Instrucciones de repetición

Instrucciones de repetición.

Con frecuencia tendremos que hacer que una parte de nuestro programa se repita (algo a lo que con frecuencia llamaremos "bucle"), bien mientras se cumpla una condición o bien un cierto número prefijado de veces.

Java incorpora varias formas de conseguirlo. La primera que veremos es la orden "while", que hace que una parte del programa se repita mientras se cumpla una cierta condición. Su formato será:

    while (condición)
      sentencia

Es decir, la sintaxis es similar a la de "if", con la diferencia de que aquella orden realizaba la sentencia indicada una vez como máximo (si se cumplía la condición), pero "while" puede repetir la sentencia más de una vez (mientras la condición sea cierta). Al igual que ocurría con "if", podemos realizar varias sentencias seguidas (dar "más de un paso") si las encerramos entre llaves:

    x = 20;
    while ( x > 10) {
      System.out.println("Aun no se ha alcanzado el valor limite");
      x --;
    }


Existe una variante de este tipo de bucle. Es el conjunto do..while, cuyo formato es:

    do {
      sentencias
    } while (condicion)

En este caso, la condición se comprueba al final, lo que quiere decir que las "sentencias" intermedias se realizarán al menos una vez, cosa que no ocurría en la construcción anterior (un único "while" antes de las sentencias), porque si la condición era falsa desde un principio, los pasos que se indicaban a continuación de "while" no llegaban a darse ni una sola vez.

Un ejemplo típico de esta construcción "do..while" es cuando queremos que el usuario introduzca una contraseña que le permitirá acceder a una cierta información:

    do {
      System.out.println("Introduzca su clave de acceso");
      claveIntentada = LeerDatosUsuario;  // LeerDatosUsuario realmente no existe
    } while (claveIntentada != claveCorrecta)

En este ejemplo hemos supuesto que existe algo llamado "LeerDatosUsuario", para que resulte legible. Pero realmente la situación no es tan sencilla: no existe ese "LeerDatosUsuario", ni sabemos todavía cómo leer información del teclado cuando trabajamos en modo texto (porque supondría hablar de excepciones y de otros conceptos que todavía son demasiado avanzados para nosotros), ni sabemos crear Applets en los que podamos utilizar una casilla de introducción de textos. Así que de momento nos creeremos que algo parecido a lo que hemos escrito podrá llegar a funcionar... pero todavía no lo hace.


Una tercera forma de conseguir que parte de nuestro programa se repita es la orden "for". La emplearemos sobre todo para conseguir un número concreto de repeticiones.  Su formato es

    for ( valor_inicial ; condicion_continuacion ; incremento ) {
      sentencias
    }

(es decir, indicamos entre paréntesis, y separadas por puntos y coma, tres órdenes: la primera dará el valor inicial a una variable que sirva de control; la segunda orden será la condición que se debe cumplir para que se repitan las sentencias; la tercera orden será la que se encargue de aumentar -o disminuir- el valor de la variable, para que cada vez quede un paso menos por dar).

Esto se verá mejor con un ejemplo. Podríamos repetir 10 veces un bloque de órdenes haciendo:

    for ( i=1 ; i<=10 ; i++ ) {
      ...
    }

O bien podríamos contar descendiendo desde el 20 hasta el 2, con saltos de 2 unidades en 2 unidades, así:

    for ( j = 20 ; j > 0 ; j -= 2 )
      System.out.println( j );
 

Nota: se puede observar una equivalencia casi inmediata entre la orden "for" y la orden "while". Así, el ejemplo anterior se podría reescribir empleando "while", de esta manera:

    j = 20;
    while ( j > 0 )
      System.out.println( j );
      j -= 2;
    }


Precauciones con los bucles: Casi siempre, nos interesará que una parte de nuestro programa se repita varias veces (o muchas veces), pero no indefinidamente. Si planteamos mal la condición de salida, nuestro programa se puede quedar "colgado", repitiendo sin fin los mismos pasos.


Se puede modificar un poco el comportamiento de estos bucles con las órdenes "break" y "continue".

La sentencia "break" hace que se salten las instrucciones del bucle que quedan por realizar, y se salga del bucle inmediatamente. Como ejemplo:

    for ( i=1 ; i<=10 ; i++ ) {
      System.out.println( "Comenzada la vuelta" );
      System.out.println( i );
      if (i==8)  break;
      System.out.println( "Terminada esta vuelta );
    }
    System.out.println( "Terminado"  );

En este caso, no se mostraría el texto "Terminada esta vuelta" para la pasada con i=8, ni se darían las pasadas de i=9 e i=10, porque ya se ha abandonado el bucle.

La sentencia "continue" hace que se salten las instrucciones del bucle que quedan por realizar, pero no se sale del bucle sino que se pasa a la siguiente iteración (la siguiente "vuelta" o "pasada"). Como ejemplo:

    for ( i=1 ; i<=10 ; i++ ) {
      System.out.println( "Comenzada la vuelta" );
      System.out.println( i );
      if (i==8)  continue;
      System.out.println( "Terminada esta vuelta );
    }
    System.out.println( "Terminado"  );

En este caso, no se mostraría el texto "Terminada esta vuelta" para la pasada con i=8, pero sí se darían la pasada de i=9 y la de i=10.


También esta la posibilidad de usar una "etiqueta" para indicar dónde se quiere saltar con break o continue. Sólo se debería utilizar cuando tengamos un bucle que a su vez está dentro de otro bucle, y queramos salir de golpe de ambos. Es un caso poco frecuente, así que no profundizaremos más, pero sí veremos un ejemplo:

    for ( i=1 ; i<=10 ; i++ ) {
      System.out.println( "Comenzada la vuelta" );
      System.out.println( i );
      if (i==8)  break salida;
      System.out.println( "Terminada esta vuelta );
    }
    System.out.println( "Terminado"  );
    salida:
    ...
 

En este caso, a mitad de la pasada 8 se saltaría hasta la posición que hemos etiquetado como "salida" (se define como se ve en el ejemplo, terminada con el símbolo de "dos puntos"), de modo que no se escribiría en pantalla el texto "Terminado" (lo hemos "saltado").

Ejemplo.

 

Hacer un programa que permita calcular la siguiente sumatoria

 

 

 

/**

 * Title: Sumatoria

 * Description: Este programa calcula la suma de 1 + 2 + 4 + 8+ 16 + ...2n

 * Copyright: Copyright (c) 2003

 * Company: UMSNH

 * author Dr. Felix Calderon Solorio

 * version 1.0

 */

 

 

class ej005

{

  public static void main (String args[])

  {

    float i=1;

    float s=0;

    do

    {

      s=((2*s) +1);

      System.out.println("s="+s);

      i++;

    }

    while (i<=64);

  }

}

 

Ejemplo.

 

Que realiza el siguiente programa

 

package ejemplos;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author not attributable

 * @version 1.0

 */

 

public class ej070 {

  public static void main(String[] args) {

 

   int i, j, k;

   double x, y, z;

 

   for(i=1, x = 100; i<=10; i++, x/=2);

   System.out.println(x);

 

   x = 100;

   y = 110;

   while(y-x > 1)

   {

     y -= 0.1;

     x *= 1.1;

     System.out.println(y + " " +x);

   }

 

   x = 1.1;

   y = 2;

 

   do

   {

     x *= x;

     z = y * 2;

     System.out.println(x + " " + z);

 

   }while (z > 2  && x <3);

 

   for(i = 0; i<2; i++)

     for(j=0; j<2; j++)

       for(k= 0; k<2; k++)

         System.out.println("" + i + j + k);

  }

}

 

Regresar.