Anda di halaman 1dari 34

CAPÍTULO 4

La estructura condicional

Hasta ahora hemos visto cómo resolver problemas muy simples. En este capítulo se in-
troduce un nuevo tipo de estructura que nos va a permitir variar el flujo de control de nuestro
programa dependiendo de que se cumplan o no ciertas condiciones. En el ejemplo de la sec-
ción 3.4 (resolución de una ecuación de segundo grado) se podía dar el caso de que a valiese
cero; en tales circunstancias sería necesario aplicar un método distinto para resolver el sis-
tema de ecuaciones, pero con las estructuras que conocemos hasta ahora no es posible tener
varias alternativas para resolver un problema. Por tanto, nos sería de gran utilidad una es-
tructura que permitiese continuar la ejecución de nuestro algoritmo por diferentes caminos,
dependiendo de si se dan unas condiciones u otras. Esta nueva estructura es la llamada estruc-
tura condicional, de bifurcación o de selección. Existen distintas instrucciones que permiten
implementar este tipo de estructura, diferenciándose entre ellas en el número de alternativas
que ofrecen.

4.1. La estructura condicional


Comenzaremos viendo el tipo más simple de estructura de bifurcación. Debido a las pala-
bras reservadas que usa se suele denominar IF-THEN (que en castellano es SI-ENTONCES).
Esta estructura nos permitirá ejecutar un bloque de código en función de la veracidad o fal-
sedad de una condición. El organigrama que explica el funcionamiento de esta instrucción lo
tenemos en la figura 4.1.
En dicha figura, Condición es una expresión que devuelve un dato de tipo lógico y Blo-
queInst es un bloque de instrucciones. La interpretación sería: “si el resultado de evaluar
Condición es verdadero (.TRUE.) entonces ejecutamos BloqueInst y, si es falso (.FALSE.),

129
130 4.1. LA ESTRUCTURA CONDICIONAL

Verdadera
Condición

Falsa
BloqueInst

Figura 4.1: Organigrama de la instrucción IF-THEN.

no lo ejecutamos”. Es decir, planteamos como alternativa la ejecución o no de un conjunto de


instrucciones.
La sintaxis1 de esta instrucción en Fortran es la siguiente:
La estructura condicional IF-THEN
IF (<Condición>) THEN
<BloqueInst>
ENDIF

Ejemplo
1 IF (x.GT.4) THEN
2 y=6
3 ENDIF

En este caso evaluamos la expresión lógica (x.GT.4) y en caso de que sea cierta,
es decir, en caso de que el valor de la variable x sea mayor que 4, ejecutaremos la
instrucción de asignación y=6.

Ejemplo
1 IF (i/=0 .AND. j>=9) THEN
2 h=1/(2*j+3)
3 k=-h*20
4 ENDIF

En este caso comprobaremos si el valor de la variable i es distinto de 0 y el valor de j


es mayor o igual que 9; de ser así ejecutaremos las dos instrucciones de asignación.
1 El uso de los paréntesis que engloban a la condición lógica es obligatorio.
4. LA ESTRUCTURA CONDICIONAL 131

Observa que la condición es una expresión cuyo resultado es un dato de tipo lógico
y que puede ser tan compleja como necesitemos. En este caso la condición está com-
puesta por dos condiciones más simples.

Ejemplo
Construir una condicional que compruebe si el valor almacenado en una variable x es
par y, en caso afirmativo, que imprima un mensaje en pantalla indicando tal hecho.

1 IF (MOD(x,2)==0) THEN
2 PRINT*, "El número ",x," es par"
3 ENDIF

Para comprobar si un número es par, calculamos el resto de la división entera entre ese
número y dos. Si el resto es cero es que el número es par; en caso contrario el número
será impar. El resto se puede calcular con la función intrínseca MOD.

Ejemplo
1 IF x.GT.4 THEN
2 y=6
3 ENDIF

En este caso la instrucción está mal escrita ya que falta un par de paréntesis que englobe
a la condición. Al igual que ocurrirá con el resto de condicionales, la expresión lógica
ha de ir, obligatoriamente, entre paréntesis.

4.1.1. IF lógico (IF-THEN simplificado)


En algunas ocasiones podemos simplificar un poco la escritura de este tipo de condicional.
En concreto, cuando el conjunto de instrucciones que vamos a ejecutar consiste en una única
instrucción, podemos escribir la sentencia de selección como2:
La estructura condicional IF lógico
IF (<Condición>) <instrucción>

Esta sentencia condicional también es conocida como IF lógico.

Ejemplo
1 IF (x>4) y=6

En este caso evaluamos la expresión lógica (x>4) y en caso de que sea cierta, es decir,
en caso de que el valor de la variable x sea mayor que 4, ejecutaremos la asignación
y=6.
2 Al igual que ocurre con la condicional simple, los paréntesis de la condición son obligatorios.
132 4.1. LA ESTRUCTURA CONDICIONAL

Ejemplo
1 IF (i/=0 .AND. j>=9) PRINT*, "El valor de i es ",i

En este otro caso, imprimiremos el valor de i en pantalla cuando i sea distinto de 0 y


j sea mayor o igual que 9.

4.1.2. Ofreciendo una alternativa


En el caso de las condicionales anteriores, sólo podemos elegir entre ejecutar o no un
determinado bloque de instrucciones. Sin embargo, hay ocasiones en las que lo que tenemos
que hacer es decidir entre la ejecución de dos posibles bloques de instrucciones.

Ejemplo
Comprobar si una variable x contiene un valor par o impar y mostrar un mensaje que
indique la situación.
Si hacemos uso de la condicional simple tendríamos que hacer algo similar a lo si-
guiente:

1 IF (MOD(x,2)==0) PRINT*, "El número ",x," es par"


2 IF (MOD(x,2)/=0) PRINT*, "El número ",x," es impar"

es decir, tenemos que hacer una comprobación para verificar si es par y otra para ve-
rificar si es impar. Esto resulta poco eficiente ya que, en definitiva, lo que estamos
haciendo es comprobar dos veces lo mismo.

La estructura condicional permite incluir una segunda parte para solucionar de una forma
más natural este tipo de situaciones. Esta segunda versión se conoce como IF-THEN-ELSE
(en castellano SI-ENTONCES-SINO). Su organigrama lo tenemos en la figura 4.2.

Verdadera Falsa
Condición

BloqueV BloqueF

Figura 4.2: Organigrama de la instrucción IF-THEN-ELSE.


4. LA ESTRUCTURA CONDICIONAL 133

En dicha figura, Condición es una expresión que devuelve un dato de tipo lógico y Blo-
queV y BloqueF son dos grupos de instrucciones. La interpretación sería: “si el resultado de
evaluar Condición es verdadero (.TRUE.) entonces ejecutamos BloqueV y en caso contrario
(si es falso, .FALSE.) ejecutamos BloqueF”. Es decir, planteamos como alternativa la eje-
cución de dos bloques distintos de instrucciones. Observa que la estructura tiene un único
punto de entrada y un único punto de salida. Se comienza con la evaluación de la condición
y ambos caminos acaban en un punto común.
La sintaxis3 de esta instrucción en Fortran es la siguiente:
La estructura condicional IF-THEN-ELSE
IF (<Condición>) THEN
<BloqueV>
ELSE
<BloqueF>
ENDIF

Ejemplo
Reescribir la condicional que imprime un mensaje diciendo si un número es par o
impar.

1 IF (MOD(x,2)==0) THEN
2 PRINT*, x, " es par"
3 ELSE
4 PRINT*, x, " es impar"
5 ENDIF

