RSS

Archivo de la etiqueta: Control del flujo

Control del Flujo: Bucles

Los bucles nos permiten alterar el flujo de ejecución de un programa ejecutando repetidamente una sentecia o grupo de sentencias.

En Java 6 tenemos tres opciones distintas a la hora de realizar iteraciones:

  • while,
  • do while,
  • for (normal y mejorado)

Vamos a ver cada una de ellas en detalle.


While

Es el bucle indicado cuando no se sabe de antemano cuántas veces se va a ejecutar el bucle. Simplemente queremos que se repitan ciertas acciones mientras la condición del bucle sea cierta.

//inicialización de variables
while (condicion){   //La condicion debe evaluarse a boolean
    //codigo         //Puede no ejecutarse ninguna vez
}

Cómo funciona:

Al entrar en el while se comprueba la condicion por primera vez.
Si resulta falsa no llega a ejecutar el código y se prosigue la ejecución fuera del bucle.
Si es cierta se ejecuta el código y se vuelve a comprobar la condición.
Así sucesivamente hasta que la condición devuelva falso y salgamos del bucle.

Como veremos la última sentencia que se ejecutará en un bucle siempre será la comprobación de la condición.

Por ejemplo:
En este código la variable i vuelve a incrementarse en la última comprobación de la condición del bucle, cuando ésta ya es falsa.

public class EjemWhile1{
    public static void main (String[] args){
        int i = -1;
        boolean encontrado = false;
        int[] medidas = {10, 30, 40, 50, 70};
        while (++i < 5 && !encontrado){
            if(medidas[i] == 40){
             encontrado = true;
            }
        }
        System.out.println(i);
    }
}

En los bucles while estar atento a:

  • Declaración de variables en la condición del while. No se puede, deben estar declaradas con anterioridad.
  • Expresiones en la condición del while que no sean boolean.
    Por ejemplo: enteros en lugar de boolean o asignaciones en lugar de comparaciones, darán error de compilación.


Do While

En estos bucles primero se ejecuta el código y luego se comprueba la condición, por lo que tenemos asegurado que el código se ejecuta al menos una vez.

do{
    elem = pila.obtener();
    System.out.println("elem: " + elem);
} while (!pila.esVacia());

Cómo funciona:
En primer lugar se ejecuta el código del bucle.
A continuación se comprueba la condición. Si esta es falsa se prosigue la ejecución fuera del bucle. Si es verdadera se ejecuta el código y se vuelve a comprobar la condición.

Estar atento a las mismas consideraciones que en el while.


For

Es el bucle que solemos utilizar cuando sabemos cuántas veces queremos ejecutar cierto código.

En su sintaxis podemos destacar tres partes importantes:
- declaración e inicialización de variables
- condición
- incremento.

Aunque ninguna de ellas son obligatorias.

Ejemplo de bucle mínimo for:

for ( ; ; ){ //sin inicializacion, condición ni incremento. Sería un bucle infinito.
    //infinito
}

Ejemplo de un bucle for que equivaldría a un while:(sin inicialización ni incremento)

int i = 0;
for ( ; i<10 ; ){
    i++;
}

Ejemplo de un bucle for típico:

for (int i=0;i<10;i++){
    //declaración e inicializacion "int i=0"
    //condicion "i<10"
    //incremento "i++"
    System.out.println("i: " + i);
}

Cómo funciona:

La inicialización de la variable se ejecuta al principio una sola vez.
A continuación se comprueba la condición y si es falsa se prosigue la ejecución fuera del bucle.
Si resulta cierta se ejecuta el código, se incrementa la variable y se vuelve a comprobar la condición.

Consideraciones del For.

Declaración e inicialización:

  • Se pueden declarar 0, 1 o más variables del mismo tipo. Si hay más de una se separan por comas.
  • Las variables declaradas en el for pierden su ámbito al salir del bucle for.
  • Esta parte sólo se ejecuta una vez, al principio de la ejecución del bucle.

Condición:

  • Sólo se puede comprobar una condición no varias.

Incremento:

  • Se ejecuta despúes de que se ejecute el código del for.


For “Mejorado”

Simplifica recorrer un array o una colección. Tiene dos partes, la declaración y el elemento a recorrer.

int[] array = {10,20,30,50};
for (int elem: array){
    System.out.println("elem: " + elem);
}

En la declaración: hay que declarar una variable compatible con el tipo de los elementos del array o de la colección.

En la expresión: será una variable array, colección o un método que las retorne.

 
Leave a comment

Publicado por en 30 noviembre, 2011 in Estudio, Tema 5

 

Etiquetas: , , , , , , , ,

Control del Flujo: If y Switch

Las sentencias condicionales permiten ejecutar código de forma selectiva.
En Java tenemos las sentencias condicionales if y switch.

Sentencia If:
La sintaxis más sencilla de una sentencia if es:

if (expresionLogica)  //Si expresionLogica se evalúa a true entonces se ejecuta codigo.
   codigo

Si se tiene una sola sentencia de código no es obligatorio encerrarla entre llaves pero siempre es recomendable por legibilidad.

Ejemplo:

if (precio < 100){
    comprar();  //Mas legible entre llaves.
}

 

Si nos encontramos un if sin llaves debemos recordar que solo aplica a la primera sentencia.

if (precio < 100)
    comprar();      //Solo esta sentencia forma parte del if.
    salirTienda();  //No forma parte del código del if. Siempre se ejecuta.
    volverACasa();  //No forma parte del código del if. Siempre se ejecuta.

