Ciclos

con un ciclo infinito, se puede presionar las teclas CTRL-C para abortar el programa. Para prevenir que un ciclo while se ejecute infinitamente, tres acciones ...
197KB Größe 15 Downloads 108 vistas
Ciclos H. Tejeda Marzo 2016

´Indice 1. Estructura de ciclo

1

2. Creaci´ on de ciclos while

2

3. Operadores aritm´ eticos abreviados

8

4. Creaci´ on de ciclos for

10

5. Creaci´ on de ciclos do...while

12

6. Ciclos anidados

15

7. Rendimiento de ciclos

16

1.

Estructura de ciclo

Con las decisiones se hace que un programa parezca inteligente, con ciclos se hace que el programa se vea poderoso. Un ciclo, o bucle, es una estructura que permite repetir la ejecuci´on de un bloque de sentencias. Una expresi´on booleana es evaluada dentro de la estructura de ciclo. Si la expresi´on es true, un bloque de sentencias, cuerpo del ciclo, se ejecuta y la expresi´on booleana vuelve a ser evaluada otra vez. El cuerpo del siglo puede ser una sola sentencia o un bloque de sentencias entre llaves. Mientras la expresi´on booleana sea true, las sentencias en el cuerpo del ciclo se contin´ uan ejecutando. Cuando la evaluaci´on booleana es false, el ciclo termina. Una ejecuci´on de cualquier ciclo se denomina iteraci´ on. En la figura 1 se muestra un diagrama de la l´ogica de un ciclo. 1

Figura 1: Diagrama de flujo de una estructura de bucle. Se pueden emplear varios tipos de ciclos en Java. Se revisar´an los siguientes tres tipos de ciclos. Ciclo while, la expresi´on booleana que controla el ciclo es la primera sentencia en el ciclo. Ciclo for, es una formato compacto para ejecutar ciclos. Ciclo do...while, la expresi´on booleana que controla el ciclo es la u ´ltima sentencia en el ciclo.

2.

Creaci´ on de ciclos while

Se puede usar un ciclo while para ejecutar un cuerpo de sentencias mientras una expresi´on booleana que controla la entrada en el ciclo contin´ ua siendo true. Un ciclo while consiste de la palabra reservada while seguida de una expresi´on booleana dentro de par´entesis, seguida por el cuerpo del ciclo. Se usan un ciclo while cuando se necesita hacer una tarea un predeterminado n´ umero de veces o una cantidad impredecible de veces. Un ciclo que se ejecuta una cantidad espec´ıfica de veces es un ciclo definido, o un ciclo contado. Por otra parte, la cantidad de veces que el ciclo se ejecuta podr´ıa no estar determinado cuando se est´a ejecutando el programa. Tal ciclo es un ciclo no definido ya que no se sabe cu´antas veces ser´a ejecutado.

2.1.

Ciclo while definido

Para escribir un ciclo definido se inicializa una variable de control del ciclo, cuyo valor determina si la ejecuci´on del ciclo contin´ ua. Mientras el valor booleano que resulta de la comparaci´on de la variable de control de ciclo contra otro valor sea true, el cuerpo del ciclo while se continuar´a ejecutando. En el cuerpo del ciclo, se deber´a incluir una sentencia 2

