Story Transcript
CAPÍTULO
4 La estructura condicional
Hasta ahora hemos visto cómo resolver problemas muy simples. En este capítulo se introduce 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 secció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 sistema 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 estructura 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 estructura 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 palabras 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 falsedad 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 BloqueInst 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
Falsa
Condición
Verdadera
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 () THEN ENDIF
Ejemplo 1 2 3
IF (x.GT.4) THEN y=6 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 2 3 4
IF (i/=0 .AND. j>=9) THEN h=1/(2*j+3) k=-h*20 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á compuesta 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 2 3
IF (MOD(x,2)==0) THEN PRINT*, "El número ",x," es par" 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 2 3
IF x.GT.4 THEN y=6 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.
´ IF logico (IF-THEN simplificado)
4.1.1.
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 ()
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 siguiente: 1 2
IF (MOD(x,2)==0) PRINT*, "El número ",x," es par" 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 verificar 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
BloqueV
Condición
Falsa
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 BloqueV 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 ejecució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 () THEN ELSE ENDIF
Ejemplo Reescribir la condicional que imprime un mensaje diciendo si un número es par o impar. 1 2 3 4 5
IF (MOD(x,2)==0) THEN PRINT*, x, " es par" ELSE PRINT*, x, " es impar" 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 almacenado en una variable x es mayor, menor o igual que 4. 1 2 3 4 5 6 7
3 El
IF (x>4) THEN PRINT*, x, " es mayor que 4" ELSE IF (x4) 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 () THEN ELSEIF () THEN ..... ELSEIF () THEN ELSE 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.
135
4. LA ESTRUCTURA CONDICIONAL
Verdadera
Bloque1
Condición1
Verdadera
Falsa
Condición2
Bloque2
Falsa
...
Verdadera
BloqueN
CondiciónN
Falsa
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 2 3 4 5 6 7
IF (x>4) THEN PRINT*, x, " es mayor que 4" ELSEIF (x.EQ.4) THEN PRINT*, x, " es igual que 4" ELSE PRINT*, x, " es menor que 4" 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 2 3 4 5 6 7 8 9 10 11 12 13
IF ((nota10)) THEN PRINT*, "Nota incorrecta" ELSEIF ((nota>=0) .AND. (nota=5) .AND. (nota=7) .AND. (nota=9) .AND. (nota=0).AND.(8=5).AND.(8=7).AND.(8=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, ((nota10)) 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 2 3 4 5 6 7 8
IF ((nota10)) THEN PRINT*, "Nota incorrecta" ELSEIF (nota