AnteriorPosterior

6. Bucles: partes del programa que se repiten

Por: Nacho Cabanes
Actualizado: 26-04-2019 13:52
Tiempo de lectura estimado: 18 min.

 

Java

6. Bucles: partes del programa que se repiten

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

6.1. while

La orden "while" 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:

// While1.java
// Comprobación repetitiva de condiciones con "while"
// Introducción a Java, Nacho Cabanes

import java.util.Scanner;

class While1 {

    public static void main( String args[] ) {

        Scanner teclado = new Scanner(System.in);
        System.out.print("Introduce un cero: ");
        int dato = teclado.nextInt();
        while (dato != 0) {
            System.out.print("No era cero. Introduce cero: ");
            dato = teclado.nextInt();
        }
        System.out.println("Terminado!");
    }
}

Estas estructuras repetitivas se pueden usar también para hacer "contadores". Por ejemplo, un programa que contase del 1 al 5 (y escribiese todos esos números) podría ser:

// Contar1a5.java
// Contar del 1 al 5 con "while"
// Introducción a Java, Nacho Cabanes

class Contar1a5 {

    public static void main( String args[] ) {

        int x = 1;

        while (x <= 5) {
            System.out.println( x );
            x++;
        }
    }
}

Ejercicio propuesto 6.1.1: Crea un programa que muestre los números del 1 al 10, usando "while"

Ejercicio propuesto 6.1.2: Crea un programa que muestre los números pares del 20 al 2, decreciendo, usando "while"

Ejercicio propuesto 6.1.3: Crea un programa que muestre la "tabla de multiplicar del 5", usando "while"

Ejercicio propuesto 6.1.4: Crea un programa que pida al usuario un número entero y muestre su cuadrado. Se repetirá mientras el usuario introduzca un número distinto de cero.

Ejercicio propuesto 6.1.5: Crea un programa que pida al usuario su contraseña (un número entero). Se repetirá mientras introduzca una contraseña distinta de "1234".

Ejercicio propuesto 6.1.6: Crea un programa que pida al usuario su login (un número entero) y su contraseña (otro número entero). Se repetirá mientras el usuario introduzca un login distinto de "1809" o una contraseña distinta de "1234".

Ejercicio propuesto 6.1.7: Crea un programa que escriba en pantalla tantos asteriscos como el usuario indique, todos ellos en la misma línea.

6.2. do-while

Existe una variante de "while", que permite comprobar la condición al final de la parte repetitiva, en vez de hacerlo antes de comenzar. Es el conjunto do..while, cuyo formato es:

do {
    sentencia;
} while (condición)

Con "while", 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; con do-while, las "sentencias" intermedias se realizarán al menos una 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:

// DoWhile1.java
// Comprobación repetitiva de condiciones con "do-while"
// Introducción a Java, Nacho Cabanes

import java.util.Scanner;

class DoWhile1 {

    public static void main( String args[] ) {

        int password;

        Scanner teclado = new Scanner(System.in);

        do {

            System.out.print( "Introduzca su password numérica: " );
            password = teclado.nextInt();

            if (password != 1234)
                System.out.println( "No es válida." );
        }
        while (password != 1234);
    }
}

Por supuesto, también podemos crear un contador usando un do..while, siempre y cuando tengamos en cuenta que la condición se comprueba al final, lo que puede hacer que la lógica sea un poco distinta en algunos casos:

// Contar1a5b.java
// Contador con "do-while"
// Introducción a Java, Nacho Cabanes

import java.util.Scanner;

class Contar1a5b {

    public static void main( String args[] ) {

        int x = 1;

        do {
            System.out.println( x );
            x++;
        }
        while (x <= 5);
    }
}

Ejercicio propuesto 6.2.1: Crea un programa que muestre los números del 1 al 10, usando "do-while"

Ejercicio propuesto 6.2.2: Crea un programa que muestre los números pares del 20 al 2, decreciendo, usando "do-while"