que modifique la variable de control del ciclo. El siguiente segmento de c´odigo muestra la secuencia de enteros del uno al diez. La variable val es la variable de control del ciclo—esta inicia el ciclo teniendo el valor de uno, y mientras el valor es menor que once, val contin´ ua mostr´andose e increment´andose. int val; final int LIMITE = 11; val = 1; while (val < LIMITE) { System.out.println(val); val = val + 1; } Cuando se escriben c´odigos conteniendo ciclos, es f´acil cometer errores. La ejecuci´on del siguiente c´odigo muestra el mensaje “Hola” siempre (te´oricamente) porque no hay c´odigo para terminar el ciclo. Un ciclo que nunca termina se conoce como un ciclo infinito. while ( 4>2 ) { System.out.println("Hola"); } En el c´odigo anterior, la expresi´on 4 > 2 eval´ ua a true as´ı que en ese ciclo, se entra al cuerpo del ciclo y “Hola” es mostrado. Enseguida, la expresi´on es evaluada nuevamente. La expresi´on 4 > 2 todav´ıa es true, as´ı que se ingresa al cuerpo otra vez. “Hola” se muestra repetidamente; el ciclo nunca termina porque 4 > 2 nunca ser´a false. Es una mala idea escribir un ciclo infinito intencionalmente. Se sugiere que antes de empezar a escribir ciclos infinitos, se sepa como salir de este ciclo. En la ejecuci´on de una aplicaci´on con un ciclo infinito, se puede presionar las teclas CTRL-C para abortar el programa. Para prevenir que un ciclo while se ejecute infinitamente, tres acciones separadas deber´an ocurrir: Una variable de control del ciclo se deber´a inicializar con un valor inicial. La variable de control del ciclo es probada en la sentencia while. La variable de control del ciclo es modificada dentro del cuerpo del ciclo. La variable deber´a ser modificada para que la expresi´on de prueba pueda eventualmente evaluar a false y as´ı el ciclo pueda terminar. Las condiciones anteriores se cumplen en el siguiente segmento de c´odigo. Primero, una variable de control del ciclo contadorCiclo es puesta al valor uno. Segundo, la sentencia while(contadorCiclo < 3) es probada. Tercero, el cuerpo del ciclo es ejecutado porque la 3

variable de control del ciclo contadorCiclo es menor que 3. El cuerpo del ciclo consiste de dos sentencias formando un bloque con las llaves que las encierran. La primera sentencia muestra “Hola”, y luego la segunda sentencia agrega uno a contadorCiclo. La siguiente vez que contadorCiclo es evaluado, este es dos, la cual todav´ıa es menor que 3, as´ı que el cuerpo del ciclo se ejecuta nuevamente. “Hola” se muestra por segunda vez, y contadorCiclo tiene tres. Finalmente, como la expresi´on contadorCiclo < 3 eval´ ua a false, el ciclo termina. La ejecuci´on del programa entonces contin´ ua con cualquier sentencia siguiente. contadorCiclo = 1; while (contadorCiclo < 3) { System.out.println("Hola"); contadorCiclo = contadorCiclo + 1; }

2.2.

Errores al codificar ciclos while

Se muestran enseguida algunos errores de l´ogica que pueden aparecer al no tener cuidado al escribir un ciclo while. 2.2.1.

Variable de control del ciclo sin modificaci´ on en el cuerpo

La variable de control del ciclo deber´a ser modificada dentro del cuerpo del ciclo. En el siguiente c´odigo, parecido al anterior, se han eliminado las llaves. En este caso, el cuerpo del ciclo while termina en el punto y coma al final de la sentencia que muestra “Hola”. Agregar uno a contadorCiclo no es parte de un bloque del ciclo, as´ı que el valor de contadorCiclo nunca cambia, y por lo tanto se tien un ciclo infinito. contadorCiclo = 1; while (contadorCiclo < 3) System.out.println("Hola"); contadorCiclo = contadorCiclo + 1; 2.2.2.

Creaci´ on de un ciclo con un cuerpo vac´ıo

Al igual que con la sentencia de decisi´on if, la colocaci´on del punto y coma es importante cuando se usa la sentencia while. Si un punto y coma es incorrectamente colocado al final de la sentencia parcial, como se muestra en el siguiente c´odigo, el ciclo tambi´en es infinito. Este ciclo tiene un cuerpo vac´ıo, o un cuerpo sin sentencias. As´ı, la expresi´on booleana es evaluada, y como sea true, se ingresa al cuerpo del ciclo. Como el cuerpo del ciclo est´a vac´ıo, no se toma ninguna acci´on, y la expresi´on booleana es evaluada otra vez. Nada ha cambiado, as´ı que sigue siendo true, se entra nuevamente al cuerpo vac´ıo, y el ciclo infinito contin´ ua. 4

