Palabras clave: Estrucutura de control
, Estructuras condicionales
, Condiciones booleanas
.
1. Instrucción Iterativa
Una instrucción iterativa o repetitiva, también conocida como bucle
, tiene la misión de ejecutar las mismas instrucciones de código una y otra vez mientras que se cumpla una determinada condición.
Se llama ciclo a la secuencia de sentencias que se repiten en un bucle. |
Una instrución iterativa requiere de una serie de componentes o instrucciones para su correcto funcionamiento. Dichas componentes, expresadas en pseudocódigo, son:
1
2
3
4
5 Inicialización. (1)
MIENTRAS (expresion booleana) HACER { (2)
Cuerpo. (3)
}
Finalización. (4)
1 | La Inicialización es el conjunto de instrucciones que se ejecutan para inicializar las variables que participan de la iteración. |
2 | MIENTRAS-HACER es la instrucción iterativa. Ejecutará el cuerpo, lo contenido entre las llaves, siempre que la expresión booleana sea cierta. |
3 | El Cuerpo es el conjunto de instrucciones que se ejecutan mientras que se cumpla la expresión booleana .
Es imprescindible que en el cuerpo haya alguna instrucción que modifique para el siguiente ciclo la expresión booleana (de no modificarse nunca, el bucle no tendría fin). |
4 | La finalización es el conjunto de instrucciones que se ejecutarán cuando la iteración
termina. |
2. Instrucción while
Los lenguajes de programación suele traducir los bucles MIENTRAS-HACER
por la instrucción while
.
En Processing la instrucción iterativa Inicialización. while (expresion booleana) { Cuerpo. } Finalización. |
3. Bucle controlado por variable centinela
Se denomina variable centinela a aquella variable tal que si tomara un cierto valor el bucle debe parar.
Cuando se utiliza una variable centinela, el esquema general presenta esa forma:
1
2
3
4
5 Inicialización - incluye inicialización de la variable centinela C -
MIENTRAS (expresion booleana dependiente de C) HACER {
Cuerpo - incluye modificar el valor de C -
}
Finalización.
Es necesario en la inicialización que la variable centinela tome un valor que permita la ejecución del ciclo;
pero una vez inicializado el bucle en algún momento debe cambiar su valor para que la expresión booleana sea falsa y pueda continuar por la componente de Finalización
.
|
El siguiente código permite dibujar círculos concéntricos centrados en la pantalla gráfica.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 /* Introducción al Sw Científico y a la Programación
Dibujando círculos concéntricos.
*/
// Tamaño de la ventana gráfica: 500px de lado.
size(500,500);
/* Inicialización */
// Radio del círculo. Será la variable centinela del bucle.
int n = width;
// El bucle se realizará mientra que el valor
// de la variable centinela sea mayor a 10.
while (n > 10) { // Instrucción iterativa de Processing: while(expresion)
/* Cuerpo */
// Se establece un relleno de color aleatorio
fill(random(255), random(255), random(255));
// Dibujar un círculo centrado en la pantalla y
// con un radio
ellipse(width/2,height/2,2*n,2*n);
// IMPRECINDIBLE. Actualización de la variable centinela.
n = n/2;
}
/* Finalización */
println("Todo OK");
Puedes verlo en acción:
Entre las variables centinelas destacan los contadores y los acumuladores.
|
4. Estructuras iterativas pre y post condicionales: instrucción do
.
La instrucción iterativa que acabamos de estudiar es una estructura iterativa pre-condicional. Se llama así a aquellas estructuras cuya componentes son tales que la expresión booleana se comprueba antes de ejecutar el cuerpo (o ciclo) del bucle: primero se evalúa la condición y si es verdadera se ejecuta el bloque de acciones.
Por contra están los bucles post-condicionales. Son aquellos en los que primero se ejecuta el bloque de acciones y luego se evalúa la condición. Existen dos tipos de bucles pot-condicionales.
-
Aquellos donde si es falsa la condición se ejecuta nuevamente el bloque de acciones. El ciclo finaliza cuando la condición toma el valor de verdadero. Esta instrucción suele conocerse como
do-until
. -
Aquellos otros donde el ciclo se ejecutará mientras el valor de la condición sea verdadero. Esta instrucción suele conocerse como
do-while
.
Notar que a diferencia de la pre-condicional, en las post-condicionales el ciclo se ejecuta al menos una vez.
Processing solo tiene una instrucción iterativa post-condicional y se escribe de esta forma: Inicialización. do { Cuerpo. while (expresion booleana); // Observa el punto y coma. Finalización. |
5. Estructuras iterativas exactas: instrucción for
.
Como hemos visto, puede ocurrir que un bloque de instrucciones se tenga que ejecutar desconociendo el numero exacto de veces que lo hará. En estos casos los lenguajes ofrecen estructuras de control iterativas que están condicionadas a la evaluación de una condición booleana (que depende de cierta variable centinela).
Podemos usar una variable centinela y una condición de evaluación para que la estructura repita el cuerpo de acciones una cantidad fija de veces. Para ello basta usar un contador, para contar el número de veces que se ha realizado el cuerpo, y establecer la condición de ejecutar el cuerpo mientra que el contador no alcance el número de veces deseado. Un esquema general sería:
1
2
3
4
5
6
7
8 Inicialización - incluye la inicialización
tanto de la variable contador c=0 (puede ser otro valor)
como de la variabe numVeces, que indica cuántas veces realizar el cuerpo
MIENTRAS (c != numVeces) HACER {
Cuerpo - incluye modificar el valor de c según c=c+1; -
}
Finalización.
Una estructura iterativa que presente este esquema es una estructura iterativa exacta.
Para este tipo de estructuras, los lenguajes de programación incluyen la instrucción for
.
En Processing la instrucción iterativa exacta Inicialización. for (int c=0; c<numVeces; c=c+1) { Cuerpo. } Finalización. |
Observa que una estructura iterativa exacta se puede realizar tanto con un while como con un for . Las dos requiere de un contador.
|
El siguiente código permite dibujar exáctamente n-cuadrados cuya esquina superior izquierda se situa en el origen de coordenadas y con una rotación de \(\frac{2\times \pi}{n}\) radianes con respecto al lado superior del cuadrado anterior.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 /* Introducción al Sw Científico y a la Programación
Rotación de cuadrados
*/
size(300,300); // Tamaño de la ventana gráfica: 300px de lado.
background(255); // Fondo de color blanco.
translate(width/2, height/2); // Se desplaza el origen de coordenadas.
/* Inicialización */
// Número de cuadrados que queremos dibujar
int n = 5;
// Bucle donde ejecutaremos exáctamente n-veces el cuerpo
for (int i=0; i<n; i++) { // Instrucción for de Processing
/* Cuerpo */
// Se establece un relleno de color aleatorio
fill(random(255), random(255), random(255));
rotate(PI*2/n); // Rotamos el plano
rect(0,0,width/3, width/3); // Se dibuja un cuadrado
}
/* Finalización */
println("Todo OK"); // Mensaje de finalización
Puedes verlo en acción:
6. Anidamiento
En el cuerpo de un instrucción iterativa se puede incluir cuantas estructuras iterativas consideres. Estas a su vez puede contener a otras y así sucesivamente.
Cuando una estructura iterativa está en el cuerpo de otra se habla de bucles anidados.
El siguiente programa dibuja una ventana gráfica con una malla de \(10\times 10\) celdillas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 /* Introducción al Sw Científico y a la Programación
Dibuja una malla de 10x10 celdillas, usando una secuencia de while.
*/
int numCeldillas = 10; // Número de celdillas, por lado, que queremos dibujar
int ancho = 30; // Ancho de la celdilla
// Ajustamos el tamaño de la ventana gráfica para un tablero "perfecto"
size(numCeldillas*ancho, numCeldillas*ancho);
int fila=0; // Inicialización del contador del primer bucle
while (fila<numCeldillas) { // Primer bucle <<<<
int columna = 0; // Inicialización del contador del segundo bucle
while (columna<numCeldillas) { // Segundo bucle (anidado) <<<<
fill(random(255)); // Relleno con un gris aleatorio
rect(columna*ancho, fila*ancho, ancho, ancho); // Dibujar un rectángulo
columna = columna + 1; // Actualización del contador del segundo bucle
}
fila = fila + 1; // Actualización del contador del primer bucle
}