capÍtulo - ugrdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 1 if (i/=0 .and. j>=9) then...

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

Upload: others

Post on 31-Jan-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

CAPÍTULO4La 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 nuestroprograma 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 quea valiesecero; 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 tenervarias 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 nuevaestructura es la llamadaestruc-tura condicional, debifurcacióno deselección. Existen distintas instrucciones que permitenimplementar este tipo de estructura, diferenciándose entre ellas en el número de alternativasque 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 denominarIF-THEN (que en castellano esSI-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 lotenemos en la figura 4.1.

En dicha figura,Condiciónes una expresión que devuelve un dato de tipo lógico yBlo-queInstes un bloque de instrucciones. La interpretación sería: “siel resultado de evaluarCondiciónes verdadero (.TRUE.) entonces ejecutamosBloqueInsty, si es falso (.FALSE.),

129

Page 2: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

130 4.1. LA ESTRUCTURA CONDICIONAL

Fal

sa

CondiciónVerdadera

BloqueInst

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

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

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) THEN2 y=63 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 variablex sea mayor que4, ejecutaremos lainstrucción de asignacióny=6.

Ejemplo

1 IF (i/=0 .AND. j>=9) THEN2 h=1/(2*j+3)

3 k=-h*204 ENDIF

En este caso comprobaremos si el valor de la variablei es distinto de0 y el valor dejes mayor o igual que9; de ser así ejecutaremos las dos instrucciones de asignación.

1El uso de los paréntesis que engloban a la condición lógica esobligatorio.

Page 3: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 131

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

Ejemplo

Construir una condicional que compruebe si el valor almacenado en una variablex espar y, en caso afirmativo, que imprima un mensaje en pantalla indicando tal hecho.

1 IF (MOD(x,2)==0) THEN2 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 esenúmero y dos. Si el resto es cero es que el número es par; en casocontrario el númeroserá impar. El resto se puede calcular con la función intrínsecaMOD.

Ejemplo

1 IF x.GT.4 THEN2 y=63 ENDIF

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

4.1.1. IF logico (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 aejecutar consiste en una únicainstrucció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 comoIF 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 variablex sea mayor que4, ejecutaremos la asignacióny=6.

2Al igual que ocurre con la condicional simple, los paréntesis de la condición son obligatorios.

Page 4: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

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 dei en pantalla cuandoi sea distinto de0 yj sea mayor o igual que9.

4.1.2. Ofreciendo una alternativa

En el caso de las condicionales anteriores, sólo podemos elegir entre ejecutar o no undeterminado bloque de instrucciones. Sin embargo, hay ocasiones en las que lo que tenemosque 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 queindique la situación.

Si hacemos uso de la condicional simple tendríamos que haceralgo 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 estamoshaciendo es comprobar dos veces lo mismo.

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

CondiciónFalsa

BloqueV BloqueF

Verdadera

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

Page 5: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 133

En dicha figura,Condiciónes una expresión que devuelve un dato de tipo lógico yBlo-queVy BloqueFson dos grupos de instrucciones. La interpretación sería: “si el resultado deevaluarCondiciónes verdadero (.TRUE.) entonces ejecutamosBloqueVy en caso contrario(si es falso,.FALSE.) ejecutamosBloqueF”. Es decir, planteamos como alternativa la eje-cución de dos bloques distintos de instrucciones. Observa que la estructura tiene un únicopunto de entrada y un único punto de salida. Se comienza con laevaluación de la condicióny 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 oimpar.

1 IF (MOD(x,2)==0) THEN2 PRINT*, x, " es par"

3 ELSE4 PRINT*, x, " es impar"5 ENDIF

El bloque de instrucciones que se ejecuta tras comprobar la condición, bien en la parteTHEN o bien en la parteELSE, puede incluir cualquier tipo de instrucción, incluso nuevascondicionales. Cuando encontramos una instrucción condicional dentro de otra decimos quela instrucción está anidada. Anidar instrucciones consiste en incluir una instrucción de undeterminado 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) THEN2 PRINT*, x, " es mayor que 4"

3 ELSE4 IF (x<4) THEN5 PRINT*, x, " es menor que 4"