contadorCiclo = 1; while (contadorCiclo < 3); { System.out.println("Hola"); contadorCiclo = contadorCiclo + 1; }

2.3.

Modificaci´ on de la variable de control del ciclo definido

Un ciclo definido es un ciclo controlado por contador ya que la variable de control del ciclo es cambiada al contar. Es habitual modificar el valor de la variable de control del ciclo agregando uno, o incrementando la variable. Sin embargo, no todos los ciclos son controlados agregando uno. El siguiente ciclo muestra “Hola” dos veces, pero el ciclo es controlando sustrayendo uno a la variable de control de ciclo, o decrement´ andola. contadorCiclo = 3; while (contadorCiclo > 1) { System.out.println("Hola"); contadorCiclo = contadorCiclo - 1; } En el segmento de programa previo, la variable contadorCiclo inicia con un tres. contadorCiclo es mayor que uno, as´ı el cuerpo del ciclo muestra “Hola” y decrementa contadorCiclo a dos. La expresi´on booleana en el ciclo while es revisada otra vez. Como dos es mayor que 1, “Hola” es mostrado otra vez, y contadorCiclo se hace uno. Ahora contadorCiclo no es mayor que uno, as´ı el ciclo termina. Hay varias formas de ejecutar un ciclo dos veces. Es importante no usar metodos inusuales para contar repeticiones porque hacen al programa confuso; por ejemplo iniciar con doce, continuar mientras sea mayor que dos, y decrementar el valor por cinco cada vez. El m´etodo m´as claro y mejor es iniciar la variable de control del ciclo en cero o uno, incrementar por uno cada vez a trav´es del ciclo, y parar cuando la variable de control de ciclo alcance el l´ımite apropiado. Nota. Muchos programadores expertos inician los valores de los contadores en cero porque este valor es usado cuando se trabaja con arreglos. En el caso de los arreglos sus elementos est´an numerados o identificados con un´ındice iniciando con cero, ya que todos los elementos comparten el mismo nombre.

2.4.

Ciclo while indefinido

En ocasiones un ciclo es alterado por la entrada del usuario en vez de ser un ciclo controlado por un contador, un ciclo indefinido es un ciclo controlado por evento, es decir, un 5

evento ocurre para determinar si el ciclo contin´ ua. Un ciclo controlado por evento es un tipo de ciclo indefinido porque no se sabe cu´antas veces ser´a repetido. Por ejemplo, quiz´as se quiera continuar haciendo alguna tarea en tanto el usuario indique su deseo de continuar presionando alguna tecla, en este caso no se sabe la cantidad de veces que ser´a ejecutado el ciclo. Considerar la aplicaci´on SaldoBancario la cual pide al usuario un saldo bancario y luego pide al usuario si quiere ver el saldo despu´es de que el inter´es ha sido acumulado. Cada vez que el usuario decide continuar, un saldo incrementado aparece, mostrando un a˜ no m´as de interes´es acumulados. Cuando el usuario finalmente decide salir, el programa termina. El programa aparece en el c´odigo 1. 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

import j a v a . u t i l . Scanner ; public c l a s s S a l d o B a n c a r i o { public s t a t i c void main ( S t r i n g [ ] a r g s ) { double s a l d o ; int r e s p u e s t a ; int a˜ no = 1 ; f i n a l double TASA = 0 . 0 3 ; Scanner t e c l a d o = new Scanner ( System . i n ) ; System . out . p r i n t ( ” I n g r e s a r e l s a l d o b a n c a r i o i n i c i a l : ” ) ; s a l d o = t e c l a d o . nextDouble ( ) ; System . out . p r i n t l n ( ”¿ Q u i e r e s v e r e l s a l d o en e l s i g u i e n t e a˜ no ? ” ) ; System . out . p r i n t ( ” I n g r e s a 1 para SI ” ) ; System . out . p r i n t ( ” o c u a l q u i e r o t r o n´ u mero para NO: ” ) ; respuesta = teclado . nextInt ( ) ; while ( r e s p u e s t a == 1 ) { s a l d o = s a l d o + s a l d o ∗ TASA; System . out . p r i n t l n ( ”\ t \ tDespu´e s d e l a˜ n o ” + a˜ n o + ” con ” + (TASA∗ 1 0 0 ) + ” % de i n t e r ´e s , ” + ” e l saldo es $” + saldo ) ; a˜ n o = a˜ no + 1 ; System . out . p r i n t l n ( ”¿ Q u i e r e s v e r e l s a l d o a l f i n a l de o t r o a˜ no ? ” ) ; System . out . p r i n t ( ” I n g r e s a 1 para SI ” ) ; System . out . p r i n t ( ” o c u a l q u i e r o t r o n´ u mero para NO: ” ) ; respuesta = teclado . nextInt ( ) ; } } }

