Iniciación a la programación: Bucles (parte 5)

Estándar

Después de mucho tiempo sin escribir en esta serie, he decidido continuarla (algunos comentarios acerca de ello también han tenido algo que ver :p). Continuamos con una pieza imprescindible dentro de cualquier lenguaje de programación, los bucles.

Un bucle es una porción de código que se repite de manera continua hasta que una condición se cumple (o no se cumple). Son muy útiles cuando debemos repetir ciertas acciones un numero determinado de veces o mientras que una condición booleana, como las que vimos en los condicionales en el anterior post, se cumple. En un bucle la condición de salida (o permanencia) del mismo, se ejecuta una vez por cada iteración.

En Java existen varios tipos de estos bucles, que voy a explicar a continuación:

Bucle For

Quizá no debería empezar por este bucle, pero es el más usado y el más común de encontrar. Consta de cuatro partes bien diferenciadas:

for (inicialización; condición; incremento) {
	cuerpo
}
  1. Inicialización: se trata de la parte donde incializamos las variables que vamos a necesitar para el control del bucle, y aunque podemos inicializar varias, normalmente se suele dar valor a una o incluso a ninguna
  2. Condición: en esta parte debemos codificar la condición booleana que hará que nuestro bucle empiece y siga en curso, hasta que deje de cumplirse la misma. Con esto hay que tener muy en cuenta que si la condición siempre se cumple acabaremos dentro de un bucle infinito, cosa que (normalmente) no queremos
  3. Incremento: en esta parte del bucle se incrementan las variables que utilizamos en la condición del bucle. Esta parte existe porque el bucle for normalmente se utiliza para iterar un número de veces sobre un mismo código, con lo que se utiliza una variable para empezar en un número determinado e ir incrementándola hasta que llegue a otro número
  4. Cuerpo: resulta bastante obvio que esta es la parte que se va a ejecutar las veces que la condición se cumpla, y en la cual debemos de llevar cuidado de modificar lo menos posible la/s variable/s que utilicemos en la condición de salida del bucle, lo que podría conllevar a efectos laterales no deseados, e incluso a los susodichos bucles infinitos, tan conocidos por los que hemos programado

A pesar de que podemos adaptar este tipo de bucles para cualquier tipo de situación, lo más común es usarlos para recorrer estructuras de datos de tipo lineal, listas o arrays de elementos, o hacer una tarea un número de veces determinado habitualmente por una variable. Ejemplos de esto serían:

//declaramos un array
int[] myarray = [0, 1, 2, 3];

//los índices de los arrays comiezan por 0
//por lo que los recorremos de 0 a su longitud - 1
//en incrementos de 1
for (int i = 0; i < myarray.length; i++) {
	//Usamos la variable auxiliar de índice para obtener el elemento
	//que vamos a utilizar en el cuerpo
	System.out.println(myarray[i]);
}

Bucle While

Este es en realidad el rey de los bucles y a su vez el más simple. Se compone de:

while (condición) {
	cuerpo
}
  1. Condición: al igual que en el bucle for, la condición del bucle dictará si este sigue en funcionamiento otra iteración más
  2. Cuerpo: como en bucle for, el cuerpo del bucle son las instrucciones que se van a repetir mientra se cumpla la condición, pero en este caso es muy importante que en el cuerpo suceda algo que cambie en algún momento el resultado de la operación booleana de la condición del bucle, sino nos encontraremos de nuevo en un caso de bucle infinito

Como vemos, el uso del bucle while es mayor para situaciones en las que la continuación de nuestras interaciones dependa más de una condición que de una secuencia de números, como por ejemplo en el siguiente ejemplo:


int num = 3;
//Creamos una variable del tipo Random para generar números aleatorios
//(aunque todavía no haya hablado de las clases, se trata de la instanciación de la clase Random)
Random r = new java.util.Random();
int rnumber = r.nextInt();

//Continuaremos escogiendo numeros aleatorios mientras que
//el número sea distinto a nuestra variable num (o sea 3)
while (num != rnumber) {
	//Aquí es donde hacemos que la condición
	//pueda cambiar su valor en la siguiente comprobación
	//de la condición
	rnumber = r.nextInt();
}

La traza real de este código puede ser infinita ya que generamos un número aleatorio que deberá coincidir con 3, pero en algún momento deberá terminar.

Bucle Do While

Este bucle es un reorientación del bucle while. La única diferencia con este es que en el bucle do while la condición es interpretada al final de la iteración, lo que nos lleva a ejecutar siempre una primera iteración, lo cual puede no ser así en los otros tipos de bucles si no se cumpliese la condición. El esqueleto del bucle es el siguiente:

do {
	cuerpo
} while (condición);

Este tipo de bucles son muy útiles cuando la ejecución de la primera iteración es siempre obligatoria, como en nuestro ejemplo en el bucle while, en cual caso este bucle nos puede ahorrar cierto código repetido, como vemos en la reescritura del ejemplo anterio a la sintaxis del bucle do while:

int num = 3;
Random r = new java.util.Random();
int rnumber;

do {
	rnumber = r.nextInt();
} while (num != rnumber);

Me ahorro los comentarios en el código porque básicamente se trata del mismo snippet, sólo que con un bucle do while. Como véis, al realizarse la primera iteración de manera obligatoria, la inicialización de la variable rnumber no es necesaria hacerla de manera prévia. Uno de los casos dónde se suele usar este tipo de bucles es cuando se efectúan lecturas de flujos de datos (ficheros, etc) ya que siempre suelen requerir al menos una lectura.

Bucle For each

Este tipo de bucle no existe como tal en la definición de algunos lenguajes de programación, pero en Java existe desde su versión 5 y nos es muy útil a la hora de recorrer estructuras de datos. ¿Pero no dijimos que para esto normalmente se utilizan los bucles for corrientes? Si, pero si en el código del cuerpo del bucle no necesitamos el índice por el que vamos en esos momentos y sólo queremos un recorrido lineal de la estructura, es más limpio este modelo de bucle. Su estructura es la siguiente:

for (T elemento: estructura) {
	cuerpo
}

Como vemos, se elimina la necesidad de la inicialización y el incremento de una variable de índice auxiliar, ahora tenemos una variable del tipo que almacena la estructura que irá cambiando su valor a medida que avance el bucle. No cabe decir que para poder hacer un bucle for each a una estructura, esta tiene que ser iterable, ya que internamente este bucle se reescribe a un bucle for normal usando un iterador para obtener los distintos elementos de la colección, como podemos ver en el siguiente snippet:

//El bucle obtiene el iterador de la colección para usarlo de manera
//interna para recorrerla. Además prescinde del incremento
//ya que al coger el siguiente item con el método next()
//el iterador incrementa una posición automáticamente
for (Iterator it = estructura.iterator(); it.hasNext();) {
	T elemento = it.next();
	cuerpo
}

Con este tipo de bucle podemos reescribir nuestro ejemplo del bucle for para recorrer un array como vemos en el siguiente ejemplo:

int[] myarray = [0, 1, 2, 3];

for (int elem: myarray) {
	System.out.println(elem);
}

Pues esto es todo por parte de los bucles, bloques necesarios en el día a día de un programador y que poco a poco se van dominando, a pesar del primer impacto (a veces no muy sencillo). Un saludo y nos vemos en la siguiente entrada con las clases!

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s