6 ELSE7 PRINT*, x, " es igual que 4"

3El paréntesis de la expresión lógica es obligatorio (al igual que en las otras condicionales).

Page 6: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

134 4.2. LA ESTRUCTURA MULTICONDICIONAL

8 ENDIF9 ENDIF

En este caso, la condicionalIF (x<4) está anidada dentro de la parteELSE de lacondicionalIF (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 parteTHEN, su parteELSE y suENDIF.

4.2. La estructura multicondicional

Llamaremos estructura multicondicional a aquella que nos permite elegir entre variasalternativas de ejecución (más de una). En Fortran existen dos instrucciones de este tipo:

IF-THEN-ELSEIF(en castellanoSI-ENTONCES-SINO SI).

SELECT CASE(en castellanoSEGÚN SEA).

4.2.1. La estructura IF-THEN-ELSEIF

En el ejemplo anterior hemos visto cómo elegir una de entre tres posibles alternativashaciendo uso de estructuras condicionales dobles anidadas. En ese caso sería más cómodousar una única instrucción que nos simplifique un poco el proceso de escritura del programa.En realidad la estructuraIF-THEN-ELSEIFse puede considerar como una simplificación enla escritura de ciertos tipos de condicionales con anidamiento en su parteELSE.

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 desalida 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 partesELSEIF (tantas comonecesitemos). El último bloqueELSE no es obligatorio.

4Los paréntesis son obligatorios en todas las condiciones.

Page 7: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 135

Condición1FalsaVerdadera

Bloque1Condición2

Verdadera

Bloque2 . . .

CondiciónNVerdadera

Falsa

Falsa

BloqueFBloqueN

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

Ejemplo

Reescribir el ejemplo anterior usando la instrucciónIF-THEN-ELSEIF:

1 IF (x>4) THEN2 PRINT*, x, " es mayor que 4"

3 ELSEIF (x.EQ.4) THEN4 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 ladel ejemplo anterior,nos hemos ahorrado escribir unENDIF. En este caso no hay anidamiento sino que hayuna única estructura multicondicional y por tanto sólo hay que usar unENDIF.

Ejemplo

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

Solución A

Page 8: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

136 4.2. LA ESTRUCTURA MULTICONDICIONAL

Veamos una posible implementación:

1 IF ((nota<0).OR.(nota>10)) THEN2 PRINT*, "Nota incorrecta"

3 ELSEIF ((nota>=0) .AND. (nota<5)) THEN4 PRINT*, "Suspenso"5 ELSEIF ((nota>=5) .AND. (nota<7)) THEN

6 PRINT*, "Aprobado"7 ELSEIF ((nota>=7) .AND. (nota<9)) THEN8 PRINT*, "Notable"

9 ELSEIF ((nota>=9) .AND. (nota<10)) THEN10 PRINT*, "Sobresaliente"11 ELSE

12 PRINT*, "Matrícula de honor"13 ENDIF

Supongamos quenota 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 siguienteELSEIF y hay que comprobar si((8>=0).AND.(8<5)).

Como es falso, entonces pasamos al siguienteELSEIF y hay que comprobar si((8>=5).AND.(8<7)).

Como es falso, entonces pasamos al siguienteELSEIF 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 primerELSEIF no es necesaria ya que sillegamos 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 lanota es mayor o igual que cero. Lo mismo ocurre en los otrosELSEIF. Por lo tanto,esta solución está evaluando algunas subexpresiones que noson necesarias.

Solución B

A continuación se propone una versión mejorada de esta multicondicional en la que sehacen menos comparaciones en las condiciones lógicas.

1 IF ((nota<0).OR.(nota>10)) THEN2 PRINT*, "Nota incorrecta"3 ELSEIF (nota<5) THEN

4 PRINT*, "Suspenso"5 ELSEIF (nota<7) THEN6 PRINT*, "Aprobado"

7 ELSEIF (nota<9) THEN8 PRINT*, "Notable"

Page 9: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 137

9 ELSEIF (nota<10) THEN10 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 multicondicionalya que deberían ser mutuamente excluyentes. Este hecho no escomprobado por el compiladorpor lo que en algún caso podríamos estar cometiendo algún tipo de error o simplementehaciendo nuestro programa poco eficiente.

Ejemplo

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

1 IF (Cond1) THEN

2 IF ((Cond2) .AND. (Cond3)) THEN3 Bloque_14 ELSE

5 IF (Cond4) THEN6 Bloque_27 END IF

8 Bloque_39 END IF

10 ELSE

11 Bloque_412 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 delejemplo 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:

Page 10: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

138 4.2. LA ESTRUCTURA MULTICONDICIONAL

1 IF (.NOT.(Cond1)) THEN2 Bloque_43 END IF

4 IF ((Cond1) .AND. .NOT.(Cond2) .AND. .NOT.(Cond4)) THEN5 Bloque_36 END IF

7 IF ((Cond1) .AND. .NOT.(Cond2) .AND. (Cond4)) THEN8 Bloque_29 Bloque_3

10 END IF11 IF ((Cond1) .AND. (Cond2) .AND. (Cond3)) THEN12 Bloque_1

13 END IF14 IF ((Cond1) .AND. (Cond2) .AND. .NOT.(Cond3) .AND. .NOT.(Cond4)) THEN15 Bloque_3

16 END IF17 IF ((Cond1) .AND. (Cond2) .AND. .NOT.(Cond3) .AND. (Cond4)) THEN18 Bloque_219 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 (ydifíciles de comprender)que la estructura multicondicional. Al ser todas las condicionales ejecutadas de formasecuencial una tras otra, es necesario que las condiciones de cada una de ellas seanmutuamente excluyentes. Es la única forma de asegurarse de que en caso de entrar enuna 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 resultacómodo usar esta estructura, aunque su uso está limitado sólo a algunos tipos de formasmulticondicionales.

El organigrama lo podemos ver en la figura 4.4.

La sintaxis5 de esta estructura es:

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

Page 11: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 139

Fal

soF

also

Cierto

expr==selector1

expr==selector2

Bloque1

Bloque2

...

Cierto

expr==selectorNCierto

BloqueN

Fal

so

BloqueDef

END SELECT

SELECT CASE (expr)

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; dependiendode con cual de ellos coincida,ejecutaremos un bloque u otro de código. Esta comparación seva haciendo en orden has-ta que encuentra coincidencia entre el valor de la expresióny alguno de los selectores. Enese 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

Page 12: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

140 4.2. LA ESTRUCTURA MULTICONDICIONAL

DEFAULT. Hay algunas cosas que hemos de tener en cuenta cuando usemosesta 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 únicovalor. Por ejemplo(3).

• Variosvalores separados por comas. Por ejemplo(2,3,4,7,9). En este caso secompara la expresión con todos ellos y si coincide con algunose ejecuta el bloquede ese selector.

• Un rangode 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. Siomitimos el final y por ejemplo ponemos(3:) queremos decir que compare conlos números 3, 4, 5, ..., es decir con todos los números mayores o iguales que3. Si omitimos el comienzo, y por ejemplo ponemos(:5) queremos indicar quecompare 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 circunstanciaen tiempo de compilación).