La cláusula else es opcional. Se incluye cuando queremos que se ejecute código en el caso de que no se cumpla la condición en el if.

if (precio < 100){
    comprar();
}
else{
    System.out.println("Yo no soy tonto.");
}

También podemos tener una estructura if, else-if, else. Se da en los casos en los que queremos comprobar varias condiciones.

if (precio < 100){
    comprar();
}
else if (price < 2000 && tengoCredito){
    comprarConTarjeta();
}
else{
    System.out.println("Yo no soy tonto.");
}

En las sentencias If se cumplirá:

  • Habrá 0 o muchos else-if y precederán a la cláusula else.
  • Habrá 0 o 1 else e irá a continuación de todas las cláusulas else-if.
  • Cuando una condición se cumple el resto no se comprueba.
  • Si tenemos un else y no sabemos a que if corresponde será el más cercano sin else.
  • La asignación en una condición no da error si se trata de un lógico: if(indicador=true)


Switch

Con esta sentencia vamos a evaluar una expresión y dependiendo de su valor ejecutaremos un código u otro:

switch (expresion){
    case constante1: codigo1
    case constante2: codigo2
    case constante3: codigo3
    default: codigo
}

Si expresion coincide con alguna de las constantes se ejecutará el código de ese case y se seguirá ejecutando el código de los siguientes case hacia abajo hasta que se encuentre una sentencia break.

La sentencia default es opcional y se puede especificar cuando queremos que se ejecute un código para cualquier valor que sea distinto a los especificados en los case.

En los siguientes ejemplos podemos comprobar cómo afecta al resultado la existencia y posición de las sentencias breaks y default:

1. Ejemplo de un Switch Típico.
Switch con breaks en cada case y una clásula default al final.
Recorremos el array niveles. Cada valor entra en su case correspondiente y para al tener la sentencia break. Al estar la cláusula default al final no hace falta que tenga break.

public class EjemploSwitch1{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};

        System.out.println("\nEjecucion Switch Tipico (breaks y default al final): " );
    	for (int i=0; i < niveles.length; i++){  	{
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i]){
            case 1:   System.out.println("\tNivel Basico.");
                      break;

            case 2:   System.out.println("\tNivel Intermedio.");
                      break;

            case 3:   System.out.println("\tNivel Avanzado.");
                      break;

            default: System.out.println("\tNivel no informado.");
            }
    	}
    }
}

Resultado:


2. Sentencia Default No al Final.
En este caso hemos colocado la sentencia default sin break después del primer case. Todos los case tienen break. Cuando niveles[i] es igual a 0, ejecuta el código asociado a default. Al no tener break pasa al case 2, ejecuta su código y entonces sí para al tener break.

public class EjemploSwitch2{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};
	System.out.println("\nEjecucion Switch con Breaks Default enmedio sin break: " );
    	for (int i=0; i < niveles.length; i++)   	{
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i]){
            case 1:   System.out.println("\tNivel Basico.");
                      break;

            default:  System.out.println("\tNivel no informado.");

            case 2:   System.out.println("\tNivel Intermedio.");
                      break;

            case 3:   System.out.println("\tNivel Avanzado.");
                      break;

            }
    	}
    }
}

Ejecución:


3. Sentencias Case sin Break (Ejemplo en el que no tiene lógica aplicarlo).
En este Switch comprobamos qué ocurre si no colocamos ningún break. Para cada valor de niveles se ejecutan todos los case y default.

public class EjemploSwitch3{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};
        System.out.println("\nEjecucion Switch sin Breaks (entra en todos los case cada vez): ");
        for (int i=0; i < niveles.length; i++)
        {
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i])
            {
              case 1: System.out.println("\tNivel Basico.");

              case 2: System.out.println("\tNivel Intermedio.");

              case 3: System.out.println("\tNivel Avanzado.");

              default: System.out.println("\tNivel no informado.");
            }
        }
    }
}

Ejecución:


4. Sentencias Case Sin Break (Ejemplo en el que sí podría ser útil).
En este caso comprobamos cómo a veces puede tener lógica para nuestro código dejar los case sin break. Hemos cambiado el orden de las constantes en los case.

public class EjemploSwitch4{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};

	System.out.println("\nEjecucion Switch sin Breaks (con logica que podria ser correcta): ");
        for (int i=0; i < niveles.length; i++)
        {
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i])
            {
              case 3: System.out.println("\tNivel Avanzado.");

              case 2: System.out.println("\tNivel Intermedio.");

              case 1: System.out.println("\tNivel Basico.");
                      break;

              default: System.out.println("\tNivel no informado.");
            }
    	}
    }
}

Ejecución:


En el switch se debe cumplir:

  • La expresión evaluará a char, byte, short, int o enum.
  • Las constantes deben ser constantes en tiempo de compilación.
  • Hay que usar break cuando se necesite parar evitar la ejecución de los case posteriores.
  • La cláusula default no tiene por qué ser la última.
  • No puede haber dos case comprobando el mismo valor. No compilará.
  • No se pueden omitir las cláusulas case ni los ‘:’
 
Leave a comment

Publicado por en 28 noviembre, 2011 in Estudio, Tema 5

 

Etiquetas: , , , , , , ,

 
Seguir

Get every new post delivered to your Inbox.

Únete a otros 190 seguidores