El bloque de instrucciones que se ejecuta tras comprobar la condición, bien en la parte


THEN o bien en la parte ELSE, puede incluir cualquier tipo de instrucción, incluso nuevas
condicionales. Cuando encontramos una instrucción condicional dentro de otra decimos que
la instrucción está anidada. Anidar instrucciones consiste en incluir una instrucción de un
determinado tipo dentro de otra del mismo tipo.

Ejemplo
Escribir un trozo de programa que imprima un mensaje diciendo si un número almace-
nado en una variable x es mayor, menor o igual que 4.

1 IF (x>4) THEN
2 PRINT*, x, " es mayor que 4"
3 ELSE
4 IF (x<4) THEN
5 PRINT*, x, " es menor que 4"
6 ELSE
7 PRINT*, x, " es igual que 4"
3 El paréntesis de la expresión lógica es obligatorio (al igual que en las otras condicionales).
134 4.2. LA ESTRUCTURA MULTICONDICIONAL

8 ENDIF
9 ENDIF

En este caso, la condicional IF (x<4) está anidada dentro de la parte ELSE de la


condicional IF (x>4) y sólo se ejecutará si la condición (x>4) evalúa como .FALSE.
Nótese que cada instrucción condicional lleva su propia parte THEN, su parte ELSE y su
ENDIF.

4.2. La estructura multicondicional


Llamaremos estructura multicondicional a aquella que nos permite elegir entre varias
alternativas de ejecución (más de una). En Fortran existen dos instrucciones de este tipo:
IF-THEN-ELSEIF (en castellano SI-ENTONCES-SINO SI).
SELECT CASE (en castellano SEGÚN SEA).

4.2.1. La estructura IF-THEN-ELSEIF


En el ejemplo anterior hemos visto cómo elegir una de entre tres posibles alternativas
haciendo uso de estructuras condicionales dobles anidadas. En ese caso sería más cómodo
usar una única instrucción que nos simplifique un poco el proceso de escritura del programa.
En realidad la estructura IF-THEN-ELSEIF se puede considerar como una simplificación en
la escritura de ciertos tipos de condicionales con anidamiento en su parte ELSE.
Al igual que ocurre con el resto de estructuras que se estudian en este texto, existe un
único punto de entrada a la multicondicional (la primera condición) y un único punto de
salida donde convergen todas las alternativas propuestas.
El organigrama de esta instrucción lo tenemos en la figura 4.3.
Su sintaxis4 es la siguiente:
La estructura multicondicional IF-THEN-ELSEIF
IF (<Condición1>) THEN
<Bloque1>
ELSEIF (<Condición2>) THEN
<Bloque2>
.....
ELSEIF (<CondiciónN>) THEN
<BloqueN>
ELSE
<BloqueF>
ENDIF

Donde aparecen los puntos suspensivos podemos poner más partes ELSEIF (tantas como
necesitemos). El último bloque ELSE no es obligatorio.
4 Los paréntesis son obligatorios en todas las condiciones.
4. LA ESTRUCTURA CONDICIONAL 135

Verdadera Falsa
Condición1

Bloque1
Verdadera Falsa
Condición2

Bloque2 ...

Verdadera Falsa
CondiciónN

BloqueN BloqueF

Figura 4.3: Organigrama de la instrucción IF-THEN-ELSEIF.

Ejemplo
Reescribir el ejemplo anterior usando la instrucción IF-THEN-ELSEIF:

1 IF (x>4) THEN
2 PRINT*, x, " es mayor que 4"
3 ELSEIF (x.EQ.4) THEN
4 PRINT*, x, " es igual que 4"
5 ELSE
6 PRINT*, x, " es menor que 4"
7 ENDIF

Podemos observar que, aunque la escritura es muy similar a la del ejemplo anterior,
nos hemos ahorrado escribir un ENDIF. En este caso no hay anidamiento sino que hay
una única estructura multicondicional y por tanto sólo hay que usar un ENDIF.

Ejemplo
Dada la nota numérica de un alumno, queremos obtener la nota expresada con palabras
(suspenso, aprobado, notable, ...):

Solución A
136 4.2. LA ESTRUCTURA MULTICONDICIONAL

Veamos una posible implementación:

1 IF ((nota<0).OR.(nota>10)) THEN
2 PRINT*, "Nota incorrecta"
3 ELSEIF ((nota>=0) .AND. (nota<5)) THEN
4 PRINT*, "Suspenso"
5 ELSEIF ((nota>=5) .AND. (nota<7)) THEN
6 PRINT*, "Aprobado"
7 ELSEIF ((nota>=7) .AND. (nota<9)) THEN
8 PRINT*, "Notable"
9 ELSEIF ((nota>=9) .AND. (nota<10)) THEN
10 PRINT*, "Sobresaliente"
11 ELSE
12 PRINT*, "Matrícula de honor"
13 ENDIF

Supongamos que nota vale 8. La ejecución de esta instrucción sería como sigue:

Comprobamos si ((8<0).OR.(8>10)).
Como es falso, entonces pasamos al siguiente ELSEIF y hay que comprobar si
((8>=0).AND.(8<5)).
Como es falso, entonces pasamos al siguiente ELSEIF y hay que comprobar si
((8>=5).AND.(8<7)).
Como es falso, entonces pasamos al siguiente ELSEIF y hay que comprobar si
((8>=7).AND.(8<9)).
Como es verdadero, entonces ejecutamos el bloque correspondiente (PRINT*,
“Notable”) y acabamos la multicondicional.

En este caso la condición (nota>=5) del primer ELSEIF no es necesaria ya que si


llegamos a ese punto es porque no se cumplió la condición del primer IF, es decir,
((nota<0).OR.(nota>10)) y a partir de ese momento se cumplirá siempre que la
nota es mayor o igual que cero. Lo mismo ocurre en los otros ELSEIF. Por lo tanto,
esta solución está evaluando algunas subexpresiones que no son necesarias.

Solución B

A continuación se propone una versión mejorada de esta multicondicional en la que se


hacen menos comparaciones en las condiciones lógicas.

1 IF ((nota<0).OR.(nota>10)) THEN
2 PRINT*, "Nota incorrecta"
3 ELSEIF (nota<5) THEN
4 PRINT*, "Suspenso"
5 ELSEIF (nota<7) THEN
6 PRINT*, "Aprobado"
7 ELSEIF (nota<9) THEN
8 PRINT*, "Notable"
4. LA ESTRUCTURA CONDICIONAL 137

9 ELSEIF (nota<10) THEN


10 PRINT*, "Sobresaliente"
11 ELSE
12 PRINT*, "Matrícula de honor"
13 ENDIF

Hay que tener cuidado con las condiciones que se ponen en la estructura multicondicional
ya que deberían ser mutuamente excluyentes. Este hecho no es comprobado por el compilador
por lo que en algún caso podríamos estar cometiendo algún tipo de error o simplemente
haciendo nuestro programa poco eficiente.

Ejemplo
Determinar qué bloques de sentencias se ejecutan (y en qué orden) dependiendo de los
valores de las condiciones:

1 IF (Cond1) THEN
2 IF ((Cond2) .AND. (Cond3)) THEN
3 Bloque_1
4 ELSE
5 IF (Cond4) THEN
6 Bloque_2
7 END IF
8 Bloque_3
9 END IF
10 ELSE
11 Bloque_4
12 END IF

En la siguiente tabla podemos ver la solución:

Cond1 Cond2 Cond3 Cond4 Bloques


