En la anterior entrega vimos como convertir una variable de un tipo a otro, que eran las enumeraciones y como podíamos pedir datos a los usuarios que utilizan un programa para poder usarlos más tarde mediante Scanner.
Ahora nos toca centraremos es las estructuras de control de flujo (condicionales, selecciones y bucles).
Introducción
En este curso la metodología de programación que estamos utilizando y aprendiendo con Java es la llamada programación estructurada y es un paradigma de programación orientado a mejorar la claridad, calidad y tiempo de desarrollo de un programa recurriendo únicamente a las subrutinas y tres estructuras básicas: secuencia, selección e iteración; Básicamente consiste en que cada línea de código (instrucción) se ejecuta de forma secuencial una detrás de otra (secuencia) pero existe unas estructuras (selección e iteración) que pueden hacer cambiar el sentido de la ejecución del código.
Las estructuras de control de flujo permiten modificar el flujo de ejecución (secuencia) de las instrucciones de un programa. Hay dos tipos de estructuras de control:
- Estructuras de selección: a partir de una condición (si se cumple o no) se selecciona una parte específica de nuestro código.
- Estructuras de iteración: nos permite ejecutar una parte específica de nuestro código un numero determinado de veces.
Por lo tanto, con las estructuras de control podemos:
- De acuerdo con una condición, ejecutar un grupo u otro de instrucciones (Operador Condicional, If, If-Else, If-Else if-Else).
- De acuerdo con el valor de una variable, ejecutar un grupo u otro de instrucciones (Switch).
- Ejecutar un grupo de instrucciones un número determinado de veces (While, Do-While, For).
Estructuras de selección
Operador condicional
Esta estructura es la más simple a utilizar en Java y su pseudocódigo (código diseñado para la lectura humana) es:
1 |
(condición ? verdad : falso) |
«Si se cumple la condición, se ejecutará verdad, sino se ejecutará falso«.
La estructura formal es:
1 |
(condicion ? true : false); |
Por lo tanto podemos ver que si la condición (por ejemplo, a>b) es verdad, se ejecutará la parte del true, si no es verdad se ejecutará la parte del false.
Veamos un ejemplo:
1 2 3 4 5 |
int a = 3; int b = 2; System.out.print(“El número mayor es: ”); System.out.println(a>b ? a : b); |
El resultado por pantalla será:
El número mayor es: 3
Fijáos que ahora hemos utilizado un método diferente, System.out.print(). Que diferencia hay entre print() y println()?
- print(): escribe por pantalla y no hace un «intro». Si volvemos a hacer otro print() seguirá escribiendo en la misma linea.
- println(): escribe por pantalla y realiza un «intro». Si volvemos a hacer otro println() escribirá en la linea siguiente.
Por ejemplo, si usamos print():
1 2 3 |
System.out.print(“a”); System.out.print(“b”); System.out.print(“c”); |
Mostraría por pantalla:
abc
Pero si usamos println():
1 2 3 |
System.out.println(“a”); System.out.println(“b”); System.out.println(“c”); |
Mostrará por pantalla:
a
b
c
If
Esta estructura nos permite comprobar mediante una condición que un valor es el que esperamos y así ejecutar una porción de código determinada. Por ejemplo, si tenemos una clase Operaciones, donde tenemos un atributo de tipo String llamado «operacion» que su valor nos indica la operación que queremos realizar, debemos especificar que si la operación es una suma «+» se deberá hacer la operación de suma de dos valores y no otra cosa diferente.
El pseudocódigo es:
1 2 3 |
Si (condición) Entonces Se ejecuta este código si condición es verdad Fin Si |
La estructura formal es:
1 2 3 4 |
if(condicion) { //Instrucciones a ejecutar si condicion == true } |
Ahora pasamos a ver el ejemplo de la clase «Operaciones» (si existen partes del código que no entendéis, tranquilos poco a poco se irán explicando):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class Operaciones{ public static void main(String[] args){ String operacion; int valor1; int valor2; int resultado; // Ejemplo operacion = "+"; //Suma valor1 = 2; valor2 = 3; resultado = 0; if(operacion == "+"){ resultado = valor1 + valor2; } //Transformamos int a String String r = Integer.toString(resultado); System.out.println(r); } } |
Podemos observar que la operación es una suma («+») y por lo tanto cuando realice la comprobación de la condición de la estructura If el resultado será true («+» == «+») y se ejecutará el código de su interior, que es la operación valor1 + valor2.
Podemos ver que al final, para mostrar un tipo entero (int) por pantalla, hemos de pasar la variable «resultado» de tipo entero (int) a String, y para eso utilizamos:
22 |
String r = Integer.toString(resultado); |
Esto debemos hacerlo así debido a la utilización de System.out.println(«») para mostrar el resultado por pantalla. Este método println() espera un argumento de tipo String dentro de su paréntesis, y no le podemos asignar un int ya que daría error.
El resultado por pantalla de la ejecución de nuestro programa es: 5 (2 + 3 = 5)
If-Else
Si en el ejemplo anterior, tuviésemos otro tipo de operación, por ejemplo una resta («-«), podríamos utilizar la estructura If-Else. Esta estructura ejecutará el código de la parte If si la operación es una suma (por ejemplo…) y sino ejecutará la parte Else por que si hay dos operaciones y no es una suma, será forzosamente una resta.
El pseudocódigo es:
1 2 3 4 5 |
Si (condición) Entonces Se ejecuta este código si condición es verdad SiNo Se ejecuta este otro código si condición es falso Fin Si |
La estructura formal es:
1 2 3 4 5 6 |
if(condicion) { //Instrucciones a ejecutar si condicion == true }else{ //Instrucciones a ejecutar si condicion == false } |
Siguiendo con nuestro ejemplo anterior, veamos como realizar la nueva estructura:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Operaciones{ public static void main(String[] args){ String operacion; int valor1; int valor2; int resultado; // Ejemplo operacion = "-"; //Ahora tenemos 2 operaciones "+" y "-" valor1 = 2; valor2 = 3; resultado = 0; if(operacion == "+"){ resultado = valor1 + valor2; }else{ resultado = valor1 - valor2; } //Transformamos int a String String r = Integer.toString(resultado); System.out.println(r); } } |
Ahora podemos ver que el atributo operacion es «–» y por tanto se ejecutará el código de la parte else de la estructura if-else.
Ahora el resultado por pantalla será: -1 (2 – 3 = -1)
If-Else if-Else
Si ahora, a parte de tener dos operaciones, queremos tener una tercera operación, por ejemplo multiplicar («*«), podemos enlazar o concatenar los else con la estructura If-Else If-Else.
El pseudocódigo es:
1 2 3 4 5 6 7 |
Si (condición1) Entonces Se ejecuta este código si condición1 es verdad SiNo Si(condición2) Entonces Se ejecuta este código si condición1 es falso y condición2 es verdad SiNo Se ejecuta este código si condición1 es falso y condición2 es falso Fin Si |
La estructura formal es:
1 2 3 4 5 6 7 8 9 10 11 |
if(condicion1) { //Instrucciones a ejecutar si condicion1 == true }else if(condicion2){ //Instrucciones a ejecutar si condicion1 == false && condicion2 == true }else{ //Instrucciones a ejecutar si condicion1 && condición2 == false } |
Ahora pasamos a ver el ejemplo completo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class Operaciones{ public static void main(String[] args){ String operacion; int valor1; int valor2; int resultado; // Ejemplo operacion = "*"; //Ahora tenemos 3 operaciones "+", "-" y "*" valor1 = 2; valor2 = 3; resultado = 0; if(operacion == "+"){ resultado = valor1 + valor2; }else if(operacion == "-"){ resultado = valor1 - valor2; }else{ resultado = valor1 * valor2; } //Transformamos int a String String r = Integer.toString(resultado); System.out.println(r); } } |
Ahora podemos ver que la operación es una multiplicación («*«). Por lo tanto al realizar la comprobación del condicional, la primera condición no pasa (ya que mira si es una suma), la segunda también no la pasa (mira si es una resta), por lo tanto ejecutara la parte del else que es la parte de la multiplicación.
El resultado por pantalla será: 6 (2 * 3 = 6)
Antes de seguir con nuevas estructuras, vamos a ver los errores más comunes a la hora de utilizar las estructuras que acabamos de ver (IF, IF-ELSE y IF-ELSE IF-ELSE):
- La comprobación (condición) siempre tiene que devolver un valor booleano (true o false).
No podemos poner:
1 2 3 4 5 |
int number = 9; if(number){ ... } |
- Debemos escribir else if (separado por un espacio) y no elseif (junto).
Switch
Como hemos podido ver anteriormente, las estructuras If, If-Else, If-Else if-Else son estructuras para comparar variables con pocas opciones. Por ejemplo comprobar que una variable tiene un valor concreto, saber si una variable es mayor o menor que un valor, si una variable es diferente a un valor, etc. Pero cuando tenemos que comprobar en un condicional una variable que puede tener muchas opciones y siempre debe ser una concreta (por ejemplo un menú enumerado donde podemos elegir diferentes partes del menú con 1,2,3,4,…) utilizaremos la nueva estructura Switch.
Switch nos permite mirar si se cumple la expresión, y si este valor concreto lo tenemos especificado en su interior con un caso (case) se ejecutará el bloque de código que contenga ese caso (case). Si la expresión no es igual a ningún caso (case) ejecutará el caso (case) por defecto (default) con su bloque de código por defecto (normalmente es un mensaje de error).
En la expresión podemos evaluar:
- Enteros (int)
- Carácteres (char y String)
- Enumeraciones (enum)
- Booleanos
Cada caso (case) ejecutará una porción de código concreto y después de ejecutarse, saldrá de la estructura switch utilizando un break. La sentencia Break rompe la secuencia de control de la estructura switch y de esta forma no ejecutará ningún caso más de forma secuencial saliendo así de la estructura y del programa. En java hay dos sentencias que nos permiten forzar la salida, y estas sentencias son break (para salir completamente del bucle) y continue (para salir de la iteración actual y saltar directamente a la siguiente).
El pseudocódigo es:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Segun (variable) Hacer opcion1: acciones1 (variable es igual a opcion1) Salir opcion2: acciones2 (variable es igual a opcion2) Salir ... opcionN: accionesN (variable es igual a opcionN) Salir De Otro Modo: accionDefecto (cuando el valor de variable no coincide con nada) Fin Segun |
La estructura formal es:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
switch(variable){ case valor1: accion1; break; case valor2: accion2; break; case valor3: accion3; break; ... case valorN: accionN; break; default: accionD; break; } |
Seguimos con el ejemplo anterior pero ahora tendremos las operaciones «+» (suma), «-» (resta), «*» (multiplicación), «/» (división) y «%» (resto o módulo):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
public class Operaciones { public static void main(String[] args) { String operacion; int valor1; int valor2; int resultado; // Ejemplo operacion = "+"; valor1 = 2; valor2 = 3; resultado = 0; switch (operacion) { case "+": //Suma resultado = valor1 + valor2; break; case "-": //Resta resultado = valor1 - valor2; break; case "*": //Produto resultado = valor1 * valor2; break; case "/": //División resultado = valor1 / valor2; break; case "%": //Módulo resultado = valor1 % valor2; break; default: resultado = 0; System.out.println("¡El resultado es "+resultado+" porque no se reconoce la operación!"); break; } //Transformamos int a String String r = Integer.toString(resultado); System.out.println(r); } } |
El resultado por pantalla sería: 5.
Esto se debe que como la operación era una suma («+»), el switch a evaluado su expresión y ha visto que el valor de la variable operación era igual que el case «+» y por lo tanto ha ejecutado ese caso.
Ahora podemos ver que solamente cambiando el valor del atributo operacion = («+», «-«, «*», «/» o «%») realizará la operación deseada. Si por ejemplo asignamos operacion = «a»; ahora el programa desconoce la operación a realizar y ejecutaría el case «default«.
Estructuras de iteración
Las estructuras de iteración o bucles son ciclos repetitivos basados en los resultados de una expresión lógica. La diferencia entre las estructuras siguientes y las vistas anteriormente es que ahora sabemos dónde evaluamos las condiciones (al principio o al final del bucle) o que condición ha de cumplirse para finalizar la iteración. Estos aspectos son muy importantes a la hora de escribir bucles correctamente ya que muy fácilmente podemos crear bucles «infinitos» que no pararán de realizar iteraciones debido a que no se especifican correctamente las condiciones de parada.
While
El bucle while tiene el propósito de repetir un bloque de código mientras una condición se mantenga verdadera. Primero evalúa la condición y si es verdadera, ejecutará el código.
El pseudocódigo es:
1 2 3 |
Mientras (condición) Hacer instrucciones cuando condición es verdad fin mientras |
La estructura formal es:
1 2 3 |
while(condición){ //Instrucciones cuando condición == true } |
Por ese motivo, seleccionaremos esta estructura cuando tengamos que hacer un bucle que en la primera iteración ya compruebe la condición. Miremos el siguiente ejemplo:
1 2 3 4 5 6 |
int a = 0; while(a>5){ System.out.println(a+" es mayor que 5"); a--; } |
Al ejecutar el programa no saldría nada por pantalla, ya que a vale 0 y la condición para entrar en el bucle while es que a debe ser mayor que 5.
Pero si ahora ejecutamos esta modificación del ejemplo anterior:
1 2 3 4 5 6 |
int a = 10; while(a>5){ System.out.println(a+" es mayor que 5"); a--; } |
Podemos ver que ahora como a =10 es mayor que 5, va a poder entrar en la primera iteración del bucle while. También podemos ver que en cada iteración nos mostrará por pantalla el mensaje y además decrementará el valor de a en una unidad. Por lo tanto el bucle finalizará cuando a valga menos que 5 y la salida por pantalla de la ejecución del programa será:
10 es mayor que 5
9 es mayor que 5
8 es mayor que 5
7 es mayor que 5
6 es mayor que 5
Por lo tanto el mensaje saldrá 5 veces, hasta que a no sea mayor que 5. Pensad que cuando a = 5, a no es mayor ni menor que 5, es igual. Por lo tanto ya no cumple la condición y no entra en el bucle finalizando así el programa.
Do-While
El bucle Do-While tiene mismo propósito de while, repetir un bloque de código mientras una condición se mantenga verdadera, pero en este caso lo primero que hace esta estructura es ejecutar el código y después realizar la evaluación de la condición. Si es verdadera, volverá a realizar otra iteración y si no, finaliza. Por lo tanto el código siempre se ejecutará como mínimo una vez.
El pseudocódigo es:
1 2 3 |
Repetir secuencia_de_acciones Hasta Que (condición) |
La estructura formal es:
1 2 3 |
do{ //Instrucciones }while(condición) |
Por ese motivo, seleccionaremos esta estructura cuando tengamos que hacer un bucle que en la primera iteración ya ejecute el código.
Miremos el siguiente ejemplo:
1 2 3 4 5 6 7 8 9 |
int numero = 4557888; int digitos = 0; do { numero /=10; //Es igual que hacer: numero = numero/10 digitos++; }while ( numero > 0 ); System.out.println(digitos); |
En este ejemplo vemos que lo que hace este programa es dividir el número 4557888 entre 10 e incrementar la variable dígitos en una unidad cada vez. Esto se realizará mientras la variable numero sea mayor que 0. Después finalizará.
El resultado por pantalla es: 7. Significa que el bucle ha realizado 7 iteraciones.
Si modificamos el código para que nos muestre la información en cada iteración (pensad que empieza en la iteración 0):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int numero = 4557888; int digitos = 0; do { numero /=10; System.out.print("Iteración nº: "+digitos); System.out.println(" - número = "+numero); digitos++; }while ( numero > 0 ); System.out.println(" "); System.out.println("Iteraciones = "+digitos); |
Resultado por pantalla:
Iteración nº: 0 – número = 455788
Iteración nº: 1 – número = 45578
Iteración nº: 2 – número = 4557
Iteración nº: 3 – número = 455
Iteración nº: 4 – número = 45
Iteración nº: 5 – número = 4
Iteración nº: 6 – número = 0
Iteraciones = 7
For
EL bucle for es una estructura de control en la que se puede indicar de antemano el número mínimo de iteraciones que queremos realizar, por eso utilizaremos esta estructura cuando queremos tener control sobre el número de iteraciones a realizar.
El pseudocódigo es el siguiente:
1 2 3 |
Para (variable_numerica<-valor_inicial Hasta valor_final Con Paso paso) Hacer secuencia_de_acciones Fin Para |
La estructura formal es:
1 2 3 |
for (inicialización; condición; actualización) { //Instrucciones ejecutadas en cada iteracion } |
Vamos a analizar poco a poco esta estructura for:
- Inicialización: Se declaran la variable con la cuales realizamos el bucle. Por ejemplo: int i = 0;
- Condición: Se determinan las condiciones para continuar dentro del bucle. Por ejemplo: i < 10;
- Actualización: Se modifica el valor de la variable de inicialización. Por ejemplo: i++;
Por ejemplo, queremos escribir 100 veces «Hola, Mundo!»:
1 2 3 |
for (int i = 0; i < 100; i++) { System.out.println("Hola, Mundo!"); } |
El resultado por pantalla sería de este tipo (hasta llegar a 100 mensajes):
Iteración 0: Hola, Mundo!
Iteración 1: Hola, Mundo!
Iteración 2: Hola, Mundo!
Iteración 3: Hola, Mundo!
Iteración 4: Hola, Mundo!
…
Iteración 99: Hola, Mundo!
Ejercicios propuestos
1) Menú gráfico de usuario
Os propongo un reto con lo aprendido hasta ahora. En el programa que hemos visto en esta entrega del curso con la estructura switch, queremos implementar (programar) un menú gráfico de programa que nos pida el valor1, el valor2 y la operación a realizar para más tarde mostrar la operación que queremos realizar y el resultado.
Un ejemplo de solución por pantalla sería:
Escribe el primer número: 2 (INTRO)
Escribe el segundo número: 4 (INTRO)
Que operación deseas realizar? (+, -, *, /, %): + (INTRO)
== Resultado ==
2 + 4 = 6
2) Pirámide de asteriscos
El segundo ejercicio propuesto (¡y muy divertido!), es crear un programa que pida al usuario por pantalla la altura de la pirámide (1, 2, 3, 4, 5 lineas) y el programa nos dibujará una pirámide de asteriscos con la altura (el número de lineas) que nos han pedido. Por ejemplo, un usuario introduce que quiere una pirámide de 5 lineas de altura. El resultado debería ser así:
*
***
*****
*******
*********
¡No seáis tramposos y miréis el código por Internet!, ya que lo detectaré en el código y de lo que se trata es de aprender a programar con Java jugando y divirtiéndonos. Por ese motivo, os daré una pista muy buena: «Debéis pintar tanto los asteriscos como los espacios«.
¿Os atrevéis?
¡Ánimo y dejad vuestras propuestas de código de los ejercicios en los comentarios! Para el ejercicio 1, especificad en el título del comentario «Menú«, y para el ejercicio 2 poned «Pirámide«.
En dos semanas os publicaré la respuesta y entre los códigos que funcionen y que estén mejor elaborados publicaré el mejor.
Hasta aquí la entrega de hoy (¡que ha sido bastante extensa y productiva!). En la próxima entrega nos pondremos con las estructuras de almacenamiento (Arrays).
Aquí os dejo un nuevo vídeo de nuestro canal donde os explico con ejemplos cada una de las estructuras vistas en este post con Java (Eclipse):
No os olvidéis de visitar y suscribiros a nuestro canal de Youtube de para ver los últimos vídeos publicados.
Saludos,
⇐ [Curso JAVA III] Conversiones, enumeraciones y petición de datos
Últimos comentarios