02 abril 2014

Pascal - 3a: Estructuras repetitivas, for

3 - Estructuras repetitivas

3.1. ¿Qué es un bucle?

Vamos a ver cómo podemos crear bucles o lazos, es decir, partes del programa que se repitan un cierto número de veces.
Según cómo queramos que se controle ese bucle, tenemos tres posibilidades, que vamos a comentar en primer lugar:
  • for..to: Repite una orden (o un bloque de órdenes) desde que una variable tiene un valor inicial hasta que alcanza otro valor final (un cierto NÚMERO de veces).
  • while..do: Repite una sentencia MIENTRAS se cumpla una condición.
  • repeat..until: Repite un grupo de sentencias HASTA que se dé una condición.
La diferencia entre estos dos últimos es que "while" comprueba la condición antes de repetir las demás sentencias, por lo que puede que estas sentencias ni siquiera se lleguen a ejecutar, en caso de que la condición de entrada fuera falsa. Por el contrario, en un "repeat", la condición se comprueba al final, de modo que las sentencias intermedias se ejecutarán al menos una vez.
Vamos a verlos con más detalle...

3.2. Desde... hasta... (for)

3.2.1 Avanzar de uno en uno

El formato de la orden "for" es
for variable := ValorInicial to ValorFinal do
    Sentencia;
Se podría traducir "desde que la variable valga ValorInicial hasta que valga ValorFinal" (y en cada pasada, su valor aumentará en una unidad).
Como primer ejemplo, vamos a ver un pequeño programa que escriba los números del uno al cinco:
(* FOR1.PAS, Primer ejemplo de "for": contador *)
(* Parte de CUPAS5, por Nacho Cabanes          *)
 
Program For1;
 
var
    contador: integer;
 
begin
    for contador := 1 to 5 do
        writeLn( contador );
end. 
 
(* Resultado:
1
2
3
4
5
*)
 

3.2.2. "For" encadenados

Los bucles "for" se pueden enlazar uno dentro de otro, de modo que podríamos escribir las tablas de multiplicar del 1 al 5, dando 5 pasos, cada uno de los cuales incluye otros 10, así:
(* FOR2.PAS, bucles enlazados: tabla de multiplicar *)
(* Parte de CUPAS5, por Nacho Cabanes               *)
 
Program For2;
 
var
    tabla, numero: integer;
 
begin
    for tabla := 1 to 5 do
        for numero := 1 to 10 do
            writeLn( tabla, ' por ', numero ,' es ', tabla * numero );
end. 
 
(* Resultado:
1 por 1 es 1
1 por 2 es 2
1 por 3 es 3
...
1 por 10 es 10
2 por 1 es 2
...
5 por 10 es 50
*)
 

3.2.3. "For" y sentencias compuestas

Hasta ahora hemos visto sólo casos en los que después de "for" había un única sentencia. Si queremos repetir más de una orden, basta encerrarlas entre "begin" y "end" para convertirlas en una sentencia compuesta, como hemos hecho hasta ahora.
Así, vamos a mejorar el ejemplo anterior haciendo que deje una línea en blanco entre tabla y tabla:
(* FOR3.PAS, bucles con sentencias compuestas *)
(* Parte de CUPAS5, por Nacho Cabanes         *)
 
Program For3;
 
var
    tabla, numero: integer;
 
begin
    for tabla := 1 to 5 do
    begin
        for numero := 1 to 10 do
            writeLn( tabla, ' por ', numero ,' es ', tabla * numero );
        writeLn;        (* Línea en blanco *)
    end;
end. 
 
(* Resultado:
1 por 1 es 1
1 por 2 es 2
1 por 3 es 3
...
1 por 10 es 10
 
2 por 1 es 2
...
5 por 10 es 50
*)
 
Como vimos, es muy conveniente usar la escritura indentada, que en este caso ayuda a ver mejor dónde empieza y termina lo que hace cada "for".

3.2.4. Contar con letras

Una observación: para "contar" no necesariamente hay que usar números, también podemos contar con letras:
(* FOR4.PAS, letras como índices en un bucle *)
(* Parte de CUPAS5, por Nacho Cabanes        *)
 
Program For4;
 
var
    letra: char;
 
begin
    for letra := 'a' to 'z' do
        write( letra );
 end. 
 

3.2.5. Contar de forma decreciente (downto)

Con el bucle "for", tal y como lo hemos visto, sólo se puede contar en forma creciente y de uno en uno. Para contar de forma decreciente, se usa "downto" en vez de "to".
(* FOR5.PAS, "for" que desciende      *)
(* Parte de CUPAS5, por Nacho Cabanes *)
 
Program For5;
 
var
    i: integer;
 
begin
    for i := 5 downto 1 do
        write( i );
end. 
 
(* Resultado:
54321
*)
 

3.2.6. Contar de 2 en 2 o usando otros incrementos

Para contar de dos en dos (por ejemplo), hay que buscarse la vida: multiplicar por dos o sumar uno dentro del cuerpo del bucle, etc... Eso sí,sin modificar la variable que controla el bucle (deberemos usar cosas como "write(x*2)" en vez de "x := x*2", que pueden dar problemas en algunos compiladores).
(* FOR6.PAS, "for" y nnmeros no correlativos  *)
(* Parte de CUPAS5, por Nacho Cabanes         *)
 
Program For6;
 
var
    contador: integer;
 
begin
    for contador := 1 to 5 do
        writeLn( 10 * contador );
end. 
 
(* Resultado:
10
20
30
40
50
*)
 
(Puedes ver la versión más actualizada, junto con ejercicios propuestos, en la página oficial del curso)