Instrucciones Repetitivas

Por
Las instrucciones repetitivas en lenguaje Pascal

En algunas situaciones, de la vida cotidiana, podemos ver como varias acciones se deben realizar repetidas veces para llevar a cabo un determinado proceso. Tomemos como ejemplo, a un operario de una fábrica de piezas mecánicas, el cual repite varias veces el corte y mecanizado de cada pieza que elabora, hasta que se complete todo el proceso de fabricación. Así mismo, ocurre con algunos programas; los cuales requieren que una o más instrucciones se repitan, un número determinado de veces, hasta completar una tarea específica.

Las instrucciones repetitivas nos permiten especificar aquellas instrucciones que requieren ser ejecutadas repetidas veces. Las instrucciones repetitivas constituyen estructuras que pueden contener una o más instrucciones. En el lenguaje Pascal disponemos de estructuras repetitivas, tales como las instrucciones repeat, while, y for; las cuales estudiaremos a continuación.

La instrucción repeat

La instrucción repeat (que en español traduce “repetir”) ejecuta una secuencia repetitiva de instrucciones hasta que una expresión se torne verdadera (true). La sintaxis de esta instrucción es como sigue:

Repeat

   Instrucciones;

Until {expresión};

La expresión debe devolver, como resultado, un valor de tipo boolean. La ejecución repetitiva de instrucciones dentro de la estructura repeat… until será finalizada hasta que {expresión} retorne el valor verdadero (true). La secuencia de instrucciones siempre se ejecutará por lo menos una vez; ya que en cada iteración, repeat primero ejecuta las instrucciones y después evalúa la expresión de control.

A continuación, se muestra un ejemplo práctico de la instrucción repeat:

Repeat
  
  Num := Num + 5;
  Writeln (Num);

Until Num >= 200;

La instrucción repeat no requiere de las palabras begin y end para ejecutar una composición de varias instrucciones, aunque no genera ningún error si estas se colocan.

La instrucción while

La instrucción while (que en español traduce “mientras que”) ejecuta repetitivamente una instrucción siempre y cuando una expresión sea verdadera (true). La instrucción contenida dentro de su estructura puede ser una instrucción simple, o una instrucción compuesta. La sintaxis para esta instrucción es la siguiente:

While {expresión} do instrucción;

La expresión que controla las repeticiones debe ser de tipo boolean. A diferencia de repeat, en la estructura while… do, primero se evalúa {expresión} antes que su instrucción contenida sea ejecutada. Por lo tanto, si la expresión de control es al principio falsa (true), su instrucción nunca será ejecutada.

Observe los ejemplos siguientes:

{Con una instrucción simple:}

While x <> y do x := x + 1;

{Con una instrucción compuesta:}

While I > 0 do
   Begin
      Z := Z * X;
      X := Sqr(X);
      I := I - 1;
   End;

Las variables utilizadas en la expresión de una instrucción while deben ser inicializadas antes de empezar su ejecución; ya que de acuerdo sus valores iniciales, se determina si la instrucción se ejecuta o no por primera vez. Luego, estas variables deben modificarse, dentro de la misma instrucción, para que en algún momento se detenga su ejecución.

La instrucción for

La instrucción for permite ejecutar una instrucción repetidas veces, a medida que va asignando una progresión de valores a una variable de control. La instrucción contenida en su estructura puede ser simple o compuesta. La sintaxis para la instrucción for es la siguiente:

For {Variable de control} := {Valor inicial} to/downto {Valor final}
     Do instrucción;

La variable de control debe ser un identificador de variable (sin ningún calificador), el cual debe estar al alcance local del contenido de la instrucción for; y que además, debe ser de tipo ordinal. Dentro de esta estructura, {Valor inicial} y {Valor final} representan los valores inicial y final del rango de valores que tomará la variable de control, a medida que avanza el ciclo repetitivo. Estos dos valores pueden ser determinados por valores literales, o por expresiones compatibles con el tipo ordinal.