El selectorDEFAULT 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 anidadaIF-THEN-ELSEo bien por unaestructuraIF-THEN-ELSEIF. En cambio, una estructuraIF-THEN-ELSE(u otra variante) nosiempre podrá ser sustituida por una multicondicionalSELECT-CASEya que en esta losselectores sólo pueden incluir constantes.

Ejemplo

Implementar un programa que, dado un número entero x, imprima un mensaje de textoen 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.

Page 13: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

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 selectorDEFAULT ya que tenemos cubiertas todaslas posibilidades. De todas formas el último selectorCASE (11:) lo podríamos habersustituido por unCASE DEFAULT ya que si llegamos a ese punto tenemos garantizadoque el número almacenado enx es mayor o igual que11.

Ejemplo

Vamos a plantearnos la posibilidad de escribir un programa para gestionar una pequeñabase de datos con los alumnos de una asignatura. Una de las tareas que hemos de haceres preparar un menú de opciones a través del cual preguntemosal usuario qué tipode 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 opcionesen pantalla, permita seleccionar una de ellas, y ejecute la acción asociada a la opciónelegida. 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 unaopción. No entraremos al detalle de realizar cada una de esastareas.

Análisis

Lo primero de todo es realizar el correspondiente análisis del problema. En este casocomenzaremos 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 nuestroprograma es la opciónque elige el usuario. ¿Qué tipo de dato es? Esto dependerá de cómo queramos hacer elmenú; una alternativa bastante usual es asignar un número a cada una de las opcionesdel menú de forma que para seleccionar una de ellas bastará con introducir el número

