


























Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
introduccion a la programacion en el lenguaje de programacion java
Tipo: Guías, Proyectos, Investigaciones
1 / 34
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!



























6.1 Sentencia while 133
En este capítulo aprenderá a:
objetivos
introducción
6.1 Sentencia while
Un bucle o lazo es cualquier construcción de programa que repite una sentencia o se- cuencia de sentencias determinado número de veces; cuando ésta se menciona varias veces en un bloque se denomina cuerpo del bucle ; cada vez que éste se repite se denomina iteración del bucle. Las dos cuestiones principales de diseño en la construcción del bucle son: ¿cuál es el cuerpo del bucle? y ¿cuántas veces se iterará el cuerpo del bucle?
134 CAPÍTULO 6 Estructuras de control: bucles (lazos)
Un bucle while tiene una condición, una expresión lógica que controla la secuen- cia de repetición; su posición es delante del cuerpo del bucle y significa que while es un bucle pretest , de modo que cuando éste se ejecuta, se evalúa la condición antes de ejecu- tarse el cuerpo del bucle; la figura 6.1 representa el diagrama de while. El diagrama indica que la ejecución de la sentencia o sentencias expresadas se repite mientras la condición del bucle permanece verdadera y termina al volverse falsa; tam- bién indica que la condición se examina antes de ejecutarse el cuerpo y, por consiguien- te, si aquélla es inicialmente falsa, éste no se ejecutará; en otras palabras, el cuerpo de un bucle while se ejecutará cero o más veces.
Figura 6.1 Diagrama de while.
Condición_bucle
Falsa
Verdadera
Sentencia
1. while ( condición_bucle ) sentencia; Cuerpo 2. while ( condición_bucle ) { sentencia-1; sentencia-2 ; . . Cuerpo . sentencia-n ; }
while es una palabra reservada de Java condición_bucle es una expresión lógica sentencia es una sentencia simple o compuesta
El comportamiento o funcionamiento de una sentencia o bucle while es:
1. Se evalúa condición_bucle.
136 CAPÍTULO 6 Estructuras de control: bucles (lazos)
. . .
Por ejemplo:
// Bucle de muestra con while
class Bucle { public static void main(String[] a) { int contador = 0; // inicializa la condición while(contador < 5) // condición de prueba { contador ++; // cuerpo del bucle System.out.println("contador: " + contador); } System.out.println("Terminado.Contador: " + contador); } }
Ejecución contador:^1 contador: 2 contador: 3 contador: 4 contador: 5 Terminado.Contador: 5
EJEMPLO 6.
Una de las aplicaciones más usuales del operador de incremento ++ es la de controlar la iteración de un bucle.
// programa cálculo de calorías import java.util.Scanner; class Calorias { public static void main(String[] a) { int num_de_elementos, cuenta, calorias_por_alimento, calorias_total; Scanner entrada = new Scanner(System.in); System.out.print("¿Cuántos alimentos ha comido hoy? "); num_de_elementos = entrada.nextInt(); System.out.println("Introducir el número de calorías de" + " cada uno de los " + num_elementos + " alimentos tomados:"); calorias_total = 0; cuenta = 1; while (cuenta++ <= numero_de_elementos)
6.1 Sentencia while 137
{ calorias_por_alimento = entrada.nextInt(); calorias_total += calorias_por_alimento; } System.out.println(("Las calorías totales consumidas hoy son = " + calorias_total); }
Un error común en el diseño de una sentencia while se produce cuando el bucle sólo tiene una sentencia en lugar de varias como se planeó; el código siguiente
contador = 1; while (contador < 25) System.out.println(contador); contador++;
visualizará infinitas veces el valor 1 porque entra en un bucle infinito que no se actualiza al modificar la variable de control contador; la razón es que el punto y coma al final de la línea System.out.println(contador); hace que el bucle termine allí, aunque aparentemente el sangrado da la sensación de que el cuerpo de while contiene 2 sen- tencias, System.out.println() y contador++. El error se detecta rápidamente si el bucle se escribe correctamente:
contador = 1; while (contador < 25) System.out.println(contador); contador++;
La solución más sencilla es utilizar las llaves de la sentencia compuesta como se mues- tra a continuación:
contador = 1; while (contador < 25) { System.out.println(contador); contador++; }
Por lo general, no se conoce con exactitud cuántos elementos de datos se procesarán antes de comenzar su ejecución debido a que hay muchos más por contar, o bien, porque el número de datos a procesar depende de la secuencia del proceso de cálculo.
Ejecución ¿Cuántos alimentos ha comido hoy? 4 Introducir el número de calorías de cada 1 de los 4 alimentos ingeridos: 500 350 1400 700 Las calorías totales consumidas hoy son = 2950
6.1 Sentencia while 139
cuando dicho dato sea un dígito y, en este caso, el valor de la variable digito_leido cambiará a verdadero. En consecuencia, la condición del bucle debe ser !digito_ leido ya que es verdadera cuando digito_leido es falso. El bucle while será:
digito_leido = false; // no se ha leído ningún dato while (!digito_leido) { System.out.print("Introduzca un carácter: "); car = System.in.read(); // lee siguiente carácter System.in.skip(1); // salta 1 carácter(fin de línea) digito_leido = (('0'<= car) && (car <= '9')); ... } // fin de while
El bucle funciona de la siguiente forma:
1. Entrada del bucle: la variable digito_leido tiene un valor falso. 2. Como la condición del bucle !digito_leido es verdadera, se ejecutan las sentencias al interior del bucle. 3. Por medio del teclado se introduce un dato que se almacena en la variable car; si es un carácter, digito_leido se mantiene falso ya que es el resultado de la sentencia de asignación:
digito_leido = (('0'<= car) && (car <= '9'));
Si el dato ingresado es un dígito, entonces la variable digito_ leido toma el valor verdadero resultante de la sentencia de asig- nación anterior.
4. El bucle termina cuando se lee un dígito entre 0 y 9 ya que la con- dición del bucle es falsa.
El formato general del modelo de bu- cle controlado por un indicador es el siguiente:
NOTA
EJEMPLO 6.
Se desea leer un dato numérico x con valor mayor que 0 para calcular la función f(x) = x*log(x).
La bandera xpositivo se utiliza para representar que el dato leído es mayor que 0, entonces la variable xpositivo se inicializa a false antes de que el bucle se ejecute y el dato de entrada se lea; cuando se ejecuta, el bucle debe continuar mientras el nú- mero leído sea negativo o 0, es decir, mientras la variable xpositivo sea false y se debe detener cuando el número leído sea mayor que 0, dando lugar a que xpositi- vo cambie a true. Considerando lo anterior, la condición del bucle debe ser !x_po- sitivo ya que ésta es true cuando xpositivo es false; a su salida, el valor de la función se calcula y se escribe la codificación correspondiente:
import java.util.Scanner; class FuncionLog { public static void main(String[] a) { double f, x; boolean xpositivo;
140 CAPÍTULO 6 Estructuras de control: bucles (lazos)
Scanner entrada = new Scanner(System.in); xpositivo = false; // inicializado a falso while (!xpositivo) { System.out.println("\n Valor de x: "); x = entrada.nextDouble(); xpositivo = (x > 0.0); //asigna true si x>0. } f = x*Math.log(x); System.out.println(" f(" + x + ") = " + f);
} }
La sentencia break a veces se utiliza para realizar una terminación anormal del bucle o antes de lo previsto; su sintaxis es:
break;
La sentencia break se utiliza para la salida de un bucle while, do-while o for, aunque su uso más frecuente es dentro de una sentencia switch.
while ( condición1 ) { if ( condición2 ) break; // sentencias }
EJEMPLO 6.
El siguiente código lee y visualiza los valores de entrada hasta que se encuentra el valor clave especificado:
int clave = -9; boolean activo = true; while (activo) { int dato; dato = entrada.nextInt(); if (dato != clave) System.out.println(dato); else break ; }
¿Cómo funciona este bucle while? El método nextInt() lee un número entero desde el dispositivo de entrada; si su condición siempre fuera true, se ejecutaría indefinidamente; sin embargo, cuando hay un dato==clave, la ejecución sigue por else y, por su parte, break hace que la ejecución continúe en la sentencia siguien- te a while.
El uso de break en un bucle no es recomendable ya que puede dificultar la comprensión del comportamiento del programa; en particular, suele complicar la verificación de los inva- riantes. Además, la reescritura de los bucles sin break es fácil; por ejemplo, éste es el bucle anterior sin dicha sen- tencia: final int clave = -9; int dato = clave+1; while (dato != clave) { dato = entrada.nextInt(); if (dato != clave) System.out.println(dato); }
PRECAUCIÓN
142 CAPÍTULO 6 Estructuras de control: bucles (lazos)
System.out.println("Media: \n" + media); } }
Para transferir el control a la siguiente sentencia de una estructura de bucles anidados, se utiliza la sentencia break con etiqueta; cuya sintaxis es:
break etiqueta
Por ejemplo, el siguiente fragmento escribe números enteros generados aleatoria- mente y termina el bucle cuando el número es múltiplo de 7. Los números son generados por el método random() de la clase Math el cual de- vuelve un valor double mayor o igual a 0.0 y menor que 1.0; para obtener valores ente- ros se multiplica por una variable que toma valores desde 11 hasta 114 y se generan 10 números aleatorios para cada uno; después, se escriben 2 bucles anidados y la estructura se etiqueta con mult7. Cuando un dato entero generado es múltiplo de 7, break mult7, hace que la ejecución pase a la siguiente sentencia.
class GeneraEnteros { public static void main(String []a) { int numero; System.out.println("\nValores generados aleatoriamente"); mult7: int tope = 11 while (tope <= (int)Math.pow(11.,4)) { int k = 1; while (k <= 10) { numero = (int)Math.random()*tope + 1; System.out.print(numero+" "); if (numero % 7 == 0) break mult7; k++ } System.out.println(); tope+= } System.out.println("Bucles han terminado con número= " +numero); } }
En el caso de no especificar etiqueta, el control de la ejecución se transfiere a la sen- tencia siguiente al bucle o sentencia switch, desde el que se ejecuta.
6.2 Repetición: bucle for
Además de while, Java proporciona otros dos tipos de bucles: for y do; el primero es el más adecuado para implementar conjuntos de sentencias que se ejecutan una vez por
6.2 Repetición: bucle for 143
cada valor de un rango especificado; a éstos se les llama bucles controlados por contador , y su algoritmo es:
por cada valor de una variable_contador de un rango específico: ejecutar sentencias
La sentencia o bucle for es la mejor forma de programar la ejecución de un bloque de sentencias un número fijo de veces; éste sitúa las operaciones de control del bucle en la cabecera de la sentencia.
for ( Inicialización; CondiciónIteración; Incremento )
Sentencias a ejecutar en cada iteración del bucle
(1) Inicializa la variable de control del bucle
(2) Expresión lógica que determina que las sentencias se ejecutan mientras sea verdadera
(3) Incrementa o decrementa la variable de control del bucle
(4) Sentencias
El bucle for se compone de:
inicialización ; while ( condiciónIteración ) { sentencias del bucle for; incremento ; }
Por ejemplo:
// imprimir Hola 10 veces for (int i = 0; i < 10; i++) System.out.println("Hola!");
O, como se indica en seguida:
int i; for (i = 0; i < 10; i++)
1 1 2 4 3 9 4 16 5 25 6 36 7 49 8 64 9 81 10 100
A continuación se presenta un ejemplo del formato descendente:
for (int n = 10; n > 5; n--) System.out.println("\t" + n + "\t" + n * n );
Su salida es:
10 100 9 81 8 64 7 49 6 36
debido a que el valor inicial de la variable de control es 10 , y el límite que se ha puesto es n > 5; es decir, es verdadera cuando n = 10, 9, 8, 7, 6; la expresión de decremen- to es n-- que disminuye en 1 el valor de d tras la ejecución de cada iteración.
Figura 6.2 Diagrama de sintaxis de un bucle for.
Var_control <= Valor_límite
Falso
Verdadera
Sentencia
Var_control = Valor_inicial
exp_incremento
6.2 Repetición: bucle for 145
146 CAPÍTULO 6 Estructuras de control: bucles (lazos)
A continuación se muestran otros intervalos de incremento/decremento: Los rangos de incremento/decremento de la variable o expresión de control del bucle pueden tener cualquier valor y no siempre 1 , es decir 5 , 10 , 20 , 4 , etcétera, depen- diendo de los intervalos necesarios; así, el bucle:
for (int n = 0; n < 100; n += 20) System.out.println("\t" + n + "\t" + n * n );
utiliza la expresión de incremento
n += 20
que aumenta el valor de n en 20 , puesto que equivale a n = n + 20 ; por tanto, la sali- da que producirá la ejecución del bucle es:
0 0 20 400 40 1600 60 3600 80 6400
Por ejemplo:
1. Inicializa la variable de control del bucle c al carácter 'A', lo cual equivale a iniciali- zar al entero 65 porque éste es el código ASCII de A e itera mientras el valor de la variable c sea menor o igual que el ordinal del carácter 'Z'. La parte de incremento del bucle aumenta el valor de la variable c en 1; por consiguiente, el bucle se realiza tantas veces como letras mayúsculas se necesiten.
for (int c = 'A'; c <= 'Z'; c++) System.out.print(c + " "); System.out.println();
2. Muestra un bucle descendente que inicializa la variable de control a 9 , el cual se rea- liza mientras i no sea negativo; como la variable disminuye en 3 , el bucle se ejecuta 4 veces con el valor de la variable de control i, 9 , 6 , 3 y 0.
for (int i = 9; i >= 0; i -= 3) System.out.println(" " + i*i);
3. La variable de control i se inicializa a 1 y se incrementa en múltiplos de 2; por con- siguiente, i toma valores de 1 , 2 , 4 , 8 , 16 , 32 , 64 y como el siguiente, 128 , no cum- ple la condición, termina el bucle.
for (i = 1; i < 100; i *= 2) System.out.println(" " + i);
4. Declara 2 variables de control i y j y las inicializa a 0 y la constante MAX; el bucle se ejecutará mientras i sea menor que j; además, i se incrementa en 1 , mientras j se decrementa en 1.
final int MAX = 25; int i,j; for (i = 0, j = MAX; i < j; i++, j--) System.out.println("d = " + (i + 2 * j));
148 CAPÍTULO 6 Estructuras de control: bucles (lazos)
Un bucle for se debe construir con precaución, asegurándose que la expresión de ini- cialización y la de incremento harán que la condición se convierta en false en algún momento; en particular “si el cuerpo de un bucle de conteo modifica los valores de cual- quier variable implicada en la condición, entonces el número de repeticiones se puede modificar”;^1 esta regla es importante porque su aplicación se considera una mala práctica de programación. Es decir, no es recomendable modificar el valor de cualquier variable de la condición del bucle dentro del cuerpo de un bucle for, ya que se pueden producir resultados imprevistos; por ejemplo, la ejecución de
int limite = 11; for (int i = 0; i <= limite; i++) { System.out.println(i); limite++; }
produce una secuencia infinita de enteros, la cual puede terminar si el compilador tiene constantes MAXINT con máximos valores enteros; entonces la ejecución finalizará cuan- do i sea MAXINT y limite sea MAXINT+1 = MININT ya que, a cada iteración, la ex- presión limite++ aumenta limite en 1, antes de que i++ incremente i.
0 1 2 3...
Como consecuencia, la condición del bucle i <= limite siempre es verdadera. Otro ejemplo de un bucle mal programado es:
int limite = 1;
for (int i = 0; i <= limite; i++) { System.out.println(i); i--; }
el cual producirá ceros infinitos
0 0 0 . .
porque en este caso la expresión i-- del cuerpo decrementa i en 1 antes de que se in- cremente la expresión i++ de la cabecera en 1 ; como resultado i es siempre 0 cuando el bucle se comprueba.
(^1) Joyanes, L., Programación en Java 2 , Madrid, McGraw-Hill, 2002, p. 220.
Éste es otro ejemplo de bucle mal programado, la condición para terminarlo depen- de de un valor de la entrada:
final int LIM = 50 int iter,tope; for (iter = tope = 0; tope <= LIM; iter++) { System.out.println("Iteración: " + iter); tope = entrada.nextInt(); }
El objetivo principal de un bucle for es implementar bucles de conteo en el que el número de repeticiones se conoce por anticipado; por ejemplo, la suma de enteros de 1 a n; sin embargo, existen muchos problemas en los que el número de repeticiones no se puede determinar por anticipado; para lo cual se puede implementar un bucle infinito.
for (;;) sentencia;
La sentencia se ejecuta indefinidamente a menos que se utilice return o break; aunque normalmente es una combinación if-break o if-return; la razón de la eje- cución indefinida es que se eliminó la expresión de inicialización, la condición y la ex- presión de incremento, y al no existir una condición específica para terminar la repetición de sentencias, se asume que la condición es verdadera; por ejemplo:
for (;;) System.out.println("Siempre así, te llamamos siempre así...");
producirá la salida
Siempre así, te llamamos siempre así... Siempre así, te llamamos siempre así... ...
un número ilimitado de veces, a menos que el usuario interrumpa la ejecución. Para evitar esto, se requiere que el diseño del bucle for sea de la forma siguiente:
1. El cuerpo del bucle debe contener todas las sentencias que se desean ejecutar repe- tidamente. 2. Una sentencia terminará la ejecución del bucle cuando se cumpla determinada con- dición. La sentencia de terminación suele ser if-break con la sintaxis:
6.2 Repetición: bucle for 149
En realidad, lo que sucede es que se visualiza una vez la frase "Sierra Magina" ya que for es una sentencia vacía pues termina con un punto y coma (;); por tanto, no hace nada durante 10 iteraciones y al terminar se ejecuta la sentencia System.out. println(), y se escribe "Sierra Magina".
Cualquiera de las tres o todas las expresiones que controlan un bucle for pueden ser nulas o vacías; el punto y coma (;) es el que marca una expresión vacía. Si la intención es crear un bucle for que actúe exactamente como while, se deben dejar vacías la prime- ra y tercera sentencias; por ejemplo, el siguiente for funciona como while, y tiene va- cías las expresiones de inicialización y de incremento:
int contador = 0; for (;contador < 5;) { contador++; System.out.print("¡Bucle! "); } System.out.println("\n Contador: " + contador);
Ejecución ¡Bucle! ¡Bucle! ¡Bucle! ¡Bucle! ¡Bucle! Contador: 5
La sentencia for no inicializa ningún valor, pero incluye una prueba de contador < 5 previamente inicializado; tampoco existe una sentencia de incremento, de modo que el bucle se comporta exactamente como la sentencia siguiente:
while(contador < 5) { contador++; System.out.printl("¡Bucle! "); }
Esta sentencia se utiliza en el contexto de un bucle y hace que la ejecución prosiga con la siguiente iteración saltando las sentencias que están a continuación; en bucles while/do- while, la ejecución prosigue con la condición de control del bucle, mientras que en bucles for, la ejecución prosigue con la expresión de incremento. Su sintaxis es la siguiente:
continue; continue etiqueta ;
EJEMPLO 6.
Se generan n números aleatorios de forma que se escriban todos excepto los múltiplos de 3.
class Multipls {
6.2 Repetición: bucle for 151
152 CAPÍTULO 6 Estructuras de control: bucles (lazos)
public static void main(Strings [] a) { final int CLAVE = 3; final int RANGO = 999; int n = (int)Math.random()RANGO +1; for (i = 0; i < n; i++) { int numero; numero = (int)Math.random()RANGO +1; if (numero % CLAVE == 0) { System.out.println(); continue; } System.out.print(" " + numero); } } }
Al generarse un entero múltiplo de 3 , se realiza un println vacío para que en- cuentre un salto de línea y continue hace que la ejecución vuelva a la cabecera de for, por consiguiente no se escribe el número en la pantalla. Cuando la sentencia continue se ejecuta con etiqueta en una estructura repetiti- va, salta las sentencias que quedan hasta el final del cuerpo del bucle y la ejecución prosigue con la siguiente iteración que está en seguida de la etiqueta especificada; en bucles while/do-while, la ejecución prosigue con la evaluación de la condición de control que se encuentra después de la etiqueta; por último, en bucles for la ejecu- ción prosigue con la expresión de incremento.
EJEMPLO 6.
El programa Asteriscos escribe líneas con asteriscos en una cantidad igual al nú- mero de línea correspondiente del código fuente.
class Asteriscos { public static void main(Strings [] a) { final int COLUMNA = 17; final int FILA =
siguiente: for (int f = 1; f <= FILA; f++) { System.out.println(); for (int c = 1; c <= COLUMNA; c++) { if (c > f) continue siguiente; System.out.print'*'); } } } }