Al entrar a una instrucción for, la instrucción contenida en su estructura se ejecuta una vez por cada valor que tome la variable de control, desde valor inicial hasta el valor final. El ciclo de repeticiones se detiene cuando dicha variable llegue a tomar el valor final.

La estructura de la instrucción for presenta dos variantes: una es el modo ascendente, mediante el formato for… to; y la otra es el modo descendente, mediante el formato for… downto.

En el modo ascendente, el valor de la variable de control se incrementa en 1 por cada iteración. En este caso, el valor inicial debe ser mayor que el valor final, de lo contrario su instrucción contenida no será ejecutada. Veamos algunos ejemplos:

{Con instrucciones simples:}

  For I := 1 to 10 do 
     Rx := Rx * r;

  For C := 'a' to 'z' do
     Writeln (C);

{Con una instrucción compuesta:}

  For I := 10 to 20 do
     Begin
       Nom := Registro (I);
       Writeln (Nom);
     End;

En el modo descendente, el valor de la variable del control es disminuido en 1 por cada iteración. En este caso, el valor inicial debe ser menor que valor final, o de lo contrario la instrucción nunca será ejecutada. Observe con atención los siguientes ejemplos:

{Con una instrucción simple:}

For J := 150 downto 50 do
   Writeln (J):

{Con una instrucción compuesta:}

For J := 200 downto 100 do
   Begin
     Write (J);
     If J > 100 then write (', ')
   End;

Es importante tener en cuenta que, si la instrucción contenida altera el valor de la variable de control, probablemente sus resultados no sean lo que esperaba. Después que una instrucción for sea ejecutada, el valor de la variable de control puede estar indefinido, a menos que su ciclo sea interrumpido por un salto interno (goto).

Los procedimientos break y continue

Los procedimientos estándar break y continue pueden ser utilizados para controlar el flujo interno de la instrucciones repetitivas.

El procedimiento break finaliza la ejecución de una instrucción repetitiva. Por ejemplo:

Var S: string;

Begin
  While true do
     Begin
        Readln(S);
        If S = 'x' then break;
        Writeln(S)
     End;
End.

Mientras que, el procedimiento continue salta a la siguiente iteración de una instrucción repetitiva. Esto significa que, dentro la composición de una instrucción repetitiva, no serán ejecutadas las instrucciones subsiguientes a dicho procedimiento. Observe el siguiente ejemplo:

Var
   s, i: integer;

Begin
   
   Writeln ('SUMATORIA DE NÚMEROS PARES');
   
   For i := 1 to 20 do
      Begin
         If i mod 2 <> 0 then begin
            Writeln ('...')
            Continue
         End;
         s := s + i;
         Writeln ('Sumatoria [i', i:2, '] = ', s);
      End;

End.

Normalmente, los procedimientos break y continue solamente pueden utilizarse dentro de la estructura de las instrucciones repetitivas (repeat, while y for); si se utilizan fuera de ellas, el compilador notificará un error.

Aplicaciones de las instrucciones repetitivas

Generalmente, son muchas las aplicaciones que podemos dar a las instrucciones repetitivas; sin embargo, cada una de éstas tiene un uso muy particular.

Filtrado de datos de entrada

Empezando por la instrucción repeat, vemos que resulta muy útil cuando se requiere que una secuencia de instrucciones se ejecute por lo menos una vez, y luego se dé la posibilidad de repetir otra vez su ejecución, según una condición dada. Una aplicación muy típica para esta instrucción suele ser el filtrado de datos de entrada, donde se comprueba si el valor ingresado por un usuario está dentro de un rango válido. Por ejemplo:

Repeat

  Write ('Ingrese un número [0..9]: ');
  Readln (I);

Until (I >= 0) and (I <= 9);

La instrucción anterior solo admite que se ingrese un número comprendido del 0 al 9; si el número ingresado está fuera de rango, se solicitará el valor nuevamente al usuario.

Cálculos sucesivos