.FALSE. - - - 4
.TRUE. .FALSE. .FALSE. .FALSE. 3
.TRUE. .FALSE. .FALSE. .TRUE. 2, 3
.TRUE. .FALSE. .TRUE. .FALSE. 3
.TRUE. .FALSE. .TRUE. .TRUE. 2, 3
.TRUE. .TRUE. .FALSE. .FALSE. 3
.TRUE. .TRUE. .FALSE. .TRUE. 2, 3
.TRUE. .TRUE. .TRUE. .FALSE. 1
.TRUE. .TRUE. .TRUE. .TRUE. 1

Ejemplo
Supongamos que tenemos la estructura multicondicional del ejemplo anterior. ¿Pode-
mos reescribir dicho código sin hacer uso de estructuras multicondicionales? La res-
puesta es que sí y a continuación vemos una posible solución:
138 4.2. LA ESTRUCTURA MULTICONDICIONAL

1 IF (.NOT.(Cond1)) THEN
2 Bloque_4
3 END IF
4 IF ((Cond1) .AND. .NOT.(Cond2) .AND. .NOT.(Cond4)) THEN
5 Bloque_3
6 END IF
7 IF ((Cond1) .AND. .NOT.(Cond2) .AND. (Cond4)) THEN
8 Bloque_2
9 Bloque_3
10 END IF
11 IF ((Cond1) .AND. (Cond2) .AND. (Cond3)) THEN
12 Bloque_1
13 END IF
14 IF ((Cond1) .AND. (Cond2) .AND. .NOT.(Cond3) .AND. .NOT.(Cond4)) THEN
15 Bloque_3
16 END IF
17 IF ((Cond1) .AND. (Cond2) .AND. .NOT.(Cond3) .AND. (Cond4)) THEN
18 Bloque_2
19 Bloque_3
20 END IF

Hay otras soluciones pero todas ellas implican hacer múltiples veces las comproba-
ciones sobre las condiciones resultando más ineficientes (y difíciles de comprender)
que la estructura multicondicional. Al ser todas las condicionales ejecutadas de forma
secuencial una tras otra, es necesario que las condiciones de cada una de ellas sean
mutuamente excluyentes. Es la única forma de asegurarse de que en caso de entrar en
una de ellas no entraremos en ninguna otra.

También podemos apreciar que repetimos varias veces algunos de los bloques de códi-
go con el consiguiente gasto de memoria que eso supone.

4.2.2. La estructura SELECT-CASE

En algunos casos concretos donde hemos de elegir entre múltiples alternativas resulta
cómodo usar esta estructura, aunque su uso está limitado sólo a algunos tipos de formas
multicondicionales.
El organigrama lo podemos ver en la figura 4.4.
La sintaxis5 de esta estructura es:

5 Los paréntesis, tanto de la expresión como de los selectores, son obligatorios.


4. LA ESTRUCTURA CONDICIONAL 139

SELECT CASE (expr)

Cierto
expr==selector1 Bloque1
Falso

Cierto
expr==selector2 Bloque2
Falso

...

Cierto
expr==selectorN BloqueN
Falso

BloqueDef

END SELECT

Figura 4.4: Organigrama de la sentencia SELECT-CASE.

La estructura multicondicional SELECT-CASE


SELECT CASE (<expr>)
CASE (<selector1>)
<Bloque1>
CASE (<selector2>)
<Bloque2>
...
CASE (<selectorN>)
<BloqueN>
CASE DEFAULT
<BloqueDef>
END SELECT

La idea de la estructura consiste en evaluar la expresión <expr> y compararla con distin-


tos valores a los que hemos llamado selectores; dependiendo de con cual de ellos coincida,
ejecutaremos un bloque u otro de código. Esta comparación se va haciendo en orden has-
ta que encuentra coincidencia entre el valor de la expresión y alguno de los selectores. En
ese momento se ejecuta el bloque asociado al selector coincidente y finaliza la instrucción.
Si no se da la igualdad en ninguno de los casos entonces ejecutamos el bloque del selector
140 4.2. LA ESTRUCTURA MULTICONDICIONAL

DEFAULT. Hay algunas cosas que hemos de tener en cuenta cuando usemos esta instrucción:

La expresión <expr> ha de devolver como resultado un dato de tipo lógico (LOGICAL),


entero (INTEGER) o carácter (CHARACTER).

Los selectores tienen que ser constantes del mismo tipo que devuelve la expresión.
Dentro de un mismo selector podemos poner:

• Un único valor. Por ejemplo (3).


• Varios valores separados por comas. Por ejemplo (2,3,4,7,9). En este caso se
compara la expresión con todos ellos y si coincide con alguno se ejecuta el bloque
de ese selector.
• Un rango de valores. Por ejemplo (3:7) sería equivalente a (3,4,5,6,7). Cuan-
do ponemos un rango podemos omitir el comienzo o el final de dicho rango. Si
omitimos el final y por ejemplo ponemos (3:) queremos decir que compare con
los números 3, 4, 5, ..., es decir con todos los números mayores o iguales que
3. Si omitimos el comienzo, y por ejemplo ponemos (:5) queremos indicar que
compare con todos los números que sean menores o iguales que 5.
• Podemos mezclar valores y rangos. Por ejemplo (3, 8, 10:15, -2).

Los selectores han de ser mutuamente excluyentes. Si no lo fuesen el compilador gene-


ra un error (si fuese posible determinar esta circunstancia en tiempo de compilación).

El selector DEFAULT es opcional.

Tanto la expresión <expr> como los selectores han de ir entre paréntesis.

Esta estructura se podría sustituir por una condicional anidada IF-THEN-ELSE o bien por una
estructura IF-THEN-ELSEIF. En cambio, una estructura IF-THEN-ELSE (u otra variante) no
siempre podrá ser sustituida por una multicondicional SELECT-CASE ya que en esta los
selectores sólo pueden incluir constantes.

Ejemplo
Implementar un programa que, dado un número entero x, imprima un mensaje de texto
en función de su valor, según las siguientes alternativas:

Si es menor que 1.
Si vale 1.
Si vale 2, 3, ó 4.
Si está entre 5 y 10.
Si es mayor que 11.
4. LA ESTRUCTURA CONDICIONAL 141

1 SELECT CASE (x)


2 CASE (:1)
3 PRINT*, "x es menor que 1"
4 CASE (1)
5 PRINT*, "x vale 1"
6 CASE (2,3,4)
7 PRINT*, "x vale 2, 3 ó 4"
8 CASE (5:10)
9 PRINT*, "x esta entre 5 y 10"
10 CASE (11:)
11 PRINT*, "x es mayor o igual que 11"
12 END SELECT

En este caso no hemos necesitado el selector DEFAULT ya que tenemos cubiertas todas
las posibilidades. De todas formas el último selector CASE (11:) lo podríamos haber
sustituido por un CASE DEFAULT ya que si llegamos a ese punto tenemos garantizado
que el número almacenado en x es mayor o igual que 11.

Ejemplo
Vamos a plantearnos la posibilidad de escribir un programa para gestionar una pequeña
base de datos con los alumnos de una asignatura. Una de las tareas que hemos de hacer
es preparar un menú de opciones a través del cual preguntemos al usuario qué tipo
de operación desea realizar sobre dicha base de datos (añadir nuevos alumnos, buscar,
...) y actuar en consecuencia. Escribir un programa que imprima un menú de opciones
en pantalla, permita seleccionar una de ellas, y ejecute la acción asociada a la opción
elegida. Las opciones serán las siguientes:

a) Obtener un listado con todos los alumnos.


