Que son las iteraciones?

Las iteraciones, o ciclos, son estructuras que permiten ejecutar una instrucción, o todo un bloque de código, tantas veces como lo diga la condición de parada de la misma. El uso de iteraciones, simplifica a gran escala el código, y además permite crear programas más eficientes y claros.

Supongamos que queremos hacer un programa que imprima 100 veces nuestro nombre, o que  muestre las tablas de multiplicar desde el 1 hasta el 100, o que simplemente, queremos que al entrar un valor inválido por teclado, el programa vuelva a pedir el valor, hasta que este sea válido. Evidentemente, habría que utilizar muchísimo código si no usamos iteraciones.

Contadores, las iteraciones los necesitan

Las iteraciones usan variables contadoras. Las variables contadoras, generalmente son del tipo Int, y el hecho de que se llamen contadoras, no agrega absolutamente nada a su concepto. Sigue siendo una variable, pero su uso es diferente. Este contador, lo usamos para controlar la cantidad de iteraciones que realizará nuestro ciclo, por ejemplo, supongamos que nuestra variable contadora se llama “i”, y que es del tipo Int. Debemos inicializarla, después definir sobre ella la condición de parada del ciclo, y más tarde darle el valor de iteración.

Estructura Iterativa “Desde”

Esta estructura ejecuta un bloque de código tantas veces como lo indique su condición de parada y su contador. Si decimos que vamos a ejecutar un bloque de código “desde” 1 hasta 10, este bloque de código se ejecutará 10 veces. Pongamos un ejemplo de esta estructura.

Ejemplo 1

Desde (int i = 1; i<=10; i++) {
    Instrucción 1;
    Instrucción 2;
    Instrucción n… ;
}

La palabra reservada Desde,  es el nombre de esta estructura iterativa, su identificador. Seguido, vemos, que dentro de los paréntesis, están los 3 elementos que controlan la iteración.

Int i = 1;

Explicacion de estructura iterativa «Desde»

En este paso, estamos declarando e inicializando la variable “i”.Al inicializarla en el valor “1”, establecemos que “1”, será el inicio de las repeticiones que realizará esta iteración. Separada por un “;”, vemos la instrucción i <=10. Esta instrucción, define, el final de la iteración, o sea, su condición de parada. “i++” Define como se va a incrementar el contador “i”.  En este caso 1. Ahora leeremos el ejemplo 1 en lenguaje común.

Desde i, tomando el valor de 1, y mientras que i sea menor o igual que 10, incrementa i en 1, y ejecútame en cada paso  de i, las instrucciones 1,2,n.

En este tipo de ciclo, de antemano sabemos cuantas veces se repetirá el bloque de código que contiene. No es el caso de otras que estudiaremos mas adelante y no lo veras claro hasta que mires este problema de ejemplo.

Demostrando la utilidad de la estructura «Desde»

Realice un programa que imprima el texto “hola mundo” 15 veces. Primero lo haremos sin usar las iteraciones, en el primer programa, después lo haremos con iteraciones, así podrás comprobar cuan eficientes y útiles pueden llegar a ser las iteraciones.

Programa #8 (versión 1)

Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;
Imprime “Hola Mundo”;

Como puedes comprobar, nuestro programa sin iteraciones, utiliza 15 líneas de código, ahora veremos el otro ejemplo.

Programa #8 (versión 2)

Desde (int i = 1; i<=15;i++) {
Imprime “Hola Mundo”;
}

Muy sencillo. ¿Verdad?

Como funciona una iteracion dentro del compilador?

Ahora veremos al detalle, como si fuéramos un compilador, que es lo que hace esta estructura para lograr semejante resultado.

Primero se declara e inicializa la variable contador “i”,  después se le dice al compilador que mientras que “i” sea menor o igual que 15, se repitan los pasos. Si observamos esta situación, y nos preguntamos, ¿Cuándo “i” dejará de cumplir esa condición? La respuesta es que, la única forma de que “i” no sea menor o igual que 15, es que “i”  sea mayor o igual que 16.