C´odigo 1: Aplicaci´on SaldoBancario. La aplicaci´on del c´odigo 1 declara las variables necesarias y una constante para una tasa de inter´es del 0.03, y luego pide al usuario el saldo. Enseguida la aplicaci´on pide al usuario que ingresa un uno si el usuario quiere ver saldo del siguiente a˜ no. Mientras el usuario quiera seguir continuando, la aplicaci´on seguir´a mostrando los saldos bancarios incrementados. El ciclo en la aplicaci´on del c´odigo 1 inicia con la l´ınea que contiene: 6

while (respuesta == 1) Si el usuario ingresa cualquier entero diferente de uno, el cuerpo del ciclo nunca se ejecuta y el programa termina. Si el usuario ingresa uno, todas las sentencias dentro del cuerpo del ciclo se ejecutan. La aplicaci´on incrementa el saldo por la tasa de inter´es, muestra el nuevo saldo, agrega uno al a~ no, y pregunta si el usuario quiere otro saldo. La u ´ltima sentencia en el cuerpo del ciclo acepta la respuesta del usuario. Despu´es de la ejecuci´on del cuerpo del ciclo, el control regresa a la cima del ciclo, donde la expresi´on boolean en el ciclo while es probada nuevamente. Si el usuario ingresa uno, se entra al ciclo y el proceso inicia nuevamente.

2.5.

Validaci´ on de datos

Se emplean ciclos no definidos cuando se validan datos de entrada. La validaci´ on de datos es el proceso para asegurar que un valor est´a dentro del rango deseado. Por ejemplo, suponer que se requiere que el usuario meta un valor que no sea mayor que tres. La aplicaci´on MeteValorChico, del c´odigo 2, contin´ ua hasta que el usuario ingresa un valor correcto. Si el usuario ingresa tres o menos en la primera petici´on, nunca se entra al ciclo. Pero, si el usuario ingresa un n´ umero mayor a tres, se ejecuta el ciclo, dando otra oportunidad al usuario de ingresar el valor correcto. Mientras el usuario d´e datos incorrectos, el ciclo se repetir´a. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

import j a v a . u t i l . Scanner ; public c l a s s MeteValorChico { public s t a t i c void main ( S t r i n g [ ] a r g s ) { int e n t r a d a U s u a r i o ; f i n a l int LIMITE = 3 ; Scanner t e c l a d o = new Scanner ( System . i n ) ; System . out . p r i n t ( ” I n g r e s a r un e n t e r o que no s e a mayor a ” + LIMITE + ” > ” ) ; entradaUsuario = teclado . nextInt ( ) ; while ( e n t r a d a U s u a r i o > LIMITE ) { System . out . p r i n t l n ( ” El n´ u mero i n g r e s a d o e s i n c o r r e c t o . ” ) ; System . out . p r i n t ( ” I n g r e s a r un e n t e r o no mayor a ” + LIMITE + ” > ” ) ; entradaUsuario = teclado . nextInt ( ) ; } System . out . p r i n t l n ( ” Se i n g r e s ´o c o r r e c t a m e n t e ” + e n t r a d a U s u a r i o ) ; } }