b) Buscar los datos de un alumno a partir de su NIF.
c) Añadir un nuevo alumno a la base de datos.
d) Borrar un alumno de la base de datos.
e) Finalizar la ejecución del programa.

Sólo tenemos que realizar la parte que se encarga de presentar el menú y elegir una
opción. No entraremos al detalle de realizar cada una de esas tareas.

Análisis

Lo primero de todo es realizar el correspondiente análisis del problema. En este caso


comenzaremos planteándonos qué datos vamos a necesitar para que funcione el menú.
El usuario, en algún momento, ha de introducir mediante el teclado la opción del me-
nú que desea ejecutar. Por tanto, un dato de entrada a nuestro programa es la opción
que elige el usuario. ¿Qué tipo de dato es? Esto dependerá de cómo queramos hacer el
menú; una alternativa bastante usual es asignar un número a cada una de las opciones
del menú de forma que para seleccionar una de ellas bastará con introducir el número
142 4.2. LA ESTRUCTURA MULTICONDICIONAL

correspondiente. Es decir si, por ejemplo, asociamos el número 1 a la opción que nos
permite hacer un listado de los datos que maneja el programa, nos bastará con introdu-
cir el número 1 por el teclado para que nuestro algoritmo interprete que deseamos tener
un listado de los datos. Si optamos por este método, entonces la variable que almace-
nará la opción elegida por el usuario puede ser de tipo entero. ¿Qué rango de valores
es válido? Esto viene determinado por el número de opciones de nuestro menú.
Ahora hay que determinar las variables de salida del algoritmo. ¿Cuáles son? En es-
te caso las variables de salida dependerán de la opción que hayamos elegido. Puesto
que no vamos a escribir los algoritmos que realizan los trabajos asociados a cada op-
ción, nuestro algoritmo no necesitará tener variables de salida. Simplemente dejaremos
indicadas las operaciones que habría que realizar para cada opción.

Diseño

Las etapas para resolver el problema serían:

a) Mostrar un menú con las opciones válidas


b) Leer un dato por teclado que sea el número de opción seleccionada
c) Según sea dicho valor ejecutar el bloque de instrucciones correspondiente

El organigrama podría quedar como el de la figura 4.5.

Implementación

Para hacer el algoritmo algo más cómodo (por si necesitásemos variar las opciones más
adelante) vamos a definir como constantes el número de opciones y los mensajes que
aparecerán por pantalla para cada opción.
El programa sería este:

1 PROGRAM Menu !### ejselect.f90 ###


2 IMPLICIT NONE
3 ! Implementación de un Menú de opciones

4 ! Declaración de constantes
5 ! Vamos a definir como constantes el número de opciones que
6 ! tendrá nuestro menú y el nombre de cada opción
7 INTEGER, PARAMETER :: NumeroOpc=5
8 CHARACTER (LEN=*), PARAMETER :: &
9 &opc1="1 - Listado de alumnos", &
10 &opc2="2 - Buscar un alumno", &
11 &opc3="3 - Añadir alumno", &
12 &opc4="4 - Borrar un alumno", &
13 &opc5="5 - Finalizar"

14 ! Declaración de variables
15 INTEGER :: op ! Esta variable servirá para leer la opción
4. LA ESTRUCTURA CONDICIONAL 143

Inicio

Mostrar Menu

Leer opcion

SELECT CASE (opcion)

Cierto
opcion==1 Listar alumnos ...
Falso

Cierto
opcion==2 Buscar alumno ...
Falso

Cierto
opcion==3 Anadir nuevo alumno ...
Falso

Cierto
opcion==4 Borrar un alumno ...
Falso

Cierto
opcion==5 Finalizar ...
Falso

Opcion incorrecta ...

END SELECT

Fin

Figura 4.5: Organigrama para el ejemplo del menú de opciones.

16 ! Mostrar menú en pantalla


17 PRINT*, opc1
18 PRINT*, opc2
144 4.2. LA ESTRUCTURA MULTICONDICIONAL

19 PRINT*, opc3
20 PRINT*, opc4
21 PRINT*, opc5

22 ! Leer opción por teclado


23 PRINT*, "¿Qué opción quieres ejecutar?"
24 READ*, op

25 ! Ejecutar la acción asociada a la opción seleccionada


26 SELECT CASE (op)
27 CASE (1)
28 PRINT*, "Has seleccionado listar a los alumnos"
29 CASE (2)
30 PRINT*, "Has seleccionado buscar a un alumno"
31 CASE (3)
32 PRINT*, "Añadir a un alguno"
33 CASE (4)
34 PRINT*, "Cuidado con quien borras"
35 CASE (5)
36 PRINT*, "Hasta la próxima"
37 CASE DEFAULT
38 PRINT*, "Te has equivocado"
39 END SELECT

40 END
4. LA ESTRUCTURA CONDICIONAL 145

4.3. Resumen

Las estructuras condicionales permiten alterar el flujo de ejecución normal de un progra-


ma y permiten elegir entre varias alternativas para seguir la ejecución.

La estructura condicional IF-THEN


IF (<Condición>) THEN
<BloqueSiCondicionTRUE>
ENDIF

La estructura condicional IF lógico


IF (<Condición>) <una_instrucción_SiCondicionTRUE>

La estructura condicional IF-THEN-ELSE


IF (<Condición>) THEN
<BloqueSiCondicionTRUE>
ELSE
<BloqueSiCondicionFALSE>
ENDIF

La estructura multicondicional IF-THEN-ELSEIF


IF (<Condición1>) THEN
<BloqueSiCondicion1TRUE>
ELSEIF (<Condición2>) THEN
<BloqueSiCondicion2TRUE>
.....
ELSEIF (<CondiciónN>) THEN
<BloqueSiCondicionNTRUE>
ELSE
<BloqueSiNingunaCondicionTRUE>
ENDIF
146 4.3. RESUMEN

La estructura multicondicional SELECT-CASE


SELECT CASE (<expr>)
CASE (<selector1>)
<BloqueSiExpr==Selector1>
CASE (<selector2>)
<BloqueSiExpr==Selector2>
...
CASE (<selectorN>)
<BloqueSiExpr==SelectorN>
CASE DEFAULT
<BloqueSiExprDistintoSelectores>
END SELECT

Los paréntesis de la condición y de los selectores son obligatorios.


El IF lógico sólo se usa cuando el bloque condicional consta de una única instrucción.
El IF lógico no lleva las palabras reservadas THEN ni ENDIF.
La parte ELSE y la parte DEFAULT son opcionales.
En SELECT-CASE: la expresión ha de devolver un dato de tipo entero, carácter o lógico.
En SELECT-CASE: los selectores han de ser mutuamente excluyentes y pueden estar
formados por:

• Valores individuales.
• Varios valores (separados por comas).
• Rangos de valores (usando dos puntos :).
• Mezcla de valores y rangos de valores.
4. LA ESTRUCTURA CONDICIONAL 147

4.4. Ejercicios
1. Supongamos que A, B, C y D son variables enteras y que Bloque1, Bloque2, Bloque3
y Bloque4 son conjuntos de instrucciones.

a) Expresa la siguiente instrucción condicional mediante condicionales simples ani-


dadas sin usar operadores lógicos:
1 IF ((A<B) .AND. (C/=D) .AND. ((B>D) .OR. (B==D))) THEN
2 Bloque1
3 ENDIF

b) Cambia el siguiente conjunto de condicionales anidadas por un grupo de condi-