Por tanto, en el preciso instante en que “i”  tome el valor de 16, el ciclo se romperá, y pasará el control del programa a la próxima instrucción, siendo esa esa la condición de parada. Ahora bien, en el primer paso de la iteración sucede todo esto que acabo de explicar, pero el primer paso también incluye ejecutar el bloque de código comprendido entre “{“ y “}”. 

Por lo tanto, ahora se ejecutaría la instrucción de imprimir el texto en pantalla. Ya terminado de ejecutar el bloque de código, que en este caso es una sola instrucción, la estructura iterativa, pasa a incrementar su contador automáticamente, dando así por terminado su primer paso. Como “i” tiene el valor de 1, pues fue así como lo inicializamos, ls estructura iterativa le suma 1 a ese valor, pues es lo que dicta “i++”.

Ahora “i”  tiene el valor de 2, y es cuando comienza el segundo paso de la iteración. Ya en la segunda repetición, no se inicializa el contador, simplemente se ejecuta la condición de parada, la cual se pregunta ¿i <= 15? Como”i” en este paso vale 2, o sea, tiene un dos como valor, la condición de parada i <= 15 se responde que si, porque 2 es menor que 15, y al responderse un si, continua con el proceso, y ejecuta nuevamente el bloque de código.

Ya terminado de ejecutar el bloque de código, el contador “i”  se vuelve a incrementar, y toma como valor un 3. Nuevamente la estructura repregunta ¿i <= 15?, siendo “i”  un 3, se cumple, por tanto, continua con el ciclo, y ejecuta nuevamente el bloque de código. Y así sucesivamente hasta que “i”  tome el valor de 16, cuando esto sucede, ya la condición i <=15 no se cumple pues 16 no es menor ni igual a 15, por tanto, en ese momento, el ciclo termina, y pasa el control a la próxima instrucción.

Dentro del contexto o ambito de la iteración, podemos hacer uso del valor de la variable contadora para los fines que la requieran. En cada paso, la variable contadora, puede ser usada para leer, pero no para escribir. O sea, podemos en cualquier paso, usar el valor de la variable, ya sea para mostrarlo en pantalla, para indexar algún tipo de dato, o bien para realizar cualquier operación matemática sobre otra variable que no sea el contador.

Utilizando variables dentro del ‘ambito’ de las iteraciones

El derecho de escribir en esta variable contadora, se lo reserva la estructura iterativa, solo dentro de ella se puede modificar el valor de esta variable. Por ejemplo, queremos hacer un programa que imprima los números del 1 al 5. El código sería así:

Programa #9

Desde(int i = 1;i<=5; i++) {
   Imprimir (“Numero : ” . i);
}

Numero : 1
Numero : 2
Numero : 3
Numero : 4
Numero : 5

En cada paso del ciclo, la variable contadora “i” aumenta en 1 su valor, desde 1 hasta 5, y aprovechando esto, podemos darle solución al problema, concatenando la variable con la cadena estática “Numero”;

Ciclos anidados

Que son los ciclos anidados?

Se pueden construir ciclos más complejos, si la situación lo requiere. Si quisiéramos escribir un programa que imprimiera las tablas de los productos del 1 al 10. Usando un solo ciclo no podriamos resolver este problema. Los ciclos pueden anidarse unos dentro de otros para resolver problemas de este tipo. Los ciclos anidados, son simplemente un ciclo dentro de otro, o sea, hasta ahora habíamos visto que un ciclo esta compuesto por las estructuras de control definidas sobre la variable contadora, y además un bloque de código. Lo que cambia es que en ese bloque de codigo, lo que ponemos es otro ciclo, siempre con otra variable contadora.

Como funcionan internamente los ciclos anidados?