Page 14: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

142 4.2. LA ESTRUCTURA MULTICONDICIONAL

correspondiente. Es decir si, por ejemplo, asociamos el número 1 a la opción que nospermite 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 tenerun listado de los datos. Si optamos por este método, entoncesla variable que almace-nará la opción elegida por el usuario puede ser de tipo entero. ¿Qué rango de valoreses 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. Puestoque 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 dejaremosindicadas las operaciones que habría que realizar para cadaopció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ásadelante) vamos a definir como constantes el número de opciones y los mensajes queaparecerán por pantalla para cada opción.

El programa sería este:

1 PROGRAM Menu !### ejselect.f90 ###2 IMPLICIT NONE3 ! Implementación de un Menú de opciones

4 ! Declaración de constantes5 ! Vamos a definir como constantes el número de opciones que

6 ! tendrá nuestro menú y el nombre de cada opción7 INTEGER, PARAMETER :: NumeroOpc=58 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 variables15 INTEGER :: op ! Esta variable servirá para leer la opción

Page 15: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 143

Fal

so

CiertoBuscar alumno ...

SELECT CASE (opcion)

opcion==2

Fal

so

Borrar un alumno ...Cierto

opcion==4

Fal

so

Anadir nuevo alumno ...Cierto

opcion==3

Fal

so

Finalizar ...Cierto

opcion==5

Opcion incorrecta ...

Fal

so

Listar alumnos ...Cierto

opcion==1

END SELECT

Fin

Inicio

Mostrar Menu

Leer opcion

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

16 ! Mostrar menú en pantalla

17 PRINT*, opc118 PRINT*, opc2

Page 16: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

144 4.2. LA ESTRUCTURA MULTICONDICIONAL

19 PRINT*, opc320 PRINT*, opc421 PRINT*, opc5

22 ! Leer opción por teclado23 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 DEFAULT38 PRINT*, "Te has equivocado"

39 END SELECT

40 END

Page 17: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

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

Page 18: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

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 reservadasTHEN ni ENDIF.

La parteELSE y la parteDEFAULT son opcionales.

EnSELECT-CASE: la expresión ha de devolver un dato de tipo entero, caráctero lógico.

En SELECT-CASE: los selectores han de ser mutuamente excluyentes y pueden estarformados por:

• Valores individuales.

• Varios valores (separados por comas).

• Rangos de valores (usando dos puntos:).

• Mezcla de valores y rangos de valores.

Page 19: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 147

4.4. Ejercicios

1. Supongamos queA, B, C y D son variables enteras y queBloque1, Bloque2, Bloque3y 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))) THEN2 Bloque13 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) THEN2 IF (B<=C) THEN

3 IF (C/=D) THEN4 Bloque15 ELSE

6 Bloque27 ENDIF8 ELSE

9 Bloque310 ENDIF11 ELSE12 Bloque4

13 ENDIF

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

3. Calcula las soluciones de una ecuación de segundo grado teniendo en cuenta todas lasposibles 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 deentrada y a qué escala la queremos convertir. Para ello sabemos que:

K = C + 273,15

R= F + 459,67

C = 5(F−32)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 calcularsu sueldo mensual:

Page 20: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

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 suponesumar al sueldo normal (con incremento) el salario base de unmes (sin incremento).

El programa imprimirá el nombre y las iniciales de los apellidos junto con el sueldobruto y neto de un mes normal, el sueldo bruto y neto de un mes depaga extra y elsueldo bruto y neto totales anuales.

