Escolar Documentos
Profissional Documentos
Cultura Documentos
requiere un ciclo en el que se introduzca de manera sucesiva el resultado de cada examen. Sabemos de an-
temano que hay precisamente 10 resultados del examen, por lo que es apropiado utilizar un ciclo contro-
lado por contador. Dentro del ciclo (es decir, anidado dentro del ciclo), una estructura de selección doble
determinará si cada resultado del examen es aprobado o reprobado, e incrementará el contador apropiado.
Entonces, el refinamiento del seudocódigo anterior es
Nosotros utilizamos líneas en blanco para aislar la estructura de control Si...De lo contrario, lo cual mejora
la legibilidad.
La instrucción en seudocódigo
Imprimir un resumen de los resultados de los exámenes y decidir si debe pagarse un bono
Fig. 4.11 冷 El seudocódigo para el problema de los resultados del examen (parte 1 de 2).
15
16 Imprimir el número de aprobados
17 Imprimir el número de reprobados
18
19 Si más de ocho estudiantes aprobaron
20 Imprimir “Bono para el instructor!”
Fig. 4.11 冷 El seudocódigo para el problema de los resultados del examen (parte 2 de 2).
La clase de Java que implementa el algoritmo en seudocódigo se muestra en la figura 4.12, junto con
dos ejecuciones de ejemplo. Las líneas 13, 14, 15 y 22 de la clase main declaran las variables que se utilizan
para procesar los resultados del examen.
Fig. 4.12 冷 Análisis de los resultados de un examen, utilizando instrucciones de control anidadas (parte 1 de 2).
Fig. 4.12 冷 Análisis de los resultados de un examen, utilizando instrucciones de control anidadas (parte 2 de 2).
La instrucción while (líneas 18 a 32) itera 10 veces. Durante cada iteración, el ciclo recibe y proce-
sa un resultado del examen. Observe que la instrucción if...else (líneas 25 a 28) se anida en la ins-
trucción while para procesar cada resultado. Si el resultado es 1, la instrucción if...else incrementa
a aprobados; en caso contrario, asume que el resultado es 2 e incrementa reprobados. La línea 31 in-
crementa contadorEstudiantes antes de que se evalúe otra vez la condición del ciclo, en la línea 18.
Después de introducir 10 valores, el ciclo termina y la línea 35 muestra el número de aprobados y de
reprobados. La instrucción if de las líneas 38 y 39 determina si más de ocho estudiantes aprobaron el
examen y, de ser así, imprime el mensaje “Bono para el instructor!”.
La figura 4.12 muestra la entrada y salida de dos ejecuciones de ejemplo del programa. Durante la primera
ejecución de ejemplo, la condición en la línea 38 del método main es true; más de ocho estudiantes aprobaron
el examen, por lo que el programa imprime un mensaje indicando que se debe dar un bono al instructor.
en donde operadorr es uno de los operadores binarios +, -, *, / o % (o alguno de los otros que veremos más
adelante en el libro), puede escribirse de la siguiente forma:
c = c + 3;
c += 3;
El operador += suma el valor de la expresión que está a la derecha del operador al valor de la variable ubica-
da a la izquierda del mismo y almacena el resultado en la variable que se encuentra a la izquierda del ope-
rador. Por lo tanto, la expresión de asignación c += 3 suma 3 a c. La figura 4.13 muestra los operadores de
asignación aritméticos compuestos, algunas expresiones de ejemplo en las que se utilizan los operadores y
las explicaciones de lo que estos operadores hacen.
aprobados = aprobados + 1;
reprobados = reprobados + 1;
contadorEstudiantes = contadorEstudiantes + 1;
pueden escribirse en forma más concisa con operadores de asignación compuestos, de la siguiente manera:
aprobados += 1;
reprobados += 1;
contadorEstudiantes += 1;
++aprobados;
++reprobados;
++contadorEstudiantes;
aprobados++;
reprobados++;
contadorEstudiantes++;
Al incrementar o decrementar una variable que se encuentre en una instrucción por sí sola, las formas
preincremento y postincremento tienen el mismo efecto, al igual que las formas predecremento y postde-
cremento. Solamente cuando una variable aparece en el contexto de una expresión más grande es cuando
los operadores preincremento y postincremento tienen distintos efectos (y lo mismo se aplica a los opera-
dores de predecremento y postdecremento).
En C y C++, los programadores con frecuencia tienen que escribir versiones independientes de los
programas para soportar varias plataformas distintas, ya que no se garantiza que los tipos primitivos sean
idénticos de computadora en computadora. Por ejemplo, un valor int en un equipo podría representarse
mediante 16 bits (2 bytes) de memoria, en un segundo equipo mediante 32 bits (4 bytes) de memoria, y
en otro mediante 64 bits (8 bytes) de memoria. En Java, los valores int siempre son de 32 bits (4 bytes).
Cada uno de los tipos del apéndice D se enumera con su tamaño en bits (hay ocho bits en un byte), así
como con su rango de valores. Como los diseñadores de Java desean asegurar la portabilidad, utilizan es-
tándares reconocidos a nivel internacional, tanto para los formatos de caracteres (Unicode; para más infor-
mación, visite www.unicode.org) como para los números de punto flotante (IEEE 754; para más informa-
ción, visite grouper.ieee.org/groups/754/).
En la sección 3.2 vimos que a las variables de tipos primitivos que se declaran fuera de un método como
variables de instancia de una clase se les asignan valores predeterminados de manera automática, a menos que
se inicialicen en forma explícita. Las variables de instancia de los tipos char, byte, short, int, long, float
y double reciben el valor 0 de manera predeterminada. Las variables de tipo boolean reciben el valor
false de manera predeterminada. Las variables de instancia de tipo por referencia se inicializan de manera
predeterminada con el valor null.
[
(0, 0) eje x
\ [ \
eje y
Fig. 4.19 冷 Creación de un objeto JFrame para mostrar un objeto PanelDibujo (parte 1 de 2).
Fig. 4.19 冷 Creación de un objeto JFrame para mostrar un objeto PanelDibujo (parte 2 de 2).
La línea 6 utiliza la palabra clave extends para indicar que la clase PanelDibujo es un tipo mejorado
de JPanel. La palabra clave extends representa algo que se denomina relación de herencia, en la cual
nuestra nueva clase PanelDibujo empieza con los miembros existentes (datos y métodos) de la clase JPanel.
La clase de la cual PanelDibujo hereda, JPanel, aparece a la derecha de la palabra clave extends. En
esta relación de herencia, a JPanel se le conoce como la superclase y PanelDibujo es la subclase. Esto
produce una clase PanelDibujo que tiene los atributos (datos) y comportamientos (métodos) de la clase
JPanel, así como las nuevas características que agregaremos en nuestra declaración de la clase PanelDi-
bujo. En particular, tiene la habilidad de dibujar dos líneas a lo largo de las diagonales del panel. En el
capítulo 9 explicaremos con detalle el concepto de herencia. Por ahora, sólo tiene que imitar nuestra
clase PanelDibujo cuando cree sus propios programas de gráficos.
El método paintComponent
Todo JPanel, incluyendo nuestro PanelDibujo, tiene un método paintComponent (líneas 9 a 22), que el
sistema llama de manera automática cada vez que necesita mostrar el objeto PanelDibujo. El método
paintComponent debe declararse como se muestra en la línea 9; de no ser así, el sistema no llamará al mé-
todo. Este método es llamado cuando se muestra un objeto JPanel por primera vez en la pantalla, cuando
una ventana en la pantalla lo cubree y después lo descubre, y cuando la ventana en la que aparece cambia su
tamaño. El método paintComponent requiere un argumento, un objeto Graphics, que el sistema propor-
ciona por usted cuando llama a paintComponent. Este objeto Graphics se usa para dibujar líneas, rectán-
gulos, óvalos y otros gráficos.
La primera instrucción en cualquier método paintComponent que cree debe ser siempre:
super.paintComponent(g);
la cual asegura que el panel se despliegue de manera apropiada en la pantalla, antes de empezar a dibujar en él.
A continuación, las líneas 14 y 15 llaman a los métodos que la clase PanelDibujo hereda de la clase JPanel.
Como PanelDibujo extiende a JPanel, éste puede usar cualquier método public de JPanel. Los métodos
getWidth y getHeight devuelven la anchura y la altura del objeto JPanel, respectivamente. Las líneas 14 y 15
almacenan estos valores en las variables locales anchura y altura. Por último, las líneas 18 y 21 utilizan la
variable g de la clase Graphics para llamar al método drawLine, para que dibuje las dos líneas. El método
drawLine dibuja una línea entre dos puntos representados por sus cuatro argumentos. Los primeros dos son
las coordenadas x y y para uno de los puntos finales de la línea, y los últimos dos son las coordenadas para el
otro punto final. Si cambia de tamañoo la ventana, las líneas se escalarán en concordancia, ya que los argumen-
tos se basan en la anchura y la altura del panel. Al cambiar el tamaño de la ventana en esta aplicación, el siste-
ma llama a paintComponent para volver a dibujarr el contenido de PanelDibujo.
La clase PruebaPanelDibujo
Para mostrar el PanelDibujo en la pantalla, debemos colocarlo en una ventana. Usted debe crear una
ventana con un objeto de la clase JFrame. En PruebaPanelDibujo.java (figura 4.19), la línea 3 impor-
ta la clase JFrame del paquete javax.swing. La línea 10 en main crea un objeto PanelDibujo, el cual
contiene nuestro dibujo, y la línea 13 crea un nuevo objeto JFrame que puede contener y mostrar nues-
tro panel. La línea 16 llama al método setDefaultCloseOperation del método JFrame con el argumen-
to JFrame.EXIT_ON_CLOSE, para indicar que la aplicación debe terminar cuando el usuario cierre la
ventana. La línea 18 utiliza el método add de JFrame para adjuntarr el objeto PanelDibujo al objeto
JFrame. La línea 19 establece el tamaño del objeto JFrame. El método setSize recibe dos parámetros
que representan la anchura y altura del objeto JFrame, respectivamente. Por último, la línea 20 muestra
el objeto JFrame mediante una llamada a su método setVisible con el argumento true. Cuando se
muestra el objeto JFrame, se hace una llamada implícita al método paintComponent de PanelDibujo
(líneas 9 a 22 de la figura 4.18) y se dibujan las dos líneas (vea los resultados de ejemplo en la figura 4.19).
Pruebe a cambiar el tamaño de la ventana, y podrá ver que las líneas siempre se dibujan con base en la
anchura y altura actuales de la ventana.
b) Modifique su respuesta en la parte (a) para hacer que las líneas se desplieguen a partir de las cuatro es-
quinas, como se muestra en la captura de pantalla derecha de la figura 4.20. Las líneas de esquinas
opuestas deberán intersecarse a lo largo de la parte media.
4.2. La figura 4.21 muestra dos diseños adicionales, creados mediante el uso de ciclos while y de
drawLine.
a) Cree el diseño de la captura de pantalla izquierda de la figura 4.21. Empiece por dividir cada borde en
un número equivalente de incrementos (elegimos 15 de nuevo). La primera línea empieza en la esquina
superior izquierda y termina un paso a la derecha, en el borde inferior. Para cada línea sucesiva, avance
hacia abajo un incremento en el borde izquierdo, y un incremento a la derecha en el borde inferior.
Continúe dibujando líneas hasta llegar a la esquina inferior derecha. La figura deberá escalarse a medi-
da que usted cambie el tamaño de la ventana, de manera que los puntos finales siempre toquen los
bordes.
b) Modifique su respuesta en la parte (a) para reflejar el diseño en las cuatro esquinas, como se muestra en
la captura de pantalla derecha de la figura 4.21.
4.16 Conclusión
Este capítulo presentó las estrategias básicas de solución de problemas para crear clases y desarrollar méto-
dos para ellas. Demostramos cómo construir un algoritmo (es decir, una metodología para resolver un
problema), y después cómo refinarlo a través de diversas fases de desarrollo de seudocódigo, lo cual produ-
ce código en Java que puede ejecutarse como parte de un método. El capítulo demostró cómo utilizar el
método de refinamiento de arriba a abajo, paso a paso, para planear las acciones específicas que debe reali-
zar un método y el orden en el que debe hacerlo.
Sólo se requieren tres tipos de estructuras de control (secuencia, selección y repetición) para desarrollar
cualquier algoritmo para solucionar un problema. En específico, este capítulo demostró el uso de la ins-
trucción if de selección simple, la instrucción if...else de selección doble y la instrucción de repetición
while. Estas instrucciones son algunos de los cimientos que se utilizan para construir soluciones para
muchos problemas. Utilizamos el apilamiento de instrucciones de control para calcular el total y el prome-
dio de un conjunto de calificaciones de estudiantes, mediante la repetición controlada por un contador y
controlada por un centinela. También utilizamos el anidamiento de instrucciones de control para analizar
y tomar decisiones con base en un conjunto de resultados de un examen. Presentamos los operadores de
asignación compuestos de Java, así como sus operadores de incremento y decremento. Por último, anali-
zamos los tipos primitivos de Java. En el capítulo 5 continuaremos nuestra explicación de las instrucciones
de control, en donde presentaremos las instrucciones for, do...while y switch.
Resumen
• El círculo sólido rodeado por una circunferencia, que aparece en la parte inferior del diagrama, representa el estado
final (pág. 104); es decir, el término del flujo de trabajo después de que el programa realiza sus acciones.
• Los rectángulos con las esquinas superiores derechas dobladas se llaman notas en UML (pág. 104), y son comen-
tarios aclaratorios que describen el propósito de los símbolos en el diagrama.
• Java tiene tres tipos de instrucciones de selección (pág. 105).
• La instrucción if de selección simple (pág. 105) selecciona o ignora una o más acciones.
• La instrucción if...else de selección doble selecciona una de dos acciones distintas, o grupos de acciones.
• La instrucción switch se llama instrucción de selección múltiple (pág. 105), ya que selecciona una de varias accio-
nes distintas, o grupos de acciones.
• Java cuenta con las instrucciones de repetición (también conocidas como de iteración o ciclos) while, do...while
y for, las cuales permiten a los programas ejecutar instrucciones en forma repetida, siempre y cuando una condi-
ción de continuación de ciclo siga siendo verdadera.
• Las instrucciones while y for realizan las acciones en sus cuerpos, cero o más veces. Si al principio la condición de
continuación de ciclo (pág. 105) es falsa, las acciones no se ejecutarán. La instrucción do...while lleva a cabo las
acciones que contiene en su cuerpo, una o más veces.
• Las palabras if, else, switch, while, do y for son palabras claves en Java. Las palabras clave no pueden utilizarse
como identificadores, como los nombres de variables.
• Cada programa se forma mediante una combinación de todas las instrucciones de secuencia, selección y repetición
(pág. 105) que sean apropiadas para el algoritmo que implementa ese programa.
• Las instrucciones de control de una sola entrada/una sola salida (pág. 105) se unen unas a otras mediante la cone-
xión del punto de salida de una al punto de entrada de la siguiente. A esto se le conoce como apilamiento de ins-
trucciones de control.
• Una instrucción de control también se puede anidar (pág. 105) dentro de otra instrucción de control.
• Así como podemos colocar un bloque en cualquier parte en la que pueda colocarse una sola instrucción, también
podemos usar una instrucción vacía, que se representa colocando un punto y coma (;) en donde normalmente
estaría una instrucción.
Ejercicios de autoevaluación
4.1 Complete los siguientes enunciados:
a) Todos los programas pueden escribirse en términos de tres tipos de estructuras de control: ,
y .
b) La instrucción se utiliza para ejecutar una acción cuando una condición es verdadera, y otra
cuando esa es falsa.
c) Al proceso de repetir un conjunto de instrucciones un número específico de veces se le llama repetición
.
d) Cuando no se sabe de antemano cuántas veces se repetirá un conjunto de instrucciones, se puede usar un
valor para terminar la repetición.
e) La estructura de está integrada en Java; de manera predeterminada, las instrucciones se ejecutan
en el orden en el que aparecen.
f ) Todas las variables de instancia de los tipos char, byte, short, int, long, float y double reciben el valor
de manera predeterminada.
g) Java es un lenguaje ; requiere que todas las variables tengan un tipo.
h) Si el operador de incremento se de una variable, ésta se incrementa en 1 primero, y después su
nuevo valor se utiliza en la expresión.
4.2 Conteste con verdadero o falso a cada una de las siguientes proposiciones; en caso de ser falso, explique
por qué.
a) Un algoritmo es un procedimiento para resolver un problema en términos de las acciones a ejecutar y el
orden en el que lo hacen.
b) Un conjunto de instrucciones contenidas dentro de un par de paréntesis se denomina bloque.
c) Una instrucción de selección especifica que una acción se repetirá, mientras cierta condición siga siendo
verdadera.
d) Una instrucción de control anidada aparece en el cuerpo de otra instrucción de control.
e) Java cuenta con los operadores de asignación compuestos aritméticos +=, -=, *=, /= y %= para abreviar las
expresiones de asignación.
f ) Los tipos primitivos (boolean, char, byte, short, int, long, float y double) son portables sólo en las
plataformas Windows.
g) Al proceso de especificar el orden en el que se ejecutan las instrucciones en un programa se denomina
control del programa.
h) El operador de conversión de tipo unario (double) crea una copia entera temporal de su operando.
i) Las variables de instancia de tipo boolean reciben el valor true de manera predeterminada.
j) El seudocódigo ayuda a un programador a idear un programa, antes de tratar de escribirlo en un lenguaje
de programación.
4.3 Escriba cuatro instrucciones distintas en Java, en donde cada una sume 1 a la variable entera x.
4.4 Escriba instrucciones en Java para realizar cada una de las siguientes tareas:
a) Usar una instrucción para asignar la suma de x y y a z, e incrementar x en 1 después del cálculo.
b) Evaluar si la variable cuenta es mayor que 10. De ser así, imprimir “Cuenta es mayor que 10”.
c) Usar una instrucción para decrementar la variable x en 1, luego restarla a la variable total y almacenar el
resultado en la variable total.
d) Calcular el residuo después de dividir q entre divisor, y asignar el resultado a q. Escriba esta instrucción
de dos maneras distintas.
4.5 Escriba una instrucción en Java para realizar cada una de las siguientes tareas:
a) Declarar la variable suma de tipo int e inicializarla con 0.
b) Declarar la variable x de tipo int e inicializarla con 1.
c) Sumar la variable x a suma y asignar el resultado a la variable suma.
d) Imprimir “La suma es: ”, seguido del valor de la variable suma.
4.6 Combine las instrucciones que escribió en el ejercicio 4.5 para formar una aplicación en Java que calcule
e imprima la suma de los enteros del 1 al 10. Use una instrucción while para iterar a través de las instrucciones de
cálculo e incremento. El ciclo debe terminar cuando el valor de x se vuelva 11.
4.7 Determine el valor de las variables en la instrucción producto *= x++;, después de realizar el cálculo. Supon-
ga que todas las variables son de tipo int y tienen el valor 5.
4.8 Identifique y corrija los errores en cada uno de los siguientes conjuntos de código:
a) while (c <= 5)
{
producto *= c;
++c;
b) if (genero == 1)
System.out.println(“Mujer”);
else;
System.out.println(“Hombre”);
4.3 x = x + 1;
x += 1;
++x;
x++;
4.4 a) z = x++ + y;
b) if (cuenta > 10)
System.out.println(“Cuenta es mayor que 10”);
c) total -= --x;
d) q %= divisor;
q = q % divisor;
La suma es: 55
Ejercicios
4.10 Compare y contraste la instrucción if de selección simple y la instrucción de repetición while. ¿Cuál es la
similitud en las dos instrucciones? ¿Cuál es su diferencia?
4.11 Explique lo que ocurre cuando un programa en Java trata de dividir un entero entre otro. ¿Qué ocurre con la
parte fraccionaria del cálculo? ¿Cómo puede un programador evitar ese resultado?
4.12 Describa las dos formas en las que pueden combinarse las instrucciones de control.
4.13 ¿Qué tipo de repetición sería apropiada para calcular la suma de los primeros 100 enteros positivos? ¿Qué tipo
de repetición sería apropiada para calcular la suma de un número arbitrario de enteros positivos? Describa brevemen-
te cómo podría realizarse cada una de estas tareas.
4.14 ¿Cuál es la diferencia entre preincrementar y postincrementar una variable?
4.15 Identifique y corrija los errores en cada uno de los siguientes fragmentos de código. [Nota: puede haber más
de un error en cada fragmento de código].
a) if (edad >= 65);
System.out.println(“Edad es mayor o igual que 65”);
else
System.out.println(“Edad es menor que 65)”;
b) int x = 1, total;
while (x <= 10)
{
total += x;
++x;
}
c) while (x <= 100)
total += x;
++x;
d) while (y > 0)
{
System.out.println(y);
++y;
Para los ejercicios 4.17 a 4.20, realice cada uno de los siguientes pasos:
a) Lea el enunciado del problema.
b) Formule el algoritmo mediante un seudocódigo y el proceso de refinamiento de arriba a abajo, paso a paso.
c) Escriba un programa en Java.
4.19 (Calculadora de comisiones de ventas) Una empresa grande paga a sus vendedores mediante comisiones.
Los vendedores reciben $200 por semana, más el 9% de sus ventas brutas durante esa semana. Por ejemplo, un
vendedor que vende $5 000 de mercancía en una semana, recibe $200 más el 9% de 5 000, o un total de $650.
Usted acaba de recibir una lista de los artículos vendidos por cada vendedor. Los valores de estos artículos son los
siguientes:
Artículo Valor
1 239.99
2 129.75
3 99.95
4 350.89
Desarrolle una aplicación en Java que reciba como entrada los artículos vendidos por un comerciante durante la últi-
ma semana, y que calcule y muestre los ingresos de ese vendedor. No hay límite en cuanto al número de artículos que
un representante puede vender.
4.20 (Calculadora del salario) Desarrolle una aplicación en Java que determine el sueldo bruto para cada uno de
tres empleados. La empresa paga la cuota normal en las primeras 40 horas de trabajo de cada empleado, y cuota y
media en todas las horas trabajadas que excedan de 40. Usted recibe una lista de los empleados de la empresa, el nú-
mero de horas que trabajó cada uno la semana pasada y la tarifa por horas de cada empleado. Su programa debe recibir
como entrada esta información para cada empleado, para luego determinar y mostrar el sueldo bruto de cada trabaja-
dor. Utilice la clase Scanner para introducir los datos.
4.21 (Encontrar el número más grande) El proceso de encontrar el valor más grande se utiliza con frecuencia en
aplicaciones de computadora. Por ejemplo, un programa para determinar el ganador de un concurso de ventas recibe
como entrada el número de unidades vendidas por cada vendedor. El vendedor que haya vendido más unidades es el
que gana el concurso. Escriba un programa en seudocódigo y después una aplicación en Java que reciba como entrada
una serie de 10 números enteros, y que determine e imprima el mayor de los números. Su programa debe utilizar
cuando menos las siguientes tres variables:
a) contador: un contador para contar hasta 10 (para llevar el registro de cuántos números se han introduci-
do, y para determinar cuando se hayan procesado los 10 números).
b) numero: el entero más reciente introducido por el usuario.
c) mayor: el número más grande encontrado hasta ahora.
4.22 (Salida tabular) Escriba una aplicación en Java que utilice ciclos para imprimir la siguiente tabla de valores:
1 10 100 1000
2 20 200 2000
3 30 300 3000
4 40 400 4000
5 50 500 5000
4.23 (Encontrar los dos números más grandes) Utilizando una metodología similar a la del ejercicio 4.21, en-
cuentre los doss valores más grandes de los 10 que se introdujeron. [Nota: puede introducir cada número sólo una vez].
4.24 (Validar la entrada del usuario) Modifique el programa de la figura 4.12 para validar sus entradas. Para
cualquier entrada, si el valor introducido es distinto de 1 o 2, debe seguir iterando hasta que el usuario introduzca un
valor correcto.
4.25 ¿Qué es lo que imprime el siguiente programa?
4.27 (Problema del else suelto) Determine la salida de cada uno de los siguientes conjuntos de código, cuando x
es 9 y y es 11, y cuando x es 11 y y es 9. Observe que el compilador ignora la sangría en un programa en Java. Además,
el compilador de Java siempre asocia un else con el if que le precede inmediatamente, a menos que se le indique de
otra forma mediante la colocación de llaves ({ }). A primera vista, el programador tal vez no esté seguro de cuál if
corresponde a cuál else; esta situación se conoce como el “problema del else suelto”. Hemos eliminado la sangría del
siguiente código para hacer el problema más retador. [Sugerencia: Aplique las convenciones de sangría que ha apren-
dido].
a) if (x < 10)
if (y > 10)
System.out.println(“*****”);
else
System.out.println(“#####”);
System.out.println(“$$$$$”);
b) if (x < 10)
{
if (y > 10)
System.out.println(“*****”);
}
else
{
System.out.println(“#####”);
System.out.println(“$$$$$”);
}
4.28 (Otro problema de else suelto) Modifique el código dado para producir la salida que se muestra en cada
parte del problema. Utilice las técnicas de sangría apropiadas. No haga modificaciones en el código, sólo inserte llaves
o modifique la sangría del código. El compilador ignora la sangría en un programa en Java. Hemos eliminado la sangría
en el código dado, para hacer el problema más retador. [Nota: es posible que no se requieran modificaciones en algu-
nas de las partes].
if (y == 8)
if (x == 5)
System.out.println(“@@@@@”);
else
System.out.println(“#####”);
System.out.println(“$$$$$”);
System.out.println(“&&&&&”);
@@@@@
$$$$$
&&&&&
@@@@@
$$$$$
@@@@@
d) Suponiendo que x = 5 y y = 7, se produce la siguiente salida. [Nota: las tres últimas instrucciones de sa-
lida después del else forman parte de un bloque].
#####
$$$$$
&&&&&
4.29 (Cuadrado de asteriscos) Escriba una aplicación que pida al usuario que introduzca el tamaño del lado de
un cuadrado y que muestre un cuadrado hueco de ese tamaño, compuesto de asteriscos. Su programa debe funcionar
con cuadrados que tengan lados de todas las longitudes entre 1 y 20.
4.30 (Palíndromos) Un palíndromo es una secuencia de caracteres que se lee igual al derecho y al revés. Por ejem-
plo, cada uno de los siguientes enteros de cinco dígitos es un palíndromo: 12321, 55555, 45554 y 11611. Escriba una
aplicación que lea un entero de cinco dígitos y determine si es un palíndromo. Si el número no es de cinco dígitos, el
programa debe mostrar un mensaje de error y permitir al usuario que introduzca un nuevo valor.
4.31 (Imprimir el equivalente decimal de un número binario) Escriba una aplicación que reciba como entrada
un entero que contenga sólo dígitos 0 y 1 (es decir, un entero binario), y que imprima su equivalente decimal. [Suge-
rencia: use los operadores residuo y división para elegir los dígitos del número binario uno a la vez, de derecha a iz-
quierda. En el sistema numérico decimal, el dígito más a la derecha tiene un valor posicional de 1 y el siguiente dígito
a la izquierda tiene un valor posicional de 10, después 100, después 1 000, etcétera. El número decimal 234 puede
interpretarse como 4 * 1 + 3 * 10 + 2 * 100. En el sistema numérico binario, el dígito más a la derecha tiene un valor
posicional de 1, el siguiente dígito a la izquierda tiene un valor posicional de 2, luego 4, luego 8, etcétera. El equiva-
lente decimal del número binario 1011 es 1 * 1 + 0 * 2 + 1 * 4 + 1 * 8, o 1 + 0 + 4 + 8, o 13].
4.32 (Patrón de asteriscos en forma de tablero de damas) Escriba una aplicación que utilice sólo las instrucciones
de salida
System.out.print(“* “);
System.out.print(“ “);
System.out.println();
para mostrar el patrón de tablero de damas que se muestra a continuación. Observe que una llamada al método
System.out.println sin argumentos hace que el programa imprima un solo carácter de nueva línea. [Sugerencia:
se requieren estructuras de repetición].
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
4.33 (Múltiplos de 2 con un ciclo infinito) Escriba una aplicación que muestre en la ventana de comandos las
potencias del entero 2 (es decir, 2, 4, 8, 16, 32, 64, etcétera). Su ciclo no debe terminar (es decir, debe crear un ciclo
infinito). ¿Qué ocurre cuando ejecuta este programa?
4.34 (¿Qué está mal en este código?) ¿Qué está mal en la siguiente instrucción? Proporcione la instrucción correc-
ta para sumar uno a la suma de x y y.
System.out.println(++(x + y));
4.35 (Lados de un triángulo) Escriba una aplicación que lea tres valores distintos de cero introducidos por el
usuario, y que determine e imprima si podrían representar los lados de un triángulo.
4.36 (Lados de un triángulo rectángulo) Escriba una aplicación que lea tres enteros distintos de cero, y luego
determine e imprima si éstos podrían representar los lados de un triángulo rectángulo.
4.37 (Factorial) El factorial de un entero n no negativo se escribe como n! (se pronuncia “factorial de n”) y se de-
fine de la siguiente manera:
Escriba una aplicación que calcule el valor de ex, utilizando la siguiente fórmula. Deje que el usuario in-
troduzca el número de términos a calcular.
x x2 x3
ex = 1 + + + +…
1! 2! 3!
Marcando la diferencia
4.38 (Implementar la privacidad con la criptografía) El crecimiento explosivo de las comunicaciones de Inter-
net y el almacenamiento de datos en computadoras conectadas en red, ha incrementado de manera considerable los
problemas de privacidad. El campo de la criptografía se dedica a la codificación de datos para dificultar (y, mediante
los esquemas más avanzados, tratar de imposibilitar) su lectura a los usuarios no autorizados. En este ejercicio, usted
investigará un esquema simple para cifrar y descifrar datos. Una compañía que desea enviar datos por Internet le pidió
a usted que escribiera un programa que los cifre, de modo que se puedan transmitir con más seguridad. Todos los
datos se transmiten como enteros de cuatro dígitos. Su aplicación debe leer un entero de cuatro dígitos introducido
por el usuario, y cifrarlo de la siguiente manera: reemplace cada dígito con el resultado de sumarle 7 y obtenga el resi-
duo después de dividir el nuevo valor entre 10. Después intercambie el primer dígito con el tercero, y el segundo dí-
gito con el cuarto. Luego imprima el entero cifrado. Escriba una aplicación separada que reciba como entrada un
entero de cuatro dígitos cifrado y lo descifre (invirtiendo el esquema de cifrado) para formar el número original.
[Proyecto de lectura opcionall: investigue la “criptografía de clave pública” en general y el esquema de clave pública
específico PGP (privacidad bastante buena). Tal vez también quiera investigar el esquema RSA, que se utiliza mucho
en las aplicaciones de nivel industrial].
4.39 (Crecimiento de la población mundial) La población mundial ha crecido de manera considerable a través
de los siglos. El crecimiento continuo podría, en un momento dado, desafiar los límites del aire respirable, el agua
potable, la tierra cultivable y otros recursos limitados. Hay evidencia de que el crecimiento se ha reducido en años
recientes, y que la población mundial podría llegar a su valor máximo en algún momento de este siglo, para luego
empezar a disminuir.
Para este ejercicio, investigue en Internet las cuestiones sobre el crecimiento de la población mundial. Asegúrese
de investigar varios puntos de vista. Obtenga estimaciones de la población mundial actual y de su tasa de crecimiento
(el porcentaje por el cual es probable que aumente este año). Escriba un programa que calcule el crecimiento anual de
la población mundial durante los siguientes 75 años, utilizando la suposición simplificada de que la tasa de crecimiento
actual permanecerá constante. Imprima los resultados en una tabla. La primera columna debe mostrar el año, desde el
año 1 hasta el año 75. La segunda columna debe mostrar la población mundial anticipada al final de ese año. La ter-
cera columna deberá mostrar el aumento numérico en la población mundial que ocurriría ese año. Use sus resultados
para determinar el año en el que el tamaño de la población será del doble del actual, si la tasa de crecimiento de este
año permaneciera.
5
La rueda se convirtió en un círculo
completo.
parte 2: operadores lógicos
—William Shakespeare
—
Objetivos
En este capítulo aprenderá a:
■ Comprender los fundamentos
de la repetición controlada por
un contador.
■ Utilizar las instrucciones de
repetición for y do...while
para ejecutar instrucciones de
manera repetitiva en un
programa.
■ Comprender la selección
múltiple utilizando la
instrucción de selección
switch.
5.4 Ejemplos sobre el uso de la instrucción for 5.10 Resumen sobre programación estructurada
Resumen | Ejercicios de autoevaluación | Respuestas a los ejercicios de autoevaluación | Ejercicios | Marcando la diferencia
5.1 Introducción
En este capítulo continuaremos nuestra presentación de la teoría y los principios de la programación es-
tructurada, presentando el resto de las instrucciones de control en Java, excepto una. También demostra-
remos las instrucciones for, do...while y switch de Java. A través de una serie de ejemplos cortos en los
que utilizaremos las instrucciones while y for, exploraremos los fundamentos de la repetición controlada
por contador. Usaremos una instrucción switch para contar el número de calificaciones equivalentes de A,
B, C, D y F, en un conjunto de calificaciones numéricas introducidas por el usuario. Presentaremos las
instrucciones de control de programa break y continue. Hablaremos sobre los operadores lógicos de Java,
que nos permiten utilizar expresiones condicionales más complejas en las instrucciones de control. Por
último, veremos un resumen de las instrucciones de control de Java y las técnicas ya probadas de solución
de problemas que presentamos en éste y en el capítulo 4.
Fig. 5.1 冷 Repetición controlada con contador, con la instrucción de repetición while (parte 1 de 2).
1 2 3 4 5 6 7 8 9 10
Fig. 5.1 冷 Repetición controlada con contador, con la instrucción de repetición while (parte 2 de 2).
En la figura 5.1, los elementos de la repetición controlada por contador se definen en las líneas 8, 10
y 13. La línea 8 declaraa la variable de control (contador) como un int, reserva espacio para esta variable en
memoria y establece su valor iniciall en 1. La variable contador también podría haberse declarado e inicia-
lizado con la siguientes instrucciones de declaración y asignación de variables locales:
int contador; // declara contador
contador = 1; // inicializa contador en 1
La línea 12 muestra el valor de la variable de control contador durante cada iteración del ciclo. La línea 13
incrementaa la variable de control en 1, para cada iteración del ciclo. La condición de continuación de ciclo
en la instrucción while (línea 10) evalúa si el valor de la variable de control es menor o igual que 10 (el
valor final para el que la condición sea true). El programa ejecuta el cuerpo de este while aun cuando la
variable de control sea 10. El ciclo termina cuando la variable de control es mayor que 10 (es decir, cuando
contador se convierte en 11).
El programa de la figura 5.1 puede hacerse más conciso si inicializamos contador en 0 en la línea 8, y
preincrementamos contador en la condición while de la siguiente forma:
while (++contador <= 10) // condición de continuación de ciclo
System.out.printf(%d ”, contador);
Este código ahorra una instrucción, ya que la condición de while realiza el incremento antes de evaluar la
condición (en la sección 4.13 vimos que la precedencia de ++ es mayor que la de <=). La codificación en
esta forma tan condensada requiere de práctica y puede hacer que el código sea más difícil de leer, depurar,
modificar y mantener, así que en general, es mejor evitarla.
1 2 3 4 5 6 7 8 9 10
Fig. 5.2 冷 Repetición controlada por contador, con la instrucción de repetición for.
Cuando la instrucción for (líneas 10 y 11) comienza a ejecutarse, la variable de control contador se
declaraa e inicializaa en 1 (en la sección 5.2 vimos que los primeros dos elementos de la repetición controlada
por un contador son la variable de controll y su valor inicial).
l A continuación, el programa verifica la condi-
ción de continuación de ciclo, contador <= 10, la cual se encuentra entre los dos signos de punto y coma
requeridos. Como el valor inicial de contador es 1, al principio la condición es verdadera. Por lo tanto, la
instrucción del cuerpo (línea 11) muestra el valor de la variable de control contador, que es 1. Después de
ejecutar el cuerpo del ciclo, el programa incrementa a contador en la expresión contador++, la cual apare-
ce a la derecha del segundo signo de punto y coma. Después, la prueba de continuación de ciclo se ejecuta
de nuevo para determinar si el programa debe continuar con la siguiente iteración del ciclo. En este punto,
el valor de la variable de control es 2, por lo que la condición sigue siendo verdadera (el valor finall no se
excede); así, el programa ejecuta la instrucción del cuerpo otra vez (es decir, la siguiente iteración del ciclo).
Este proceso continúa hasta que se muestran en pantalla los números del 1 al 10 y el valor de contador se
vuelve 11, con lo cual falla la prueba de continuación de ciclo y termina la repetición (después de 10 repe-
ticiones del cuerpo del ciclo). Luego, el programa ejecuta la primera instrucción después del for; en este
caso, la línea 13.
La figura 5.2 utiliza (en la línea 10) la condición de continuación de ciclo contador <= 10. Si usted
especificara por error contador < 10 como la condición, el ciclo sólo iteraría nueve veces. A este error lógi-
co común se le conoce como error por desplazamiento en uno.
Separador Punto
Palabra Variable de punto y y coma
clave for de control coma requerido requerido
En la sección 5.8 veremos un caso para el cual no es posible representar una instrucción for con una ins-
trucción while equivalente. Por lo general, las instrucciones for se utilizan para la repetición controlada
por un contador, y las instrucciones while para la repetición controlada por un centinela. No obstante,
while y for pueden usarse para cualquiera de los dos tipos de repetición.
contador = contador + 1
contador += 1
++contador
contador++
son expresiones de incremento equivalentes en una instrucción for. Muchos programadores prefieren
contador++, ya que es concisa y además un ciclo for evalúa su expresión de incremento despuéss de la eje-
cución de su cuerpo, por lo que la forma de postincremento parece más natural. En este caso, la variable
que se incrementa no aparece en una expresión más larga, por lo que los operadores de preincremento y
postdecremento tienen en realidad el mismo efecto.
es equivalente a la instrucción
El incremento de una instrucción for también puede ser negativo, en cuyo caso sería un decremento y el
ciclo contaría en orden descendente.
Inicializa la
int contador = 1
variable de control
System.out.printf(“%d ”, contador);
Fig. 5.4 冷 Diagrama de actividad de UML para la instrucción for de la figura 5.2.