C´odigo 2: La aplicaci´on MeteValorChico. Los programadores novatos cometen el error de revisar datos inv´alidos usando una decisi´on en vez de un ciclo. Revisan si el dato es inv´alido usando una sentencia if; si el dato es inv´alido, lo vuelven a pedir al usuario. Sin embargo, no consideran que el usuario podr´ıa meter datos incorrectos m´as de una vez. 7

3.

Operadores aritm´ eticos abreviados

Incrementar una variable en un ciclo para llevar la cantidad de ocurrencias de alg´ un evento es conocido como contar. El proceso de incrementar repetidamente un valor por alguna cantidad es conocida como acumular. Java proporciona varios atajos para incrementar y acumular. La sentencia contar += 1; es id´entica a contar = contar + 1;. El operador sumar y asignar es +=. La sentencia saldo += saldo * TASA; incrementa el saldo por un porcentaje de la TASA. Otros atajos que se pueden usar son el operador de sustraer y asignar (-=), operador de multiplicar y asignar (*=), operador de dividir y asignar (/=), operador de residuo y asignar ( %=). Cada uno de estos operadores es usado para hacer la operaci´on y asignaci´on del resultado en una sola instrucci´on. Para incrementar el valor de una variable en uno, se pueden usar otros dos operadores de atajo—el prefijo ++ tambi´en conocido como operador de incremento prefijo, y el postfijo ++, u operador de incremento postfijo. Para usar un prefijo ++, se ponen dos signos de suma antes del nombre de la variable. La sentencia algunValor = 6; seguida por ++algunValor; resulta en algunValor teniendo siete. Para usar un postfijo ++, se ponen dos signos m´as justo despu´es del nombre de la variable. Enseguida se muestran cuatro formas para incrementar valor en uno; cada uno da el mismo resultado. No es obligatorio emplear atajos, pero son una ventaja para escribir menos c´odigo y tener menos errores. int valor; valor = 123; ++valor; // valor tiene 124 valor = 123; valor++; // valor tiene 124 valor = 123; valor = valor + 1; // valor tiene 124 valor = 123; valor += 1; // valor tiene 124 El prefijo ++ y el postfijo ++ se usan con variables pero no con constantes. Es ilegal una expresi´on como ++84;. Nota. Los operadores de incremento prefijo y postfijo son operadores unarios, s´olo se usan con una variable. Otros operadores unarios son los operadores de conversi´on, o los operadores para indicar valor positivo (+) y negativo (-).

Cuando s´olo se quiere incrementar el valor de la variable en uno, no hay diferencia si se usa el operador incremento prefijo o postfijo. Sin embargo, cuando un operador prefijo o postfijo es usado como parte de una expresi´on, si hay diferencia en el resultado obtenido. Cuando un 8

operador prefijo es usado en una expresi´on, primero se incrementa la variable y despu´es se eval´ ua la expresi´on, y cuando un operador postfijo es usado primero se eval´ ua la expresi´on y luego se incrementa la variable. Considerar las siguientes sentencias: b = 4; c = ++b; El resultado es que ambos b y c tienen el valor de cinco porque b es incrementado a cinco y luego el valor de la expresi´on es asignado a c. Cuando se usa el postfijo ++, el valor de la expresi´on antes del incremento es guardado. Considerar la siguientes sentencias: b = 4; c = b++; b tiene el valor de cinco, pero c es s´olo cuatro. La aplicaci´on DemoIncremento, c´odigo 3, ilustra la diferencia de la forma como trabajan los operadores prefijo y postfijo. Cuando el operador incremento prefijo es usado en miNumero, este pasa de 123 a 124, y el resultado se asigna a respuesta, as´ı que tendr´a 124. Luego de que el es puesto 123 en miNumero, el operador incremento postfijo es usado; 123 es asignado a respuesta, y miNumero es incrementado a 124.

9

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