Por ejemplo, un empleado con una antigüedad de 4 años y un sueldo base de 1000 euroscobrará un mes normal 1100 euros brutos. Descontando de ahí 55 euros de seguridadsocial y 132 de IRPF nos queda que el sueldo neto es de 913 eurosmensuales. Losmeses de paga extra cobrará 2100 euros brutos y 1743 euros netos. El sueldo brutoanual 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 delas 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 los30 años y cuyo sueldo esté entre 1200 y 2000 euros/mes.

Es posible que una persona no entre dentro de ninguna de estascategorías. En tal casoimprime 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 nodentro del círculo.

8. Haz un programa que lea las coordenadas que definen un rectángulo (esquina superiory esquina inferior opuesta) y las coordenadas de un punto en el espacio. El programadeberá 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 divideo no al segundo.

Page 21: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 149

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

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

a) Si las tres cargas del camión van al mismo barrio se aplica un30 % de descuentoa cada carga.

b) Si dos cargas van al mismo barrio se les aplica un 15 % de descuento (sólo a esasdos).

Haz un programa que reciba como entrada los códigos de los barrios a los que van lastres cargas de un viaje y que nos diga la cantidad que hay que pagar por cada carga. Latasa ú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 unnombre de una fruta desconocida se mostrará un mensaje adecuado.

13. Realizar un programa que lea un año por teclado y diga si eso no bisiesto (divisiblepor 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 tieneese mes.

15. Hacer un programa que lea las coordenadas de tres puntos yque diga si forman o noun 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 costede la caja es 0.02 euros porcm2 de cartón. Si hay N pares de zapatos dispuestos paraser embalados, y cada caja tiene una superficie de Mcm2, realizar un algoritmo quecalcule el gasto de la fabrica en las cajas y el precio de ventade los zapatos a partir delcosto (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 billetesen 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 7añ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.

6Si llamamos a los puntos A, B y C sabremos que forman un triángulo si la mayor de las distancias AB, AC, BCes menor que la suma de las otras dos. Además, el triángulo será equilátero si las tres distancias son iguales. Tambiénpodemos decir que los tres puntos forman un triángulo si no están alineados.

Page 22: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

150 4.5. SOLUCIONES

Haz un programa que reciba como entrada el precio de un billete y que le pregunte alusuario los datos necesarios para averiguar que descuento le corresponde. El programanos dirá que porcentaje de descuento se aplica y el precio rebajado. Ten en cuenta quesiempre se aplicará el descuento más beneficioso para el usuario y que los descuentosno 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) THEN3 IF (B>=D) THEN4 Bloque1

5 ENDIF6 ENDIF7 ENDIF

b) La solución al segundo apartado es:

1 IF ((A>B) .AND. (B<=C) .AND. (C/=D)) THEN

2 Bloque13 ENDIF4 IF ((A>B) .AND. (B<=C) .AND. (C==D)) THEN

5 Bloque26 ENDIF7 IF ((A>B) .AND. (B>C)) THEN

8 Bloque39 ENDIF

10 IF (A<=B) THEN

11 Bloque412 ENDIF

Ejercicio 2

Necesitamos tres variables enteras para almacenar los tresdatos de entrada. Podríamosdeclarar una cuarta variable para almacenar el dato de salida (que podría ser entero oreal dependiendo del caso) pero nos la vamos a ahorrar de forma que escribiremos laexpresión que hace el cálculo del resultado directamente enla instrucciónPRINT desalida 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 queparece que la estructura se ajusta a una condicional doble.

La solución sería la siguiente:

Page 23: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

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 resultado8 IF (b<0) THEN9 PRINT*, "El producto es: ", a*b*c

10 ELSE11 PRINT*, "La media es: ", (a+b+c)/3.012 ENDIF

13 END PROGRAM TresNumeros

Observa que para el cálculo de la media hemos dividido por el número real 3.0. De estaforma forzamos la promoción del numerador a representaciónreal 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 cuantoa los datos de salida, estos pueden variar en función del tipode ecuación que formenlos coeficientes: podemos tener una solución, dos soluciones, ninguna solución realo infinitas soluciones. Puesto que hasta que no empezamos a hacer los cálculos nosabemos qué solución debemos dar, podríamos pensar en ir escribiendo instruccionesPRINT 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 llamaremosx1).