cionales simples equivalentes sin usar anidamiento (nota: usa condiciones com-
puestas mediante operadores lógicos):
1 IF (A>B) THEN
2 IF (B<=C) THEN
3 IF (C/=D) THEN
4 Bloque1
5 ELSE
6 Bloque2
7 ENDIF
8 ELSE
9 Bloque3
10 ENDIF
11 ELSE
12 Bloque4
13 ENDIF

2. Haz un programa que lea tres números enteros por teclado y que, si el segundo de ellos
es negativo, calcule e imprima el producto de los tres. En caso contrario debe imprimir
la media de los tres números.

3. Calcula las soluciones de una ecuación de segundo grado teniendo en cuenta todas las
posibles alternativas.

4. Haz un programa que permita traducir entre grados Celsius (C), Fahrenheit (F), Kelvin
(K) y Rankine (R). El programa preguntará en qué unidades damos la temperatura de
entrada y a qué escala la queremos convertir. Para ello sabemos que:
K = C + 273,15
R = F + 459,67
5(F−32)
C= 9

5. Escribe un programa que pregunte el nombre, los apellidos, el salario base de un em-
pleado y su antigüedad en la empresa y que aplique las siguientes tablas para calcular
su sueldo mensual:
148 4.4. EJERCICIOS

Antigüedad Incremento Sueldo


<3 años +5 %
3≤ y <5 +10 %
5≤ y <8 +15 %
≥8 +20 %
Las retenciones sobre la nómina mensual (ya aplicado el incremento de sueldo) son:
Sueldo bruto mensual Seguridad social IRPF
<900 euros 5% 10 %
900≤ y <1300 5% 12 %
1300≤ y <1800 7% 15 %
≥1800 8% 18 %
En los meses de Julio y Diciembre el empleado cobra paga extra. Esta paga supone
sumar al sueldo normal (con incremento) el salario base de un mes (sin incremento).
El programa imprimirá el nombre y las iniciales de los apellidos junto con el sueldo
bruto y neto de un mes normal, el sueldo bruto y neto de un mes de paga extra y el
sueldo bruto y neto totales anuales.
Por ejemplo, un empleado con una antigüedad de 4 años y un sueldo base de 1000 euros
cobrará un mes normal 1100 euros brutos. Descontando de ahí 55 euros de seguridad
social y 132 de IRPF nos queda que el sueldo neto es de 913 euros mensuales. Los
meses de paga extra cobrará 2100 euros brutos y 1743 euros netos. El sueldo bruto
anual es de 15200 euros y el neto es de 12616 euros.

6. Haz un programa que lea los siguientes datos de una persona: nombre, sueldo mensual,
edad y sexo. A continuación, el programa deberá clasificar a la persona en alguna de
las siguientes categorías:

a) Hombre pobre. Aquellos hombres cuyo sueldo sea inferior a 500 euros/mes.
b) Mujer rica. Las mujeres cuyo sueldo supere los 6000 euros/mes.
c) Joven mujer de clase media. Mujer cuya edad esté comprendida entre los 20 y los
30 años y cuyo sueldo esté entre 1200 y 2000 euros/mes.

Es posible que una persona no entre dentro de ninguna de estas categorías. En tal caso
imprime un mensaje que lo indique.

7. Haz un programa que lea los datos que definen un círculo (centro y radio) y las coor-
denadas de un punto en el espacio. El programa deberá decirnos si el punto está o no
dentro del círculo.

8. Haz un programa que lea las coordenadas que definen un rectángulo (esquina superior
y esquina inferior opuesta) y las coordenadas de un punto en el espacio. El programa
deberá decirnos si el punto está o no dentro del rectángulo.

9. Haz un programa que lea dos números enteros por teclado y diga si el primero divide
o no al segundo.
4. LA ESTRUCTURA CONDICIONAL 149

10. Haz un programa que lea tres valores enteros por teclado y que diga cuántos de ellos
hay iguales entre si.

11. En una ciudad compuesta por 6 barrios (cada uno identificado por un número entero
del 1 al 6) hay una empresa de transportes que cobra una tasa única por el reparto de
una carga (65 euros). Los camiones de la empresa pueden transportar tres pedidos en
cada viaje. Se establecen algunos descuentos según los siguientes criterios:

a) Si las tres cargas del camión van al mismo barrio se aplica un 30 % de descuento
a cada carga.
b) Si dos cargas van al mismo barrio se les aplica un 15 % de descuento (sólo a esas
dos).

Haz un programa que reciba como entrada los códigos de los barrios a los que van las
tres cargas de un viaje y que nos diga la cantidad que hay que pagar por cada carga. La
tasa única no será un dato de entrada sino una constante con nombre.

12. Haz un programa que lea por teclado el nombre de una fruta (manzana, naranja, pera,
...) y que, según sea la fruta, muestre una descripción de la misma. Si se introduce un
nombre de una fruta desconocida se mostrará un mensaje adecuado.

13. Realizar un programa que lea un año por teclado y diga si es o no bisiesto (divisible
por 4 y no por 100; excepto los divisibles por 400).

14. Haz un programa que lea el nombre de un mes y que diga el número de días que tiene
ese mes.

15. Hacer un programa que lea las coordenadas de tres puntos y que diga si forman o no
un triángulo6. Indicar también si el triángulo es o no equilátero.

16. Una fabrica de zapatos también fabrica las cajas de cartón para embalarlos. El coste
de la caja es 0.02 euros por cm2 de cartón. Si hay N pares de zapatos dispuestos para
ser embalados, y cada caja tiene una superficie de M cm2 , realizar un algoritmo que
calcule el gasto de la fabrica en las cajas y el precio de venta de los zapatos a partir del
costo (dado), del gasto en la caja y de la ganancia (30 %) (N y M son datos de entrada).

17. Un operador ferroviario establece una serie de descuentos en el precio de sus billetes
en función de las características del cliente:

a) Los clientes menores de 4 años no pagan. Los clientes cuya edad está entre 4 y 7
años pagan la mitad del billete. Los mayores de 65 años pagan el 40 % del billete.
b) Los estudiantes pagan el 40 % del importe.
c) Los miembros de familia numerosa pagan el 70 % del precio.
6 Si llamamos a los puntos A, B y C sabremos que forman un triángulo si la mayor de las distancias AB, AC, BC

es menor que la suma de las otras dos. Además, el triángulo será equilátero si las tres distancias son iguales. También
podemos decir que los tres puntos forman un triángulo si no están alineados.
150 4.5. SOLUCIONES

Haz un programa que reciba como entrada el precio de un billete y que le pregunte al
usuario los datos necesarios para averiguar que descuento le corresponde. El programa
nos dirá que porcentaje de descuento se aplica y el precio rebajado. Ten en cuenta que
siempre se aplicará el descuento más beneficioso para el usuario y que los descuentos
no son acumulativos.

4.5. Soluciones
Ejercicio 1
a) La solución al primer apartado es la siguiente:
1 IF (A<B) THEN
2 IF (C/=D) THEN
3 IF (B>=D) THEN
4 Bloque1
5 ENDIF
6 ENDIF
7 ENDIF
b) La solución al segundo apartado es:
1 IF ((A>B) .AND. (B<=C) .AND. (C/=D)) THEN
2 Bloque1
3 ENDIF
4 IF ((A>B) .AND. (B<=C) .AND. (C==D)) THEN
5 Bloque2
6 ENDIF
7 IF ((A>B) .AND. (B>C)) THEN
8 Bloque3
9 ENDIF
10 IF (A<=B) THEN
11 Bloque4
12 ENDIF