import j a v a . u t i l . Scanner ; public c l a s s DemoIncremento { public s t a t i c void main ( S t r i n g [ ] a r g s ) { int miNumero , r e s p u e s t a ; miNumero = 1 2 3 ; System . out . p r i n t l n ( ” Antes de i n c r e m e n t a r , miNumero e s ” + miNumero ) ; r e s p u e s t a = ++miNumero ; System . out . p r i n t l n ( ” Luego d e l i n c r e m e n t o p r e f i j o , miNumero e s ” + miNumero ) ; System . out . p r i n t l n ( ” y r e s p u e s t a e s ” + r e s p u e s t a ) ; miNumero = 1 2 3 ; System . out . p r i n t l n ( ” Antes de i n c r e m e n t a r , miNumero e s ” + miNumero ) ; r e s p u e s t a = miNumero++; System . out . p r i n t l n ( ” Luego d e l i n c r e m e n t o p o s t f i j o , miNumero e s ” + miNumero ) ; System . out . p r i n t l n ( ” y r e s p u e s t a e s ” + r e s p u e s t a ) ; } }

C´odigo 3: Aplicaci´on DemoIncremento. El escoger si se usa operador prefijo o postfijo es importante cuando es parte de una expresi´on m´as grande. Por ejemplo, si d es 5, entonces 2 * ++d es 12, pero 2 * d++ es 10. Una l´ogica similar se aplica cuando se usan los operadores decremento prefijo y postfijo. Por ejemplo, si b = 4 y c = b--, 4 es asignado a c, pero b es decrementado y tiene el valor 3. Si b = 4 y c = --b, b es decrementado a 3 y 3 es asignado a c.

4.

Creaci´ on de ciclos for

Un ciclo for es un ciclo especial que es usado cuando una cantidad definida de iteraciones del ciclo es requerida, ya que tiene una forma adecuada para crear un ciclo controlado por un contador. Un ciclo while puede ser usado para lo anterior, sin embargo el ciclo for da una notaci´on breve para el ciclo definido. Al usar un ciclo for, se puede indicar el valor inicial para la variable de control del ciclo, la condici´on de prueba que controla la entrada al ciclo, y la expresi´on que altera la variable de control del ciclo. El ciclo for inicia con la palabra reservada for seguido por un juego de par´entesis. Se puede usar una sola sentencia o un bloque de sentencias como el cuerpo de un ciclo for. Muchos programadores recomienden que siempre se use un juego de llaves para envolver el cuerpo de un ciclo for por claridad. Suponiendo que una variable llamada val ha sido declarada como un entero, entonces la sentencia for mostrada a continuaci´on da la misma salida que la sentencia while que 10

est´a enseguida—ambas muestran los enteros del 1 al 10. for (val = 1; val < 11; ++val) { System.out.println(val); } val = 1; while (val < 11) { System.out.println(val); } Dentro de los par´entesis de la sentencia for, del segmento de c´odigo anterior, la secci´on primera antes del primer punto y coma inicializa val a uno. El programa ejecuta esta sentencia una sola vez, sin importar cuantas veces el cuerpo del ciclo for se ejecuta. Despu´es de la inicializaci´on, el control del programa pasa al centro, o secci´on de prueba, de la sentencia for que est´a entre los dos punto y coma. Si la expresi´on booleana se eval´ ua a true, se entra al cuerpo del ciclo for. Como val es puesta a uno, la expresi´on val < 11 es true. El cuerpo del ciclo muestra val. Como el cuerpo del ciclo es una sola sentencia no se requieren las llaves. Despu´es que se ejecuta el cuerpo del ciclo, la secci´on tercera final del ciclo for que sigue al segundo punto y coma se ejecuta, y val es incrementado a dos. El control del programa pasa de la secci´on tercera a la secci´on segunda, donde val es comparada contra once una segunda vez. Como val es todav´ıa menor que once, se ejecuta el cuerpo: val (ahora teniendo dos) es mostrado, y luego la tercera, que modifica una porci´on del ciclo for se ejecuta otra vez. La variable val se incrementa a tres, y el ciclo for contin´ ua. Eventualmente, cuando val no es menor que once (despu´es de que se mostr´o del uno al diez), el ciclo for termina, y el programa contin´ ua con la sentencia que siga al ciclo. Las tres secciones del ciclo for son tambi´en conocidas como inicializaci´on, prueba, e incremento, tambi´en se pueden realizar las siguientes tareas: Inicializar m´as de una variable en la primera secci´on de la sentencia for usando comas entre estas, como sigue: for (g = 0, h = 1; g < 6; ++g) Realizar m´as de una prueba usando los operadores Y o´ O en la segunda secci´on, por ejemplo: for (g = 0; g < 3 && h > 1; ++g) Decrementar o realizar alguna otra tarea en la tercera secci´on, por ejemplo: 11

