Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Estructuras de Control
Estructuras de Control
ESTRUCTURAS DE CONTROL
2.1.1 Sintaxis
En este apartado vamos a ilustrar una serie de actuaciones erróneas que son
muy habituales entre las personas que empiezan a programar. Resulta especialmente
conveniente prestar atención en este apartado para evitar, en la medida de lo posible,
codificar los programas con errores.
La primera situación que vamos a analizar son los bucles infinitos (producto
siempre de un error en la programación). En el siguiente ejemplo (BucleFor5) se
produce esta situación, debido a que la condición de continuidad del bucle nunca se
evalúa como false. Analizando el programa, llegamos fácilmente a la conclusión de
que la variable i albergará únicamente valores pares positivos, por lo que la
condición de continuidad i!=21 nunca se evaluará como false y por lo tanto nunca se
saldrá del bucle.
Las instrucciones que se repiten (1000 veces) son las que se encuentran
entre los delimitadores { } asociados a la instrucción repetitiva for; por ello tanto la
instrucción 5 como la 6 se ejecutan 1000 veces. En cada vuelta del bucle se añade el
valor de i (1,2,3,4, ..., 1000) al resultado de la suma anterior (guardado en la variable
Suma). La evolución de las variables es la siguiente:
Factorial de un número
Solución:
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 2: ESTRUCTURAS DE CONTROL 27
Para hallar el factorial de cualquier otro número, basta con variar el valor
con el que inicializamos la variable Numero, en la línea 6. Obsérvese que el factorial
de 1 (que es cero) no se saca con este método, y sobre todo, que si el valor de
Numero es muy grande, podemos desbordar el rango del tipo int, por lo que sería
conveniente emplear el tipo long.
Problema de logística
En las grandes ciudades el precio del suelo es muy caro, por lo que comprar
o alquilar grandes superficies de almacenamiento de electrodomésticos resulta
prohibitivo en el centro de la ciudad. La solución es alejarse del núcleo urbano, sin
embargo, cuanto más nos alejamos, más nos cuesta el precio de distribución que
cada día hay que abonar a los transportistas que nos trasladan los electrodomésticos
de la periferia al centro (donde se realizan la mayoría de las compras).
Solución:
Para realizar este ejercicio hubiera sido mucho más elegante emplear una
estructura de control de flujo en bucle que nos permitiera iterar mientras (o hasta)
que se cumpla una condición determinada: (que CapacidadTotal >=100000). El
bucle for no nos resuelve esta situación adecuadamente, puesto que está diseñado
para indicar a priori el número de iteraciones, aunque tampoco resulta imposible
utilizarlo de otra manera:
En cualquier caso, para resolver este ejercicio, resulta más apropiado utilizar
las estructuras de control que se explican en el siguiente apartado.
2.2.1 Sintaxis
do {
Instrucciones a ejecutar de forma repetitiva
} while (condición de continuidad);
Este problema lo podemos resolver de forma muy simple haciendo uso del
bucle while:
6 i++;
7 Suma = Suma + i;
8 } while (Suma<100000);
9 System.out.println(i);
10 }
11 }
Problema de logística
En las grandes ciudades el precio del suelo es muy caro, por lo que comprar
o alquilar grandes superficies de almacenamiento de electrodomésticos resulta
prohibitivo en el centro de la ciudad. La solución es alejarse del núcleo urbano, sin
34 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
embargo, cuanto más nos aleja mos, más nos cuesta el precio de distribución que
cada día hay que abonar a los transportistas que nos trasladan los electrodomésticos
de la periferia al centro (donde se realizan la mayoría de las compras).
Solución:
2.3.1 Sintaxis
if (condición)
Instrucción
if (condición) {
Instrucciones
}
if (condición)
Instrucción de la rama “then”
else
Instrucción de la rama “else”
if (condición) {
Instrucciones de la rama “then”
} else {
Instrucciones de la rama “else”
}
En las dos últimas sintaxis de la instrucción if, se introduce una “rama” else,
cuyo significado es: si la condición se evalúa como true se ejecuta el grupo de
instrucciones de la primera rama (llamémosla “then”), en caso contrario (la
condición se evalúa como false) se ejecuta el grupo de instrucciones de la segunda
rama (la rama “else”).
2.3.3 if anidados
Una solución más fácil de entender, pero mucho más costosa en ejecución
(por el número de condiciones a evaluar) es:
2.4.1 Sintaxis
switch (expresión) {
case valor1:
Instrucciones;
break;
case valor1:
Instrucciones;
break;
...........................
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 2: ESTRUCTURAS DE CONTROL 41
default:
Instrucciones;
break;
}
La cláusula default es muy útil, nos sirve para indicar que se ejecuten sus
instrucciones asociadas en el caso de que no se haya ejecutado previamente ningún
otro grupo de instrucciones.
Nuestro primer ejemplo (Switch1) nos muestra una instrucción switch (línea
5) con una expresión de tipo int. Según el valor de la expresión sea 1, 2 ó 3, se
imprimirán diferentes mensajes. Cuando el valor de la expresión es diferente a 1, 2 y
3 (línea 18) se imprime un mensaje genérico (línea 19). En el ejemplo, si la
instrucción 12 no existiera, se imprimirían dos mensajes: “Medalla de plata” y
“Medalla de bronce”.
10 case 2:
11 System.out.println("Medalla de plata");
12 break;
13
14 case 3:
15 System.out.println("Medalla de bronce");
16 break;
17
18 default:
19 System.out.println("Gracias por participar");
20 break;
21
22 }
23
24 }
25 }
22 }
23
24 }
25 }
Podemos ampliar el ejemplo anterior para que admita también los comandos
en mayúsculas. Obsérvese la nueva sintaxis:
7 System.out.println("Primera opcion");
8 break;
9
10 case 1:
11 System.out.println("Segunda opcion");
12 break;
13
14 case 2:
15 System.out.println("Tercera opcion");
16 break;
17
18 }
19
20 }
21 }
Resulta muy habitual tener que realizar selecciones basadas en dos niveles;
el siguiente ejemplo muestra una de estas situaciones: estamos realizando las
páginas Web de un concesionario de vehículos de la marca SEAT y en un momento
dado el usuario puede escoger entre las siguientes opciones:
Para programar la elección de opción por parte del usuario, resulta adecuado
emplear una instrucción switch anidada:
11 break;
12 case 'b':
13 Disponible = true;
14 break;
15 case 'r':
16 Disponible = true;
17 break;
18 default:
19 System.out.println("Opcion no contemplada");
20 break;
21 }
22 break;
23
24 case 'c':
25 switch (Color) {
26 case 'a':
27 Disponible = false;
28 break;
29 case 'b':
30 Disponible = true;
31 break;
32 case 'r':
33 Disponible = false;
34 break;
35 default:
36 System.out.println("Opcion no contemplada");
37 break;
38 }
39 break;
40
41 case 't':
42 switch (Color) {
43 case 'a':
44 Disponible = false;
45 break;
46 case 'b':
47 Disponible = true;
48 break;
49 case 'r':
50 Disponible = true;
51 break;
52 default:
53 System.out.println("Opcion no contemplada");
54 break;
55 }
56 break;
57
58 default:
59 System.out.println("Opcion no contemplada");
46 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
60 break;
61 }
62
63 if (Disponible)
64 System.out.println("Opcion disponible");
65 else
66 System.out.println("Opcion no disponible");
67
68 }
69 }
4 byte Mes = 2;
5 boolean Bisisesto = false;
6
7 switch (Mes) {
8 case FEBRERO:
9 if (Bisisesto)
10 System.out.println(29);
11 else
12 System.out.println(28);
13 break;
14
15 case ABRIL:
16 case JUNIO:
17 case SEPTIEMBRE:
18 case NOVIEMBRE:
19 System.out.println(30);
20 break;
21
22 case ENERO:
23 case MARZO:
24 case MAYO:
25 case JULIO:
26 case AGOSTO:
27 case OCTUBRE:
28 case DICIEMBRE:
29 System.out.println(31);
30 break;
31
32 default:
33 System.out.println("Numero de mes erroneo");
34 break;
35 }
36 }
37 }
2.5 EJEMPLOS
En esta lección se realizan tres ejemplos en los que se combinan buena parte
de los conceptos explicados en las lecciones anteriores. Los ejemplos seleccionados
son:
1. Cálculo de la hipotenusa de un triángulo
2. Soluciones de una ecuación de segundo grado
50 JAVA A TRAVÉS DE EJEMPLOS JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES)
Para permitir que el usuario pueda seleccionar, en cada caso, los parámetros
necesarios (longitudes de los catetos, coordenadas de los vectores en las rectas, etc.)
se proporciona una clase de entrada de datos por teclado desarrollada por el autor: la
clase Teclado, que consta de los métodos:
• public static String Lee_String()
• public static long Lee_long()
• public static int Lee_int()
• public static int Lee_short()
• public static byte Lee_byte()
• public static float Lee_float()
• public static double Lee_double()
De esta manera, para leer un valor de tipo byte, podemos utilizar una
instrucción similar a: byte Edad = Teclado.Lee_byte();
H = √ C12 * C22
C1
C2
JESÚS BOBADILLA SANCHO (JBOBI@EUI.UPM.ES) CAPÍTULO 2: ESTRUCTURAS DE CONTROL 51
Ejercicio resuelto
Comentarios
Resultados
X1, Y1
X2, Y2
Cualquier punto de la recta puede obtenerse multiplicando un número real por los
vectores (X2-X1) e (Y2-Y1):
X1, Y1
X2, Y2
Siendo t el valor real a partir del cual podemos obtener cualquier punto de la
recta. Si dibujamos dos rectas no paralelas:
X4, Y4 X = X1 + (X2-X1) * t
Y = Y1 – (Y2-Y1) * t
X1, Y1
El punto de corte es el que cumple que la X y la Y en las dos rectas son los
mismos:
X1 + (X2-X1) * t = X3 + (X4-X3) * r
Y1 – (Y2-Y1) * t = Y4 – (Y4-Y3) * r
Despejando:
Ejercicio resuelto
22 X3 = Teclado.Lee_int();
23 System.out.println();
24
25 System.out.print("Introduce el valor de X4:");
26 X4 = Teclado.Lee_int();
27 System.out.println();
28
29 System.out.print("Introduce el valor de Y3:");
30 Y3 = Teclado.Lee_int();
31 System.out.println();
32
33 System.out.print("Introduce el valor de Y4:");
34 Y4 = Teclado.Lee_int();
35 System.out.println();
36
37 int Denominador = (Y4-Y3)*(X2-X1) - (Y2-Y1)*(X4-X3);
38 if (Denominador == 0)
39 System.out.println("Las rectas son paralelas");
40 else {
41 int Numerador = (Y4-Y3)*(X3-X1) - (Y3-Y1)*(X4-X3);
42 float t = (float) Numerador / (float) Denominador;
43 float CorteX = X1 + (X2-X1)*t;
44 float CorteY = Y1 + (Y2-Y1)*t;
45 System.out.println("Punto de corte: " + CorteX +
46 ", "+ CorteY);
47 }
48
49 }
50 }
Comentarios
Resultados
Una ecuación de grado 2 define una parábola, que puede no cortar el eje x,
cortarlo en un único punto o bien cortarlo en dos puntos.
Ejercicio resuelto
19 if (Auxiliar<0)
20 System.out.println("No existen raices reales");
21 else
22 if (Auxiliar == 0d) {
23 System.out.print("Solo existe una raiz: ");
24 System.out.println(-b/2d*a);
25 } else { // Auxiliar mayor que cero
26 Auxiliar = Math.sqrt(Auxiliar);
27 double Raiz1 = (-b + Auxiliar) / (2 * a);
28 double Raiz2 = (-b - Auxiliar) / (2 * a);
29 System.out.println("Raices: " + Raiz1 +
30 ", "+ Raiz2);
31 }
32
33 }
34 }
Comentarios
Resultados