Si a/=0 y el discriminante es negativo entonces no hay soluciones reales.

Si a/=0 y el discriminante es positivo entonces hay dos solucionesx1 y x2.

Si a/=0 y el discriminante es cero entonces hay una soluciónx1.

Page 24: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

152 4.5. SOLUCIONES

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

Si a==0 y b==0 entonces escribimos un mensaje diciendo que cualquier x essolución de la ecuación.

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

...

Es decir, hemos de escribir una estructura de condicionalesanáloga a la anterior. Paraevitar repetir esta estructura podemos usar una variable adicional (tiposolucion) quealmacene 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 enx1.

tiposolucion=2 si las dos soluciones están enx1 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-datiposolucion el valor que le corresponde para después consultarlo y mostrar elmensaje de salida adecuado.

1 PROGRAM Ecuacion2G !### ecu2g.f90 ###2 IMPLICIT NONE

3 REAL :: a,b,c,x1,x2,disc4 INTEGER :: tiposolucion

5 ! Leemos coeficientes6 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 almacenar10 ! el tipo de solución que hemos encontrado:11 ! 0 -> No hay soluciones reales

12 ! 1 -> Hay una solución real13 ! 2 -> Hay dos soluciones reales14 ! 3 -> Hay infinitas soluciones reales

15 IF (a==0) THEN16 IF (b==0) THEN17 tiposolucion = 3 ! Infinitas soluciones

18 ELSE19 tiposolucion = 1 ! Unica solución real20 x1 = -c / b

21 ENDIF22 ELSE

Page 25: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 153

23 disc = b**2 - 4*a*c ! El discriminante24 IF (disc<0) THEN25 tiposolucion = 0 ! No hay soluciones reales

26 ELSE IF (disc>0) THEN27 tiposolucion = 2 ! Tenemos 2 soluciones reales28 x1 = (-b + SQRT(disc)) / (2*a)

29 x2 = (-b - SQRT(disc)) / (2*a)30 ELSE31 tiposolucion = 1 ! Única solución real

32 x1 = -b / (2*a)33 ENDIF34 ENDIF

35 ! Imprimimos los resultados36 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=",x243 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 elsalario base (real).

Hemos optado por calcular primero todos los porcentajes quese 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 loque valgan en concreto dichos porcentajes.

1 PROGRAM Sueldo !### sueldo.f90 ###2 IMPLICIT NONE

3 ! Declaración de variables de entrada4 CHARACTER (LEN=50) :: nombre, apellidos ! Nombre y apellidos

5 INTEGER :: antiguedad ! Antigüedad en la empresa6 REAL :: salario_base ! Salario base de cálculo

7 ! Otras variables8 REAL :: incremento ! Incremento de sueldo por antigüedad

Page 26: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

154 4.5. SOLUCIONES

9 REAL :: retencion_ss, retencion_irpf ! Retenciones del sueldo10 REAL :: sueldo_bruto_mes, sueldo_neto_mes ! Sueldo bruto/neto al mes11 REAL :: sueldo_extra_bruto, sueldo_extra_neto ! Sueldo con paga extra

12 REAL :: sueldo_bruto_anual, sueldo_neto_anual ! Sueldo anual13 CHARACTER :: inicial1, inicial2 ! Iniciales de cada apellido14 INTEGER :: pos2 ! Para calcular la posición de inicio del 2o apellido

15 ! Lectura de datos desde teclado16 PRINT*, "Dime el nombre del empleado"

17 READ*, nombre18 PRINT*, "Dime los dos apellidos del empleado" ! Suponemos 2 apellidos19 READ*, apellidos

20 PRINT*, "¿Cuántos años lleva en la empresa?"21 READ*, antiguedad22 PRINT*, "¿Cuál es el salario base?"

23 READ*, salario_base

24 IF ((antiguedad<0) .OR. (salario_base<0)) THEN25 PRINT*, "Los datos de entrada son incorrectos"

26 ELSE27 ! Calculamos el factor de incremento de sueldo por antigüedad28 IF (antiguedad<3) THEN

29 incremento = 0.0530 ELSE IF (antiguedad<5) THEN31 incremento = 0.10