Para construir un ciclo anidado, debemos poner, dentro de  este bloque de código, otro ciclo. Siendo así, tendríamos un ciclo exterior y un ciclo interior. Por llamarlo de esa forma, el ciclo exterior es el que comprende al interior. En cada iteración del ciclo exterior se ejecutaran todas las iteraciones del ciclo interior. Cuando el ciclo interior termina, pasa el control al ciclo exterior, este incrementa su propio contador y pasa a su segundo paso. Así tenemos un ciclo anidado. Lógicamente para controlar al mismo tiempo estos dos ciclos, necesitamos 2 variables contadoras, una para cada ciclo.

Si utilizáramos una sola variable el compilador nos lanzaria un error. Al igual que en los ciclos simples, la variables contadoras, solo se podrían leer dentro del contexto que comprende a nuestro ciclo anidado. No se podrá escribir en ellas ya que esas variables están reservadas por el ciclo para garantizar que las instrucciones que lo forman, solo se repitan las veces que definimos en su inicialización. Veamos un ejemplo de un ciclo anidado.

Demostrando la utilidad de las iteraciones anidadas

Programa #10

Desde(int i = 1;i<=10;i++) {
Desde(int j = 1;j<=10;j++) {
Imprimir (i . “*” . j . “ = ” . i*j);     
   }
}

Este ejemplo, resuelve el problema que nos planteamos con anterioridad. Pasemos a ejecutar el programa en nuestra mente, y ver los resultados que produce. El ciclo exterior se define sobre el contador “i”, se inicia en 1 y finaliza en 10. El ciclo interior, se define sobre la “j” , e igualmente se inicializa en 1 y termina en 10. Al comenzar a correr el programa, nos damos cuenta de que en el primer paso del ciclo exterior, suceden los 10 pasos del ciclo interior, y siendo así, la variable “i” tomará el valor de 1 para todas estas iteraciones. En cada paso del ciclo interior, la variable “j” incrementa su valor desde 1 hasta 10, por tanto, en el bloque de código que comprende al ciclo interior, tenemos una variable “i” con el valor de 1, y una variable “j” que va incrementando su cantidad de 1 en 1. Si imaginamos la tabla de multiplicar del 1, tendríamos esto:

1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
1 * 4 = 4
(…)
Y así sucesivamente.

Como funciona internamente las iteraciones anidadas?

Si observamos al primer múltiplo de cada  operación de multiplicación en este ejemplo, veremos que se mantiene en 1, mientras que el segundo cambia incrementándose de 1 en 1. Y precisamente es esto lo que hace el ciclo anidado. El primer producto nos lo daría la variable “i”, y el segundo múltiplo nos lo ofrece la variable “j”, para el resultado de la multiplicación, podemos dejar que el cpu de la computadora lo calcule, haciendo “i * j”, pues ya que  “i” y “j” son dos variables Int, podemos hacer esta operación sin ningún problema.

Cuando el ciclo “j” tome el valor de 10, se habrán completado los productos del 1, y vendrían los del 2. El ciclo anidado al terminar de ejecutarse el ciclo interior, pasa a ejecutar la segunda instrucción del ciclo exterior, incrementando a “i” en 1, y tomando el valor de 2. Ya con el valor de 2, el ciclo interior, esta en condiciones de imprimir los productos del 2. Y así sucesivamente hasta que el contador “i” llegue a 10. Cuando esto suceda, el ciclo exterior se “rompe”, o termina, y pasa el control al fin del programa. Como resultado tendríamos la tabla de los productos del 1 al 10.

las iteraciones en imagen

Analogia de las iteraciones anidadas

Si aun no has entendido bien de que van los ciclos anidados, te propongo la siguiente analogia. En una fiesta hay 2 hombres y 5 mujeres, el juego consiste en que cada mujer le va a dar un beso ‘en la cara’ a cada hombre. Los actores son : Pepe y Juan, y por las chicas A,B,C,D,E (esos son sus nombres). En la primera vuelta Pepe recibe besos de A,B,C,D,E, mientras que juan espera su tuno. Cuando la ultima chica, E, ha terminado de besar a Pepe, entonces le toca a Juan. Comienza nuevamente A de primera, B de segunda y asi hasta E. Cundo la chica E ha termina, finaliza el juego.