Ejercicio 2
Necesitamos tres variables enteras para almacenar los tres datos de entrada. Podríamos
declarar una cuarta variable para almacenar el dato de salida (que podría ser entero o
real dependiendo del caso) pero nos la vamos a ahorrar de forma que escribiremos la
expresión que hace el cálculo del resultado directamente en la instrucción PRINT de
salida de datos.
Una vez leídos los datos de entrada hemos de usar una condicional que permita com-
probar el valor del segundo de ellos y, en función de su valor (positivo o negativo),
que se realice un cálculo u otro. Es decir, tenemos dos posibles alternativas, por lo que
parece que la estructura se ajusta a una condicional doble.
La solución sería la siguiente:
4. LA ESTRUCTURA CONDICIONAL 151

1 PROGRAM TresNumeros !### tresnum.f90 ###


2 IMPLICIT NONE

3 INTEGER :: a, b, c

4 ! Pedimos los datos


5 PRINT*, "Dime tres números enteros"
6 READ*, a, b, c

7 ! Comprobamos si el segundo es negativo y mostramos resultado


8 IF (b<0) THEN
9 PRINT*, "El producto es: ", a*b*c
10 ELSE
11 PRINT*, "La media es: ", (a+b+c)/3.0
12 ENDIF

13 END PROGRAM TresNumeros

Observa que para el cálculo de la media hemos dividido por el número real 3.0. De esta
forma forzamos la promoción del numerador a representación real y la división es real
(obtenemos también los decimales).

Ejercicio 3
Como entradas tendremos los coeficientes (reales) de la ecuación a, b y c. En cuanto
a los datos de salida, estos pueden variar en función del tipo de ecuación que formen
los coeficientes: podemos tener una solución, dos soluciones, ninguna solución real
o infinitas soluciones. Puesto que hasta que no empezamos a hacer los cálculos no
sabemos qué solución debemos dar, podríamos pensar en ir escribiendo instrucciones
PRINT conforme las vayamos necesitando (intercaladas entre los cálculos).
En lugar de hacer eso vamos a seguir el protocolo habitual:

a) Pedimos datos de entrada.


b) Hacemos todos los cálculos.
c) Mostramos datos de salida.

Tras pedir los datos de entrada empezamos a distinguir posibles casos:

Si a==0 y b==0 entonces cualquier x es solución de la ecuación.


Si a==0 y b/=0 entonces hay una única solución real (la llamaremos x1).
Si a/=0 y el discriminante es negativo entonces no hay soluciones reales.
Si a/=0 y el discriminante es positivo entonces hay dos soluciones x1 y x2.
Si a/=0 y el discriminante es cero entonces hay una solución x1.
152 4.5. SOLUCIONES

Una vez que hemos hecho el cálculo, en función del valor de los coeficientes, vamos a
mostrar el resultado pero de nuevo tenemos varias alternativas:

Si a==0 y b==0 entonces escribimos un mensaje diciendo que cualquier x es


solución de la ecuación.
Si a==0 y b/=0 entonces diremos que la única solución es el valor de x1.
...

Es decir, hemos de escribir una estructura de condicionales análoga a la anterior. Para


evitar repetir esta estructura podemos usar una variable adicional (tiposolucion) que
almacene un valor que codifique el tipo de solución que hemos de mostrar. Por ejemplo:

tiposolucion=0 si no hay soluciones reales.


tiposolucion=1 si la única solución se ha calculado en x1.
tiposolucion=2 si las dos soluciones están en x1 y x2.
tiposolucion=3 si cualquier valor de x es solución.

De esta forma, cuando estamos haciendo los cálculos le asignamos a la variable llama-
da tiposolucion el valor que le corresponde para después consultarlo y mostrar el
mensaje de salida adecuado.

1 PROGRAM Ecuacion2G !### ecu2g.f90 ###


2 IMPLICIT NONE

3 REAL :: a,b,c,x1,x2,disc
4 INTEGER :: tiposolucion

5 ! Leemos coeficientes
6 PRINT*, "Dime los coeficientes de la ecuación a, b y c"
7 READ*, a, b, c

8 ! Calculamos las soluciones


9 ! Usaremos la variable de tipo "bandera" tiposolucion para almacenar
10 ! el tipo de solución que hemos encontrado:
11 ! 0 -> No hay soluciones reales
12 ! 1 -> Hay una solución real
13 ! 2 -> Hay dos soluciones reales
14 ! 3 -> Hay infinitas soluciones reales
15 IF (a==0) THEN
16 IF (b==0) THEN
17 tiposolucion = 3 ! Infinitas soluciones
18 ELSE
19 tiposolucion = 1 ! Unica solución real
20 x1 = -c / b
21 ENDIF
22 ELSE
4. LA ESTRUCTURA CONDICIONAL 153

23 disc = b**2 - 4*a*c ! El discriminante


24 IF (disc<0) THEN
25 tiposolucion = 0 ! No hay soluciones reales
26 ELSE IF (disc>0) THEN
27 tiposolucion = 2 ! Tenemos 2 soluciones reales
28 x1 = (-b + SQRT(disc)) / (2*a)
29 x2 = (-b - SQRT(disc)) / (2*a)
30 ELSE
31 tiposolucion = 1 ! Única solución real
32 x1 = -b / (2*a)
33 ENDIF
34 ENDIF

35 ! Imprimimos los resultados


36 SELECT CASE (tiposolucion)
37 CASE (0)
38 PRINT*, "No hay soluciones reales"
39 CASE (1)
40 PRINT*, "La única solución es ",x1
41 CASE (2)
42 PRINT*, "Las soluciones son x=",x1," y x=",x2
43 CASE (3)
44 PRINT*, "Cualquier valor de x es solución"
45 END SELECT

46 END PROGRAM

Ejercicio 5
En este problema los datos de entrada son el nombre del empleado (cadena de carac-
teres), los apellidos (cadena de caracretes), la antigüedad en la empresa (entero) y el
salario base (real).
Hemos optado por calcular primero todos los porcentajes que se han de aplicar (incre-
mentos y retenciones) para, posteriormente, aplicarlos sobre el sueldo. De esta forma,
las ecuaciones que calculan los datos de salida son válidas independientemente de lo
que valgan en concreto dichos porcentajes.

1 PROGRAM Sueldo !### sueldo.f90 ###


2 IMPLICIT NONE

3 ! Declaración de variables de entrada


4 CHARACTER (LEN=50) :: nombre, apellidos ! Nombre y apellidos
5 INTEGER :: antiguedad ! Antigüedad en la empresa
6 REAL :: salario_base ! Salario base de cálculo

7 ! Otras variables
8 REAL :: incremento ! Incremento de sueldo por antigüedad
154 4.5. SOLUCIONES

9 REAL :: retencion_ss, retencion_irpf ! Retenciones del sueldo


10 REAL :: sueldo_bruto_mes, sueldo_neto_mes ! Sueldo bruto/neto al mes
11 REAL :: sueldo_extra_bruto, sueldo_extra_neto ! Sueldo con paga extra
12 REAL :: sueldo_bruto_anual, sueldo_neto_anual ! Sueldo anual
13 CHARACTER :: inicial1, inicial2 ! Iniciales de cada apellido
14 INTEGER :: pos2 ! Para calcular la posición de inicio del 2o apellido

15 ! Lectura de datos desde teclado


16 PRINT*, "Dime el nombre del empleado"
17 READ*, nombre
18 PRINT*, "Dime los dos apellidos del empleado" ! Suponemos 2 apellidos
19 READ*, apellidos
20 PRINT*, "¿Cuántos años lleva en la empresa?"
21 READ*, antiguedad
22 PRINT*, "¿Cuál es el salario base?"
23 READ*, salario_base