32 ELSE IF (antiguedad<8) THEN33 incremento = 0.1534 ELSE

35 incremento = 0.2036 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 mensual40 IF (sueldo_bruto_mes<900) THEN41 retencion_ss = 0.05

42 retencion_irpf = 0.1043 ELSE IF (sueldo_bruto_mes<1300) THEN44 retencion_ss = 0.05

45 retencion_irpf = 0.1246 ELSE IF (sueldo_bruto_mes<1800) THEN47 retencion_ss = 0.7

48 retencion_irpf = 0.1549 ELSE50 retencion_ss = 0.08

51 retencion_irpf = 0.1852 ENDIF

Page 27: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

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*262 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 la67 ! posición donde se encuentre el primer espacio en blanco en la

68 ! cadena apellidos. La inicial será, previsiblemente, el carácter69 ! que viene a continuación. Si, por ejemplo, usamos varios70 ! 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))) THEN75 ! En el caso de que no haya segundo apellido

76 inicial2 = " "77 ELSE78 inicial2 = apellidos(pos2+1:pos2+1)

79 ENDIF

80 ! Mostramos datos:

81 IF (inicial2==" ") THEN82 PRINT*, "Trabajador: ", inicial1, "., ",TRIM(nombre)83 ELSE

84 PRINT*,"Trabajador: ", inicial1, ". ", inicial2, "., ", &85 & TRIM(nombre)86 ENDIF

87 PRINT*, "Sueldo bruto mensual = ", sueldo_bruto_mes88 PRINT*, "Sueldo neto mensual = ", sueldo_neto_mes

89 PRINT*, "Sueldo bruto paga extra = ", sueldo_extra_bruto90 PRINT*, "Sueldo neto paga extra = ", sueldo_extra_neto91 PRINT*, "Sueldo bruto anual = ", sueldo_bruto_anual

92 PRINT*, "Sueldo neto anual = ", sueldo_neto_anual93 ENDIF

Page 28: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

156 4.5. SOLUCIONES

94 END PROGRAM Sueldo

Ejercicio 6

Los datos de entrada al problema serían: el nombre (cadena decaracteres), el sueldo(número entero), la edad (entero) y el sexo (un carácter:M o F). Observa que en la etapade petición de datos no se hace ninguna comprobación sobre lavalidez de los mismos(que el sueldo sea positivo, que el sexo sea M o F, que la edad sea positiva, etc.). Traspedir los datos de entrada, comprobaremos cuál de las condiciones del enunciado es laque se cumple y codificaremos en una variable (tipo) el resultado. En la variabletipopondremos 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 losdatos de salida con una multicondicional de tipoSELECT CASE.

Observa que al escribir el nombre en pantalla hacemos uso de la funciónTRIM paraevitar 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) :: nombre4 INTEGER :: sueldo, edad5 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*, edad12 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 clasificar18 ! 1 -> Hombre pobre

19 ! 2 -> Mujer rica20 ! 3 -> Joven mujer de clase media

Page 29: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 157

21 tipo=022 IF ((sexo==’M’) .OR. (sexo==’m’)) THEN23 IF (sueldo<500) tipo=1

24 ELSE25 IF (sueldo>6000) THEN26 tipo=2

27 ELSE IF ((edad>=20) .AND. (edad<=30) .AND. (sueldo>=1200) &28 & .AND. (sueldo<=2000)) THEN29 tipo=3

30 ENDIF31 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 coordenadasdel punto. Las coorde-nadas del centro y del punto se pueden almacenar en cuatro variables de tipo real peroen este caso vamos a definir un nuevo tipo de dato para almacenarlas. Ese nuevo tipoconstará de dos campos: uno para las ordenadas y otro para lasabscisas.

La forma de resolver el problema es calcular la distancia desde el centro del círculo alpunto 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 Punto5 REAL :: x,y6 END TYPE

7 TYPE (Punto) :: centro, p ! Definimos dos variables de tipo Punto8 REAL :: radio, dist

9 ! Leemos datos de entrada

Page 30: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

158 4.5. SOLUCIONES