for (g = 5; g >= 3; --g) Alterar m´as de una variable en la tercera secci´on separ´andolas con comas, como sigue: for (g = 0; g < 10; ++g, ++h, sum += g) Se pueden dejar una o m´as secciones de un ciclo for vac´ıas, sin embargo se requiere seguir poniendo punto y coma. Suponiendo que x ha sido inicializada previamente, se podr´ıa escribir: for (; x < 10; ++x) Dejar una secci´on, o varias, de una sentencia for vac´ıa hace la lectura del c´odigo dif´ıcil. Se sugiere usar la misma variable de control del ciclo en las tres partes de la sentencia for. Tambi´en deber´ıa evitarse alterar la variable de control del ciclo en el cuerpo del ciclo, al hacer la modificaci´on en el cuerpo es m´as dif´ıcil seguir la l´ogica del programa, adem´as puede generar errores complejos de quitar. Se podr´ıa encontrar un ciclo for que no contenga cuerpo, como en el siguiente: for (x = 0; x < 100000; ++x); Este ciclo se usa para consumir tiempo de tal forma que se d´e una breve pausa durante la ejecuci´on del programa. Java tiene un m´etodo nativo, sleep, para pausar la ejecuci´on del programa. Este m´etodo es parte de la clase Thread del paquete java.lang. Tambi´en se puede declarar una variable dentro de una sentencia for, como en la siguiente: for (int val = 1; val < 11; ++val)

5.

Creaci´ on de ciclos do...while

En los ejemplos revisados previamente, la variable de control del ciclo es evaluado en la “cima” del ciclo antes de que el cuerpo tenga oportunidad de ejecutarse. Ambos ciclos while y for son ciclos preprobados—aquellos en los cuales las variables de control del ciclo son probadas antes de que el cuerpo del ciclo se ejecute. En ocasiones se podr´ıa necesitar asegurar que el cuerpo de un ciclo se ejecute al menos una vez. As´ı se quiere escribir un ciclo que revise en la “fondo” del ciclo despu´es de la primera iteraci´on. Tal ciclo es el ciclo do...while; este es un ciclo postprobado—uno en el cual la variable de control del ciclo es probado despu´es de que se ejecuta el cuerpo del ciclo. 12

La figura 5 muestra la estructura general de un ciclo do...while. Observar que el cuerpo del ciclo se ejecuta al menos una vez y antes de que se haga la pregunta de control del ciclo. La aplicaci´on SaldoBancario2, c´odigo 4, tiene un ciclo do...while. El ciclo inicia en la l´ınea 11. El cuerpo del ciclo est´a enseguida encerrado entre llaves. El saldo del primer a˜ no es mostrado antes de que el usuario tenga oportunidad de responder. En el fondo del ciclo, se le pregunta al usuario si quiere ver el saldo al final de otro a˜ no, as´ı el usuario tiene la opci´on de ver m´as saldos, pero ver el primer mensaje no se puede.

Figura 2: Diagrama de flujo de un ciclo do...while.

13

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