24 IF ((antiguedad<0) .OR. (salario_base<0)) THEN


25 PRINT*, "Los datos de entrada son incorrectos"
26 ELSE
27 ! Calculamos el factor de incremento de sueldo por antigüedad
28 IF (antiguedad<3) THEN
29 incremento = 0.05
30 ELSE IF (antiguedad<5) THEN
31 incremento = 0.10
32 ELSE IF (antiguedad<8) THEN
33 incremento = 0.15
34 ELSE
35 incremento = 0.20
36 ENDIF

37 ! El sueldo bruto mensual será:


38 sueldo_bruto_mes = salario_base + salario_base*incremento

39 ! Cálculo de retenciones IRPF y SS en función del bruto mensual


40 IF (sueldo_bruto_mes<900) THEN
41 retencion_ss = 0.05
42 retencion_irpf = 0.10
43 ELSE IF (sueldo_bruto_mes<1300) THEN
44 retencion_ss = 0.05
45 retencion_irpf = 0.12
46 ELSE IF (sueldo_bruto_mes<1800) THEN
47 retencion_ss = 0.7
48 retencion_irpf = 0.15
49 ELSE
50 retencion_ss = 0.08
51 retencion_irpf = 0.18
52 ENDIF
4. LA ESTRUCTURA CONDICIONAL 155

53 ! El sueldo neto mensual será:


54 sueldo_neto_mes = sueldo_bruto_mes - &
55 & (retencion_ss+retencion_irpf)*sueldo_bruto_mes

56 ! Los meses de paga extra:


57 sueldo_extra_bruto = sueldo_bruto_mes + salario_base
58 sueldo_extra_neto = sueldo_extra_bruto - &
59 & (retencion_ss+retencion_irpf)*sueldo_extra_bruto

60 ! Al año gana:
61 sueldo_neto_anual = sueldo_neto_mes*10 + sueldo_extra_neto*2
62 sueldo_bruto_anual = sueldo_bruto_mes*10 + sueldo_extra_bruto*2

63 ! Calculamos las iniciales de los apellidos.


64 ! El primer carácter será la inicial del primer apellido
65 inicial1 = apellidos(1:1)

66 ! Para buscar la inicial del segundo apellido buscamos la


67 ! posición donde se encuentre el primer espacio en blanco en la
68 ! cadena apellidos. La inicial será, previsiblemente, el carácter
69 ! que viene a continuación. Si, por ejemplo, usamos varios
70 ! espacios en blanco para separar los apellidos este método no
71 ! funciona bien.

72 ! Posición donde se encuentra el primer espacio en blanco


73 pos2 = INDEX(apellidos," ")
74 IF ((pos2==0) .OR. (pos2==LEN(apellidos))) THEN
75 ! En el caso de que no haya segundo apellido
76 inicial2 = " "
77 ELSE
78 inicial2 = apellidos(pos2+1:pos2+1)
79 ENDIF

80 ! Mostramos datos:
81 IF (inicial2==" ") THEN
82 PRINT*, "Trabajador: ", inicial1, "., ",TRIM(nombre)
83 ELSE
84 PRINT*,"Trabajador: ", inicial1, ". ", inicial2, "., ", &
85 & TRIM(nombre)
86 ENDIF

87 PRINT*, "Sueldo bruto mensual = ", sueldo_bruto_mes


88 PRINT*, "Sueldo neto mensual = ", sueldo_neto_mes
89 PRINT*, "Sueldo bruto paga extra = ", sueldo_extra_bruto
90 PRINT*, "Sueldo neto paga extra = ", sueldo_extra_neto
91 PRINT*, "Sueldo bruto anual = ", sueldo_bruto_anual
92 PRINT*, "Sueldo neto anual = ", sueldo_neto_anual
93 ENDIF
156 4.5. SOLUCIONES

94 END PROGRAM Sueldo

Ejercicio 6
Los datos de entrada al problema serían: el nombre (cadena de caracteres), el sueldo
(número entero), la edad (entero) y el sexo (un carácter: M o F). Observa que en la etapa
de petición de datos no se hace ninguna comprobación sobre la validez de los mismos
(que el sueldo sea positivo, que el sexo sea M o F, que la edad sea positiva, etc.). Tras
pedir los datos de entrada, comprobaremos cuál de las condiciones del enunciado es la
que se cumple y codificaremos en una variable (tipo) el resultado. En la variable tipo
pondremos alguno de los siguientes valores:

0 : No es posible clasificar a la persona.


1 : Es un hombre pobre.
2 : Es una mujer rica.
3 : Es una mujer joven de clase media.

Una vez que tenemos calculado el valor de la variable tipo procederemos a mostrar los
datos de salida con una multicondicional de tipo SELECT CASE.
Observa que al escribir el nombre en pantalla hacemos uso de la función TRIM para
evitar que se escriban también los espacios en blanco de relleno de la cadena.

1 PROGRAM Clasifica !### clasifica.f90 ###


2 IMPLICIT NONE

3 CHARACTER(LEN=30) :: nombre
4 INTEGER :: sueldo, edad
5 CHARACTER :: sexo
6 INTEGER :: tipo

7 ! Leemos datos de entrada


8 PRINT*, "Dime el nombre"
9 READ*, nombre
10 PRINT*, "Dime la edad"
11 READ*, edad
12 PRINT*, "Dime el sueldo"
13 READ*, sueldo
14 PRINT*, "Dime el sexo (M/F)"
15 READ*, sexo

16 ! La variable tipo valdrá:


17 ! 0 -> Sin clasificar
18 ! 1 -> Hombre pobre
19 ! 2 -> Mujer rica
20 ! 3 -> Joven mujer de clase media
4. LA ESTRUCTURA CONDICIONAL 157

21 tipo=0
22 IF ((sexo==’M’) .OR. (sexo==’m’)) THEN
23 IF (sueldo<500) tipo=1
24 ELSE
25 IF (sueldo>6000) THEN
26 tipo=2
27 ELSE IF ((edad>=20) .AND. (edad<=30) .AND. (sueldo>=1200) &
28 & .AND. (sueldo<=2000)) THEN
29 tipo=3
30 ENDIF
31 ENDIF

32 SELECT CASE (tipo)


33 CASE (0)
34 PRINT*, TRIM(nombre),", usted no es clasificable"
35 CASE (1)
36 PRINT*, TRIM(nombre),", es usted un pobre hombre"
37 CASE (2)
38 PRINT*, TRIM(nombre),", es usted una mujer rica"
39 CASE (3)
40 PRINT*, TRIM(nombre),", eres una joven mujer de clase media"
41 END SELECT

42 END PROGRAM

Ejercicio 7
En este caso los datos de entrada serían las coordenadas del centro del círculo (reales)
y el radio del mismo (también real) además de las coordenadas del punto. Las coorde-
nadas del centro y del punto se pueden almacenar en cuatro variables de tipo real pero
en este caso vamos a definir un nuevo tipo de dato para almacenarlas. Ese nuevo tipo
constará de dos campos: uno para las ordenadas y otro para las abscisas.
La forma de resolver el problema es calcular la distancia desde el centro del círculo al
punto y comprobar si es menor, mayor o igual que el radio.

1 PROGRAM PuntoEnCirculo !### puntocir.f90 ###


2 IMPLICIT NONE

3 ! Definimos el tipo de dato Punto


4 TYPE Punto
5 REAL :: x,y
6 END TYPE