Ejercicio propuesto 6.2.3: Crea un programa que muestre la "tabla de multiplicar del 5", usando "do-while"

Ejercicio propuesto 6.2.4: Crea un programa que pida al usuario dos números enteros y muestre su suma. Se repetirá hasta que los dos sean 0. Emplea do-while.

Ejercicio propuesto 6.2.5: Crea un programa que pida al usuario su login (un número entero) y su contraseña (otro número entero). Se repetirá hasta que el usuario introduzca como login "1809" y como contraseña "1234". En esta ocasión, hazlo con do-while.

Ejercicio propuesto 6.2.6: Crea un programa que pida un número de tipo byte al usuario y escriba en pantalla un cuadrado formado por asteriscos, que tendrá como alto y ancho la cantidad introducida por el usuario.

6.3. for

Una tercera forma de conseguir que parte de nuestro programa se repita es mediante la orden "for". La emplearemos sobre todo para conseguir un número concreto de repeticiones. En lenguajes como BASIC su formato es muy simple: "FOR x = 1 TO 10" irá recorriendo todos los valores de x, desde uno hasta 10. En Java y otros lenguajes que derivan de C, su sintaxis es más enrevesada:

for ( valor_inicial ; condicion_continuacion ; incremento ) {
sentencias
}

Es decir, indicamos entre paréntesis, y separadas por puntos y coma, tres órdenes:

  • La primera orden dará el valor inicial a una variable que sirva de control.
  • La segunda orden será la condición que se debe cumplir mientras 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:

// For1.java
// Repetición con "for" 1: escribir 10 veces
// Introducción a Java, Nacho Cabanes

class For1 {

    public static void main( String args[] ) {

        int i;

        for ( i=1 ; i<=10 ; i++ ) {
            System.out.print( "Hola " );
        }
    }
}

(inicialmente i vale 1, hay que repetir mientras sea menor o igual que 10, y en cada paso hay que aumentar su valor una unidad),

De forma similar, podríamos hacer un contador de 1 a 5, como los que hemos creado con "while" y con "do-while":

// Contar1a5c.java
// Repetición con "for" 2: contar de 1 a 5
// Introducción a Java, Nacho Cabanes

class Contar1a5c {

    public static void main( String args[] ) {

        int x;

        for ( x=1 ; x<=5 ; x++ ) {
            System.out.println( x );
        }
    }
}

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

// Contar10a0.java
// Repetición con "for" 3: descontar de 10 a 0, de 2 en 2
// Introducción a Java, Nacho Cabanes

class Contar10a0 {

    public static void main( String args[] ) {

        int i;

        for ( i=10 ; i>=0 ; i-=2 ) {
            System.out.println( i );
        }

    }
}

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:

// Contar10a0b.java
// Repetición con "while": descontar de 10 a 0, de 2 en 2
// Programa equivalente a "For2.java"
// Introducción a Java, Nacho Cabanes

class Contar10a0b {

    public static void main( String args[] ) {

        int i;

        i=10 ;
        while ( i>=0 ) {
            System.out.println( i );
            i-=2;
        }

    }
}

No hay obligación de declarar las variables justo al principio del programa. Es frecuente hacerlo buscando legibilidad, pero también se pueden declarar en puntos posteriores del fuente. Por eso, un sitio habitual para declarar la variable que actúa de contador de un "for" es dentro del propio "for", así:

// ForVariable.java
// Variable declarada dentro de un "for"
// Introducción a Java, Nacho Cabanes

class ForVariable {

    public static void main( String args[] ) {

        for (int i=10 ; i>=0 ; i-=2 ) {
            System.out.println( i );
        }

    }
}

Esto tiene la ventaja de que no podemos reutilizar por error esa variable "i" después de salir del "for", porque "se destruye" automáticamente y obtendríamos un mensaje de error si tratamos de usarla. Así evitamos efectos indeseados de que cambios en una parte del programa afecten a otra parte del programa porque estemos reusando una variable sin darnos cuenta.