La particularidad que tiene la instrucción while de ejecutarse indefinidamente, mientras se cumpla una condición determinada, puede ser de gran utilidad al momento de realizar cálculos de forma sucesiva; siendo posible realizar diferentes operaciones con varios datos, en forma repetitiva, hasta obtener el resultado deseado. Por ejemplo

Dividendo := 50;
divisor := 12;
Cociente := 0;
r := Dividendo;

While r >= divisor do begin
   r := r – divisor;   
   Cociente := Cociente + 1;
End;

La instrucción del ejemplo anterior realizara sucesivamente los cálculos indicados en su secuencia de instrucciones, hasta obtener como resultado los valores que provoquen que r >= divisor = False.

A continuación, veamos un pequeño programa que realiza operaciones de división entera. En dicho programa se hace uso de la instrucción repeat para hacer el filtrado de los datos de entrada. La operación de división se efectúa (sin hacer uso del operador div) mediante el cálculo de restas sucesivas, utilizando una instrucción while:

Program Division_Entera;

 { Programa para efectuar la división entera o
   Inexacta }

Uses
   Crt;

Var
   Dx, d, q, r: integer;

 { Dx: dividendo
   d:  divisor
   q:  cociente
   r:  residuo }

Begin

   Clrscr;
   Writeln ('******* DIVISIÓN ENTERA O INEXACTA *******', #10#13);

 { Entrada y filtrado de datos: }

   Repeat
      Write ('Ingrese el dividendo (Dx >= 0): ');
      Readln (Dx);
   Until Dx > 0;

   Repeat
      Write ('Ingrese el divisor (d > 0)    : ');
      Readln (d)
   Until d > 0;

 { Procesos:

      Basándonos de que en la división siempre se
      cumple que: Dx = d * q + r; se procede a la
      resta sucesiva hasta que 0 <= r < d; teniendo
      en cuenta que r = Dx al inicio. }

   r := Dx;
   q := 0;

   While r >= d do begin
      r := r - d;
      q := q + 1  {Conteo de restas efectuadas}
   End;

 { Salida de datos: }

   Writeln (#10#13, 'Resultados:');
   Writeln ('Operación (Dx/d) : ', Dx, ' / ', d);
   Writeln ('Cociente (q)     : ', q:10);
   Writeln ('Residuo (r)      : ', r:10);
   Readkey

End.

Manejo de matrices de datos

Finalizando con la instrucción for, decimos que ésta suele utilizarse cuando el número de repeticiones es conocido de antemano. Su aplicación principal se orienta al manejo de matrices; permitiendo modificar, agregar, eliminar o consultar datos que se identifiquen mediante un índice ordenado. Observe el programa a continuación:

Program Llenado_de_Matrices;

Uses
   Crt;
Var
   Data: Array [0..2, 0..3] of real;
   I, J, N, M: Integer;

Begin

   Clrscr;
   Writeln ('Ingrese los datos para la matriz Data:');
 
 { Entrada de datos de la matriz: }

   N := 2; M := 3;
   For I := 0 to N do begin
     For J := 0 to M do begin
        Write ('Data[', I, ',', J, ']: ');
        Readln (Data[I, J])
     End
   End;
  
 { Ordenamiento de la matriz: }

   Writeln (#10#13, 'Matriz Data:');
   For I := 0 to N do begin
     For J := 0 to M do begin
        Write (Data[I, J]:10:2, '  ')
     End;
     Writeln
   End;
   
   Write ('Pulse una tecla para salir’);
   Readkey

End.

El programa anterior utiliza dos pares de instrucciones for anidadas para manejar los datos de una matriz 4 x 4; el primer par solicita los datos de la matriz al usuario, y el segundo los visualiza ordenadamente, formando filas y columnas de datos.

Importante: el código de instrucciones de los programas de ejemplo, en este artículo, se ha dado a modo didáctico; si necesita utilizar el código en aplicaciones de uso práctico, deberá mejorarlo para que sus aplicaciones sean más vistosas y funcionales.