7 TYPE (Punto) :: centro, p ! Definimos dos variables de tipo Punto


8 REAL :: radio, dist

9 ! Leemos datos de entrada


158 4.5. SOLUCIONES

10 PRINT*, "Dime las coordenadas del centro del círculo"


11 READ*, centro
12 PRINT*, "Dime ahora su radio"
13 READ*, radio

14 PRINT*, "Dime las coordenadas del punto"


15 READ*, p

16 ! Calculamos la distancia del punto al centro del círculo


17 dist = SQRT((centro%x-p%x)**2+(centro%y-p%y)**2)

18 ! Comprobamos si la distancia es menor/mayor/igual que el radio


19 IF (dist<radio) THEN
20 PRINT*, "El punto está dentro del círculo"
21 ELSE IF (dist==radio) THEN
22 PRINT*, "El punto está en la circunferencia del círculo"
23 ELSE
24 PRINT*, "El punto está fuera del círculo"
25 ENDIF

26 END PROGRAM

Vemos cómo se ha usado la declaración de un nuevo tipo de dato para nombrar a un


nuevo tipo de objetos en el programa (coordenadas 2D). El uso de nuevos tipos de datos
simplifica la escritura de los programas y los hace más comprensibles, sobre todo si son
grandes. En este programa en lugar de haber definido cuatro variables reales para las
coordenadas del centro y del punto, únicamente hemos definido dos variables del nuevo
tipo de dato Punto.

Ejercicio 9
Como datos de entrada tenemos dos números enteros (m y n). El dato de salida será un
mensaje en pantalla indicando si m es divisible por n.
Para comprobar si un número m es divisible por otro n vamos a comprobar si el resto
de la división entera del primero por el segundo es cero. En caso afirmativo podremos
decir que n divide a m. Para el cálculo del resto de una división entera usaremos la
función intrínseca MOD.
Equivalentemente, podemos sustituir la función MOD por la expresión m-(m/n)*n. En
este caso, al tratarse de variables enteras, la división m/n obtendría el cociente de la
división entera (sin decimales).

1 PROGRAM DivideNum !### ndivm.f90 ###


2 IMPLICIT NONE

3 INTEGER :: n, m
4. LA ESTRUCTURA CONDICIONAL 159

4 ! Preguntamos por los números


5 PRINT*, "Dime dos números enteros"
6 READ*, n, m

7 ! Comprobamos si n divide a m
8 IF (MOD(m,n)==0) THEN
9 PRINT*, n, " divide a ", m
10 ELSE
11 PRINT*, n, " no divide a ", m
12 ENDIF

13 END PROGRAM

Ejercicio 14
El dato de entrada es el nombre de un mes. Para almacenarlo necesitaremos una va-
riable de tipo cadena de caracteres. La longitud máxima de dicha cadena será la del
nombre del mes más largo que podamos tener (Septiembre con diez caracteres).
En este programa hemos de cuidar la escritura de mayúsculas y minúsculas en el nom-
bre de los meses cuando lo ejecutemos ya que si, por ejemplo, escribimos el nombre
todo en minúsculas o todo en mayúsculas nos diría que no es reconocido. La forma de
escribir los meses será: la primera letra mayúscula y el resto minúsculas (tal como se
han escrito en la multicondicional SELECT CASE).

1 PROGRAM NombreMes !### nommes.f90 ###


2 IMPLICIT NONE

3 CHARACTER (LEN=10) :: mes

4 PRINT*, "Dime el mes:"


5 READ*, mes

6 ! Tenemos que tener cuidado con mayúsculas y minúsculas


7 SELECT CASE (mes)
8 CASE ("Enero","Marzo","Mayo","Julio","Agosto","Octubre",&
9 &"Diciembre")
10 PRINT*, "Tiene 31 días"
11 CASE ("Febrero")
12 PRINT*, "Tiene 28 o 29 días"
13 CASE ("Abril","Junio","Septiembre","Noviembre")
14 PRINT*, "Tiene 30 días"
15 CASE DEFAULT
16 PRINT*, "No conozco ese mes"
17 END SELECT

18 END
160 4.5. SOLUCIONES

Ejercicio 15
Para almacenar las coordenadas de los tres puntos de entrada usaremos un nuevo tipo
de dato de forma análoga a como hicimos en el ejercicio 7. Los pasos a seguir son los
siguientes:

a) Preguntamos por las coordenadas de los tres puntos A, B y C.


b) Calculamos la longitud de los tres lados AB, AC, BC.
c) Comprobamos cuál de los tres lados es el mayor mediante varias condicionales.
Anotamos en una nueva variable (LadoMayor) cuál de las tres es la mayor dis-
tancia.
d) A continuación, sabiendo cuál es lado de mayor longitud sumamos los otros dos.
e) Finalmente, y de acuerdo a la regla que indica el enunciado, comprobamos si
los tres puntos forman un triángulo o no. En el caso de que lo formen, también
comprobaremos si es equilátero.

1 PROGRAM Triangulo !### triangulo.f90 ###


2 IMPLICIT NONE

3 TYPE Punto2D
4 REAL :: x, y
5 END TYPE Punto2D

6 TYPE(Punto2D) :: a, b, c
7 REAL :: AB, AC, BC, LadoMayor, SumaOtros

8 ! Leemos datos
9 PRINT*, "Dame las coordenadas (x,y) del punto A:"
10 READ*, a
11 PRINT*, "Dame las coordenadas (x,y) del punto B:"
12 READ*, b
13 PRINT*, "Dame las coordenadas (x,y) del punto C:"
14 READ*, c

15 ! Calculamos la longitud de los lados


16 AB = SQRT( (a%x-b%x)**2 + (a%y-b%y)**2 )
17 AC = SQRT( (a%x-c%x)**2 + (a%y-c%y)**2 )
18 BC = SQRT( (b%x-c%x)**2 + (b%y-c%y)**2 )

19 ! Calculamos el lado de mayor longitud y lo almacenamos en LadoMayor


20 ! Esto lo podríamos hacer fácilmente usando la función intrínseca MAX:
21 ! LadoMayor = MAX(AB, AC, BC)
22 ! aunque en su lugar vamos a hacer uso de estructuras condicionales.
23 IF (AB>AC) THEN
24 IF (AB>BC) THEN
25 LadoMayor = AB
4. LA ESTRUCTURA CONDICIONAL 161

26 ELSE
27 LadoMayor = BC
28 ENDIF
29 ELSE
30 IF (AC>BC) THEN
31 LadoMayor = AC
32 ELSE
33 LadoMayor = BC
34 ENDIF
35 ENDIF

36 ! Comprobamos cuál es el lado mayor y calculamos la suma de los otros


37 ! dos en SumaOtros
38 IF (LadoMayor==AB) THEN
39 SumaOtros = AC+BC
40 ELSE IF (LadoMayor==AC) THEN
41 SumaOtros = AB+BC
42 ELSE
43 SumaOtros = AB+AC
44 ENDIF

45 ! Comprobamos si forman o no un triángulo


46 IF (LadoMayor<SumaOtros) THEN
47 PRINT*, "Los puntos sí forman un triángulo"
48 ! Comprobamos si es equilátero
49 IF ((AB==AC) .AND. (AB==BC)) THEN
50 PRINT*, "El triángulo es equilátero"
51 ELSE
52 PRINT*, "El triángulo no es equilátero"
53 ENDIF
54 ELSE
55 PRINT*, "Los puntos no forman un triángulo"
56 ENDIF

57 END
162 4.5. SOLUCIONES