Ejercicio propuesto 6.3.1: Crea un programa que muestre los números del 1 al 15, usando "for"

Ejercicio propuesto 6.3.2: Crea un programa que muestre los números pares del 20 al 2, decreciendo, usando "for"

Ejercicio propuesto 6.3.3: Crea un programa que muestre la "tabla de multiplicar del 5", usando "for"

Ejercicio propuesto 6.3.4: Crea un programa que muestre los números enteros del 0 al 100 que son múltiplos de 6 (el resto al dividir por 6 sea 0).

Ejercicio propuesto 6.3.5: Crea un programa que muestre los números enteros entre 0 y el que introduzca el usuario que sean múltiplos de 3 (el resto al dividir por 3 es 0) y a la vez múltiplos de 7 (ídem).

Ejercicio propuesto 6.3.6: Crea un programa que pida dos números de tipo byte al usuario y escriba en pantalla un rectángulo formado por asteriscos, que tendrá como alto el primer número y como ancho el segundo número.

Ejercicio propuesto 6.3.7: Crea un programa que pida un número de tipo byte al usuario y escriba en pantalla un cuadrado hueco de ese ancho, que tendrá un borde formado por asteriscos y su interior serán espacios en blanco. Por ejemplo, para un tamaño de 4 sería:

****
*  *
*  *
****

Ejercicio propuesto 6.3.8: Crea un programa que pida al usuario un número entero largo y muestre cuáles son sus divisores (aquellos entre los que se puede dividir, obteniendo como resto 0).

Ejercicio propuesto 6.3.9: Crea un programa que pida al usuario un número entero largo y diga si es primo (si sólo es divisible entre 1 y él mismo).

Ejercicio propuesto 6.3.10: Crea un programa que pida al usuario dos números enteros largos y diga cuántos números primos hay entre ellos (ambos incluidos).

Precaución 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 (dentro de un "bucle sin fin").

6.4. break y continue

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:

// Break1.java
// Ejemplo de uso de "break"
// Introducción a Java, Nacho Cabanes

class Break1 {

    public static void main( String args[] ) {

        int i;
        System.out.println( "Empezamos..." );
        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:

// Continue1.java
// Ejemplo de uso de "continue"
// Introducción a Java, Nacho Cabanes

class Continue1 {

    public static void main( String args[] ) {

        int i;
        System.out.println( "Empezamos..." );
        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.

Ejercicio propuesto 6.4.1: Crea un programa que muestre los números del 1 al 20, excepto el 15, usando "for" y "continue"

Ejercicio propuesto 6.4.2: Crea un programa que muestre los números del 1 al 10, usando "for" que vaya del 1 al 20 y "break"

6.5. Etiquetas

También existe 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 ese caso (muy poco frecuente), deberemos crear una etiqueta justo antes de la orden que queremos que se interrumpa, y luego usar "break" seguido del nombre de esa etiqueta, así

// BreakEtiqueta.java
// Ejemplo de uso de "break" con etiqueta de salto
// Introducción a Java, Nacho Cabanes

class BreakEtiqueta {
    public static void main( String args[] ) {
        int i;
        bucleAInterrumpir:
        for ( i=1 ; i<=10 ; i++ ) {
            System.out.println( "Comenzada la vuelta" );
            System.out.println( i );
            if (i==8) break bucleAInterrumpir;
            System.out.println( "Terminada esta vuelta" );
        }
        System.out.println( "Terminado" );
    }
}

En este caso, a mitad de la pasada 8 se interrumpiría el bloque que hemos etiquetado como "bucleAInterrumpir" (una etiqueta se define como se ve en el ejemplo, con su nombre terminado con el símbolo de "dos puntos").

Ejercicio propuesto 6.5.1: Crea un programa que muestre los números del 1 al 10, usando "for" que vaya del 1 al 20 y un "break" con etiqueta.

100417 visitas desde el 26-04-2019

AnteriorPosterior