9. Bucles 3: Desde... hasta... (for... to... )
Versión en video (8:08 min):
Pascal
9. Bucles 3: Desde... hasta... (for... to... )
9.1 Avanzar de uno en uno
Los "contadores", que ya hemos introducido al hablar de la orden "while", son una estructura de programación tan frecuente que la mayoría de lenguajes incluyen alguna forma más sencilla de crearlos.
En el caso de Pascal se trata de la orden "for", que permite que una cierta variable vaya desde un cierto valor inicial a otro valor final.
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 *)
(* Curso de Pascal, por Nacho Cabanes *)
Program For1;
var
contador: integer;
begin
for contador := 1 to 5 do
writeLn( contador );
end.
(* Resultado:
1
2
3
4
5
*)
9.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, de la siguiente forma:
(* FOR2.PAS, bucles enlazados: tabla de multiplicar *)
(* Curso de Pascal, 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
*)
9.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 *)
(* Curso de Pascal, 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 ya habíamos comentado, es muy conveniente usar la escritura indentada, que en este caso ayuda a ver mejor dónde empieza y termina el bloque de órdenes que está incluido en cada bucle "for".
Esta misma estructura se puede usar para resolver muchos problemas de computación. La emplearemos dentro de poco para recorrer "matrices", y la podemos utilizar también para dibujar algunas figuras geométricas en pantalla, como por ejemplo rectángulos:
(* FOR3BRECT.PAS, bucles con sentencias compuestas *)
(* 2: Dibuja un rectangulo formado por asteriscos *)
(* Curso de Pascal, por Nacho Cabanes *)
Program For3bRect;
var
fila, columna: integer;
maxFilas, maxColumnas: integer;
begin
maxFilas := 3;
maxColumnas := 7;
for fila := 1 to maxFilas do
begin
for columna := 1 to maxColumnas do
write('*');
writeLn; (* Avance de linea *)
end;
end.
(* Resultado:
*******
*******
*******
*)
9.4. 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 *)
(* Curso de Pascal, por Nacho Cabanes *)
Program For5;
var
i: integer;
begin
for i := 5 downto 1 do
write( i );
end.
(* Resultado:
54321
*)
9.5. Contar de 2 en 2 o usando otros incrementos
Para contar de dos en dos o con cualquier otro incremento, no existe una solución inmediata. En el lenguaje BASIC, por ejemplo, existe la orden STEP, de modo que un FOR que termine con "STEP 2" incrementará la variable 2 unidades en cada pasada. Pero en Pascal no existe esa posibilidad, sino que debemos hacerlo "de forma artesanal".
Así, para avanzar de 3 en 3, tenemos alternativas sencillas como usar la variable multiplicadaa ("write(i*3)") o incrmentarla dentro del cuerpo del bucle ("i := i+3"). En este último caso, es recomendable usar una variable auxiliar y no modificar la variable que controla el bucle, porque esto puede chocar con las optimizaciones que realice algún compilador. De hecho, Free Pascal no nos permitirlá hacerlo. Vamos a verlo con un ejemplo que escriba de varias formas los números del 3 al 15, avanzando de 3 en 3:
(* FOR6.PAS, "for" y numeros no correlativos *)
(* Curso de Pascal, por Nacho Cabanes *)
program For6;
var
i: integer;
contadorAuxiliar: integer;
begin
(* Forma 1: contador multiplicado *)
for i := 1 to 5 do
writeLn( 3 * i );
(* Forma 2: segundo contador incrementado *)
contadorAuxiliar := 0;
for i := 1 to 5 do
begin
inc(contadorAuxiliar, 3);
writeLn(contadorAuxiliar);
end;
(* Forma 3: variable de control modificada, más peligroso *)
(* No permitido en Free Pascal *)
(*
for i := 1 to 5 do
begin
inc (i, 2);
writeLn(i);
end;
*)
end.
(* Resultado:
3
6
9
12
15
3
6
9
12
15
*)
Ejercicios propuestos
Ej.09.01: Crea un programa que muestre los números del 10 al 15, cada uno en una línea.
Ej.09.02: Haz un programa que escriba 10 veces "Hola" (en la misma línea).
Ej.09.03: Crea un programa que escriba "Hola" (en una línea) y luego Adios" (en otra línea). Esta estructura debe repetirse 4 veces.
Ej.09.04: Prepara un programa que escriba un cuadrado de asteriscos, con la anchura que escoja el usuario.
Ej.09.05: Crea un programa que escriba un triángulo de asteriscos, que en la primera línea tendrá la anchura que escoja el usuario (por ejemplo, 4), en la siguiente línea tendrá uno menos (3), y así sucesivamente hasta que la última línea tenga anchura 1.
Ej.09.06: Crea un programa que escriba los números del 10 al 1 (de forma descendente).
Ej.09.07: Un programa que escriba la secuencia de números 2, 4, 6, 8 ... 16.
Ej.09.08: Crea un programa que escriba un rectángulo hueco, con la anchura y altura que escoja el usuario, que tendrá asteriscos en el borde (primera y última fila, primera y última columna) y espacios en blanco en el interior.