import j a v a . u t i l . Scanner ; public c l a s s S a l d o B a n c a r i o 2 { public s t a t i c void main ( S t r i n g [ ] a r g s ) { double s a l d o ; int r e s p u e s t a ; int a˜ no = 1 ; f i n a l double TASA = 0 . 0 3 ; Scanner t e c l a d o = new Scanner ( System . i n ) ; System . out . p r i n t ( ” I n g r e s a r e l s a l d o b a n c a r i o i n i c i a l : ” ) ; s a l d o = t e c l a d o . nextDouble ( ) ; do { s a l d o = s a l d o + s a l d o ∗ TASA; System . out . p r i n t l n ( ”\ t \ tDespu´e s d e l a˜ n o ” + a˜ n o + ” con ” + (TASA∗ 1 0 0 ) + ” % de i n t e r ´e s , ” + ” e l saldo es $” + saldo ) ; a˜ n o = a˜ no + 1 ; System . out . p r i n t l n ( ”¿ Q u i e r e s v e r e l s a l d o a l f i n a l de o t r o a˜ no ? ” ) ; System . out . p r i n t ( ” I n g r e s a 1 para SI ” ) ; System . out . p r i n t ( ” o c u a l q u i e r o t r o n´ u mero para NO: ” ) ; respuesta = teclado . nextInt ( ) ; } while ( r e s p u e s t a == 1 ) ; } }

C´odigo 4: La aplicaci´on SaldoBancario2 usando el ciclo do...while. Cuando el cuerpo de un ciclo do...while contiene una sola sentencia, no se requiere usar llaves. El siguiente ciclo agrega valor a total mientras total permanezca menor que 200: do total += valor; while (total < 200); A pesar de que las llaves no son requeridas en este caso, varios programadores recomiendan usarlas, de esta forma se previene que en la tercera l´ınea del c´odigo parezca que inicia un nuevo ciclo while en vez de la finalizaci´on del ciclo do...while previo. El siguiente ejemplo incluye las llaves y es menos probable de confundir al lector: do { total += valor; } while (total < 200); No es obligatorio usar el ciclo do...while. Pero cuando se sabe que se quiere hacer alguna tarea al menos una vez, el ciclo do...while es m´as conveniente.

14

6.

Ciclos anidados

Al igual que la sentencia if que se puede anidar, tambi´en se puede con los ciclos. Cualquier tipo de ciclo se puede poner dentro de cualquier otro tipo de ciclo. Cuando los ciclos est´an anidados, cada par contiene un ciclo interno y un ciclo externo. El ciclo interno deber´a estar enteramente contenido dentro del ciclo externo; los ciclos no se pueden traslapar. Se puede anidar virtualmente cualquier cantidad de ciclos; sin embargo, en alg´ un punto, el sistema no podr´a guardar toda la informaci´on necesaria del ciclo. Suponer que se quieren mostrar los saldos bancarios futuros mientras se var´ıan los a˜ nos y las tasas de inter´es. La aplicaci´on SaldoInteresAnual, c´odig´o 5, tiene un ciclo externo que varia las tasas de inter´es dentro de un rango. Al inicio del ciclo externo, el saldo es reiniciado a su valor inicial para que los c´alculos sean correctos para cada valor de inter´es revisado. El ciclo interno var´ıa la cantidad de a˜ nos y muestra cada saldo calculado. 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

import j a v a . u t i l . Scanner ; public c l a s s S a l d o I n t e r e s A n u a l { public s t a t i c void main ( S t r i n g [ ] a r g s ) { double s a l d o I n i c i a l ; double s a l d o ; int a˜ no = 1 ; double i n t e r e s ; int r e s p u e s t a ; f i n a l double BAJO = 0 . 0 2 ; f i n a l double ALTO = 0 . 0 5 ; f i n a l double INCREMENTO = 0 . 0 1 ; ˜ f i n a l int MAX ANOS = 4; Scanner e n t r a d a = new Scanner ( System . i n ) ; System . out . p r i n t ( ” I n g r e s a r e l s a l d o b a n c a r i o i n i c i a l : ” ) ; s a l d o I n i c i a l = e n t r a d a . nextDouble ( ) ; for ( i n t e r e s = BAJO; i n t e r e s