10 PRINT*, "Dime las coordenadas del centro del círculo"11 READ*, centro12 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) THEN20 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 ELSE24 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 unnuevo tipo de objetos en el programa (coordenadas 2D). El usode nuevos tipos de datossimplifica la escritura de los programas y los hace más comprensibles, sobre todo si songrandes. En este programa en lugar de haber definido cuatro variables reales para lascoordenadas del centro y del punto, únicamente hemos definido dos variables del nuevotipo de datoPunto.

Ejercicio 9

Como datos de entrada tenemos dos números enteros (m y n). El dato de salida será unmensaje en pantalla indicando sim es divisible porn.

Para comprobar si un númerom es divisible por otron vamos a comprobar si el restode la división entera del primero por el segundo es cero. En caso afirmativo podremosdecir quen divide am. Para el cálculo del resto de una división entera usaremos lafunción intrínsecaMOD.

Equivalentemente, podemos sustituir la funciónMOD por la expresiónm-(m/n)*n. Eneste caso, al tratarse de variables enteras, la divisiónm/n obtendría el cociente de ladivisión entera (sin decimales).

1 PROGRAM DivideNum !### ndivm.f90 ###2 IMPLICIT NONE

3 INTEGER :: n, m

Page 31: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 159

4 ! Preguntamos por los números5 PRINT*, "Dime dos números enteros"6 READ*, n, m

7 ! Comprobamos si n divide a m8 IF (MOD(m,n)==0) THEN

9 PRINT*, n, " divide a ", m10 ELSE11 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 delnombre del mes más largo que podamos tener (Septiembre con diez caracteres).

En este programa hemos de cuidar la escritura de mayúsculas yminúsculas en el nom-bre de los meses cuando lo ejecutemos ya que si, por ejemplo, escribimos el nombretodo en minúsculas o todo en mayúsculas nos diría que no es reconocido. La forma deescribir los meses será: la primera letra mayúscula y el resto minúsculas (tal como sehan escrito en la multicondicionalSELECT 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

Page 32: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

160 4.5. SOLUCIONES

Ejercicio 15

Para almacenar las coordenadas de los tres puntos de entradausaremos un nuevo tipode dato de forma análoga a como hicimos en el ejercicio 7. Los pasos a seguir son lossiguientes:

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

b) Calculamos la longitud de los tres ladosAB, 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 silos tres puntos forman un triángulo o no. En el caso de que lo formen, tambiéncomprobaremos si es equilátero.

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

2 IMPLICIT NONE

3 TYPE Punto2D

4 REAL :: x, y5 END TYPE Punto2D

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

8 ! Leemos datos9 PRINT*, "Dame las coordenadas (x,y) del punto A:"

10 READ*, a

11 PRINT*, "Dame las coordenadas (x,y) del punto B:"12 READ*, b13 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 LadoMayor20 ! 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) THEN25 LadoMayor = AB

Page 33: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

4. LA ESTRUCTURA CONDICIONAL 161

26 ELSE27 LadoMayor = BC28 ENDIF

29 ELSE30 IF (AC>BC) THEN31 LadoMayor = AC

32 ELSE33 LadoMayor = BC34 ENDIF

35 ENDIF

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

37 ! dos en SumaOtros38 IF (LadoMayor==AB) THEN39 SumaOtros = AC+BC

40 ELSE IF (LadoMayor==AC) THEN41 SumaOtros = AB+BC42 ELSE43 SumaOtros = AB+AC

44 ENDIF

45 ! Comprobamos si forman o no un triángulo

46 IF (LadoMayor<SumaOtros) THEN47 PRINT*, "Los puntos sí forman un triángulo"48 ! Comprobamos si es equilátero

49 IF ((AB==AC) .AND. (AB==BC)) THEN50 PRINT*, "El triángulo es equilátero"51 ELSE

52 PRINT*, "El triángulo no es equilátero"53 ENDIF54 ELSE

55 PRINT*, "Los puntos no forman un triángulo"56 ENDIF

57 END

Page 34: CAPÍTULO - UGRdecsai.ugr.es/fipi/fortran/doc/f90.condicional.pdf · 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

162 4.5. SOLUCIONES