Hasta ahora, todas las sentencias que forman los programas se ejecutan. Sin embargo, hay ocasiones en que un determinado conjunto de sentencias se deben ejecutar slo si una determinada condicin es cierta y sino no. Los valores lgicos: constantes, variables y expresiones lgicas, permiten controlar la ejecucin de las sentencias de un programa. Hay dos tipos de expresiones lgicas: las expresiones lgicas relacionales y las expresiones lgicas combinacionales.
Las expresiones lgicas relacionales comparan los valores de dos expresiones aritmticas o dos expresiones de tipo carcter. La evaluacin de una expresin lgica relacional produce un resultado de tipo lgico: .TRUE. o .FALSE. La sintaxis de una expresin lgica de tipo relacional es:
operando1 OPERADOR_LGICO_RELACIONAL operando2 operando es una expresin, variable o constante aritmtica o de tipo carcter. OPERADOR_LGICO_RELACIONAL puede ser: SIGNIFICADO IGUAL DISTINTO MENOR QUE MENOR O IGUAL QUE MAYOR QUE MAYOR O IGUAL QUE
OPERADOR LGICO RELACIONAL F77 .EQ. .NE. .LT. .LE. .GT. .GE. F90/95 == /= < <= > >=
Los operadores lgicos relacionales de Fortran 77 han sobrevivido y funcionan en los compiladores actuales de Fortran 90/95. Por lo tanto, es interesante que el programador sepa reconocerlos en los programas, sin embargo, es preferible usar la forma de Fortran 90 en sus programas nuevos, que adems, es mucho ms intuitiva.
35
INTEGER :: i=3,j=5
La ltima expresin lgica relacional de la Tabla 2.2 es cierta porque los caracteres se evalan en orden alfabtico. Ms detalles en el captulo 6. Son invlidas las siguientes expresiones lgicas relacionales: Falta operando1 No se pueden comparar reales con caracteres.
<=5 8.44/='XYZ'
i=3 No es una expresin lgica relacional, sino una sentencia de asignacin! No confundir el operador lgico relacional de igualdad con el operador de asignacin.
La evaluacin de una expresin lgica combinacional produce un resultado de tipo lgico: .TRUE. o .FALSE. La sintaxis de una expresin lgica de tipo combinacional es:
operando1 OPERADOR_LGICO_COMBINACIONAL operando2 operando es una expresin relacional, variable lgica o constante lgica. Operando1 no existe cuando el operador lgico usado es unario. OPERADOR_LGICO_COMBINACIONAL puede ser: SIGNIFICADO ES LO OPUESTO A OPERANDO2 ES .TRUE. SI Y SLO SI OPERANDO1 Y OPERANDO2 SON .TRUE.
36
.OR.
BINARIO
.EQV.
ES .TRUE. SI Y SLO SI LOS DOS BINARIO OPERANDOS SON .TRUE. O LOS DOS OPERANDOS SON .FALSE. ES .TRUE. SI BINARIO OPERANDOS DISTINTOS Y SLO SI TIENEN LOS DOS VALORES
.NEQV.
Sean operando1 y operando2 A y B, respectivamente, la tabla de verdad de los operadores lgicos combinacionales es: A .TRUE. .TRUE. B .TRUE. .NOT.B A.AND.B A.OR.B .TRUE. .TRUE. .TRUE. A.EQV.B A.NEQV.B .TRUE. .FALSE. .FALSE. .FALSE. .TRUE. .TRUE. .FALSE.
.FALSE. .TRUE.
.FALSE. .TRUE.
.FALSE. .TRUE.
Tabla 2 .4: Tabla de verdad de los o pe rado r es lg icos com b ina c ionale s
Precedencia de los operadores lgicos combinacionales: OPERADOR(ES) PRECEDENCIA ( ) .NOT. .AND. .OR. .EQV. , .NEQV. MENOR MAYOR
Si una expresin lgica contiene dos o ms operadores de la misma precedencia se siguen las siguientes reglas:
37
Precedencia de los operadores aritmticos, lgicos relacionales y lgicos combinacionales: OPERACIN PRIORIDAD
OPERADORES ARITMTICOS ** *, / + , 1 2 3
variable_lgica = expresin_lgica variable_lgica es el nombre de una variable, o elemento de matriz, declarada en el programa del tipo LOGICAL. expresin_lgica es una expresin lgica Fortran vlida. Se evala la expresin_lgica. Se asigna el valor obtenido a la variable_lgica.
El funcionamiento es:
Ej:
2.6 Bloque IF
Permite que un bloque de sentencias (puede ser slo una) sea ejecutado si y slo si el valor de una expresin lgica es cierta. Si la expresin lgica es falsa se salta ese bloque de sentencias y se ejecuta la primera sentencia ejecutable por debajo de END IF. bloque de sentencias
ENDIF marca la terminacin de la sentencia bloque IF. El bloque de sentencias suele dentarse por dos o ms espacios para facilitar la lectura del bloque IF, aunque no es obligatorio hacerlo. La estructura del bloque IF puede ser ms complicada. A veces, se quiere ejecutar un bloque de sentencias si una expresin lgica es cierta y diferentes bloques de sentencias si otras condiciones son ciertas. Por ejemplo: bloque de sentencias 1
IF (expresin lgica 1) THEN ELSE IF (expresin lgica 2) THEN bloque de sentencias 2] ELSE bloque de sentencias 3 END IF
Si la expresin lgica 1 es cierta se ejecuta el bloque de sentencias 1 y se salta el resto de bloques hasta la primera sentencia ejecutable por debajo de END IF. Si la expresin lgica 1 es falsa se salta el bloque de sentencias 1, se evala la expresin lgica 2 y si es cierta se ejecuta el bloque de sentencias 2 y se salta hasta la primera sentencia ejecutable por debajo de END IF. Si ambas expresiones lgicas son falsas, el programa ejecuta el bloque de sentencias 3. En general, un bloque IF puede contener opcionalmente cualquier nmero de subbloques ELSE IF (0, 1, 2, 3,), pero slo puede contener un subbloque ELSE. La sintaxis general de un bloque IF es: bloque de sentencias 1
39
La expresin lgica de una clusula es evaluada slo si las expresiones lgicas de todas las clusulas precedentes han sido falsas. Cuando la prueba de una expresin lgica es cierta se ejecuta el bloque de sentencias correspondiente y se salta a la primera sentencia ejecutable por debajo de END IF. Cuando el bloque IF no incluye la clusula ELSE, puede ocurrir que ninguna de las expresiones lgicas sean ciertas y que, por lo tanto, no se ejecute ninguno de los bloques de sentencias dados.
Es posible asignar un nombre a un bloque IF. La sintaxis general de un bloque IF con nombre es: bloque de sentencias 1
[nombre:] IF (expresin lgica 1) THEN [ELSE IF (expresin lgica 2) THEN [nombre] bloque de sentencias 2] [ELSE [nombre] bloque de sentencias n] END IF [nombre]
nombre es cualquier identificador vlido. Es recomendable usar nombres en los bloque IF largos y complicados. Por un lado, el programador estructura mejor los programas y, por otro, el compilador encuentra errores en su cdigo de forma ms precisa. Adems, los bloques IF pueden estar anidados. Dos bloques IF se dice que estn anidados cuando uno de ellos se encuentra dentro de otro. En este caso, cada uno de los bloques IF requerir su propia sentencia ENDIF. bloque de sentencias 1 [nombre_interno:]IF (expresin lgica 2) THEN bloque de sentencias 2 END IF [nombre_interno]
END IF [nombre_externo] 40
2.9 IF lgico
La sentencia IF lgica es el caso particular ms simple del bloque IF. La sentencia IF lgica evala una expresin lgica y ejecuta una sentencia si dicha expresin es cierta. sentencia es cualquier sentencia ejecutable excepto DO, END, bloque IF u otra sentencia IF lgica. Si el valor de la expresin lgica es .TRUE., se ejecuta la sentencia. Si es .FALSE. se salta esa sentencia y se pasa el control a la sentencia siguiente. Ej:
41
El bloque SELECT CASE aparece en Fortran 90/95 como otra forma de controlar la ejecucin de determinados bloques de sentencias junto con el bloque IF. Su sintaxis general es:
[nombre:] SELECT CASE (expresin caso) CASE (selector de caso 1) [nombre] bloque de sentencias 1 [CASE (selector de caso 2) [nombre] bloque de sentencias 2] [CASE DEFAULT [nombre] bloque de sentencias n] END SELECT [nombre]
El bloque SELECT CASE ejecuta un bloque determinado de sentencias cuando el valor de la expresin caso coincide o pertenece al rango dado de su correspondiente selector de caso. Opcionalmente puede existir un CASE DEFAULT en un bloque SELECT CASE. El bloque de sentencias de este caso por defecto se ejecuta cuando el valor de la expresin caso no coincide con ningn selector de caso. expresin caso es una expresin entera, lgica o de caracteres. Selector de caso es una lista de uno o ms valores posibles del mismo tipo que la expresin caso. Cada selector de caso debe ser mutuamente excluyente. Los valores pueden escribirse como:
valor valormin: valormax : valormax valormin: o una combinacin de las formas anteriores separadas por comas.
Es recomendable poner nombre a un bloque SELECT CASE largo y complicado. Por un lado, el programador estructura mejor los programas y, por otro, el compilador encuentra errores en su cdigo de forma ms precisa.
Determinar si un nmero entero entre 1 y 10 es par o impar y visualizar un mensaje adecuado en consecuencia.
42
INTEGER :: valor parimpar: SELECT CASE (valor) CASE (1, 3, 5, 7, 9) WRITE (*,*) el valor es impar CASE (2, 4, 6, 8, 10) WRITE (*,*) el valor es par CASE (11:) WRITE (*,*) el valor es demasiado grande CASE DEFAULT WRITE (*,*) el valor es negativo o cero END SELECT parimpar
INTEGER :: temp friocalor: SELECT CASE (temp) CASE (:-1) WRITE (*,*) por debajo de 0 Celsius CASE (0) WRITE (*,*) Est helando CASE (1:10) WRITE (*,*) Hace fro CASE (11:20) WRITE (*,*) templado CASE (21:) WRITE (*,*) Hace calor END SELECT friocalor
43
EJERCICIOS RESUELTOS
Objetivos:
Aprender a ejecutar unas instrucciones u otras dependiendo de que se cumplan o no una serie de condiciones. Es decir, manejar los bloques IF simples y con anidamiento y los bloques SELECT CASE. Antes de abordar los primeros programas se muestran los organigramas que representan los algoritmos de los problemas planteados. Los problemas planteados usan expresiones lgicas en las que intervienen operadores lgicos relacionales y/o combinacionales.
45
F
N>0
PROGRA M c ap 2_1
R EAL : : nu m W R IT E( * ,* ) ' D A M E U N N U MER O' R EAD ( * ,*) n u m IF (num > 0) THEN W R IT E( * ,* ) ' E S P O S IT I V O ' ELSE WR ITE( *,*)' ES NEGATIVO O CERO' E N D IF E ND PROGRA M ca p2_ 1
46
N>0
VISUALIZAR N POSITIVO
C
N<0
VISUALIZA N NEG
VISUALIZA ES EL 0
PROGRA M c ap 2_2
R EAL : : nu m WR ITE ( * ,*) 'DA M E UN NU MERO' R EAD ( * ,*) n u m IF (num > 0) THEN W R IT E ( * , * ) ' E S P O S I T I VO ' ELSE IF (num < 0) THEN W R IT E ( * , * ) ' E S N EG A T I VO' ELSE W R IT E ( * , * ) ' E S EL 0 ' E N D IF E ND PROGRA M ca p2_ 2
47
ABS(argumento) es una funcin intrnseca que devuelve el valor absoluto del argumento escrito entre parntesis. Su tipo puede ser entero o real. Repite el ejercicio cambiando el orden de evaluacin de las expresiones lgicas relacionales.
4. Resolver una ecuacin de 2 grado con A, B y C cualquier valor.
48
WR ITE ( * ,*) ' IN TRODUC E A ,B ,C, CON A , B, C CUALQU IER VALOR ' R EA D ( * ,*) a , b ,c d= b* *2- 4* a* c
e c2: IF (a /= 0) TH EN
discriminante: IF (d == 0) THEN r1=-b/(2*a) r2=r1 W R IT E ( * , * ) ' S O L U C . R EALES DOB LES, R1=R 2=' ,r1,r2 E L S E IF( d > 0 ) T H EN d i s c r im in a n t e r1=(-b+ SQR T(d) )/(2*a) r2=(-b-SQR T(d) ) /(2*a) WR ITE ( * ,*) 'LA S RA IC ES DEL POLINOMIO SON:' WR IT E ( * ,*) 'R1=',r 1 ,'R2= ' ,r2 ELSE discriminante pr=-b/(2*a) p i= SQ R T ( A B S(d ) ) /( 2 * a ) W R IT E ( * ,*) ' S O L U C ION E S C O M PL EJ A S' W R IT E ( * ,*) ' PA R T E R EA L : ' ,p r W R IT E ( * ,*) ' PA R T E I M A G IN A R IA: ' , p i E N D IF d is cr i m in ante
E L S E IF ( b / = 0 ) T H EN e c 2 r= -c/b WR IT E (* ,*) ' SOLUC ION UN ICA , R=' ,r E L S E IF ( c / = 0 ) T H EN e c 2 WR ITE (*,*) ' ECUAC ION IMPOSIB LE' ELSE WR ITE (*,*) ' ECUAC ION IND ETER M INADA' END IF ec2 E ND PROGRA M ca p2_ 4
la
correspondiente
Suspenso Aprobado
49
7 Nota < 9
Notable
PROGRA M c ap 2_5
R EAL : : no ta WR IT E ( * ,*) 'DA M E UNA NO TA' R EAD ( * ,*) nota IF (nota < 0 .OR. nota > 10) THEN WR ITE ( *,*) 'NOTA INCORR ECTA ' E L S E IF ( n o t a < 5 ) T H EN W R IT E ( * , * ) ' SU SP EN SO ' E L S E IF ( n o t a < 7 ) T H EN WR ITE ( *,*) 'A PROBADO' E L S E IF ( n o t a < 9 ) T H EN W R IT E ( * , * ) ' N O T A B L E ' E L S E IF ( n o t a < 1 0 ) T H EN W R IT E ( * , * ) ' SO B R ES A L I EN T EE ' ELSE WR ITE ( *,*) 'MA TR ICU LA DE HON OR' E N D IF E ND PROGRA M ca p2_ 5
6. Realizar una operacin entre cuatro posibles segn se desee. El programa pide dos nmeros y una operacin visualizando el resultado de la misma.
PROGRA M c ap 2_6
R EA L : : a ,b , c CHARAC TER (LEN= 1) :: oper WR IT E ( * ,*) 'DA M E 2 NU MER O S ' R EAD ( * ,*) a , b WR IT E ( * ,*) 'DA M E UNA O PERAC ION (+ , - , * , /)' R EAD ( * ,*) o pe r IF (oper == '+ ') TH EN
50
En este ejercicio, OPER es el nombre que damos a la variable donde almacenamos el smbolo aritmtico de la operacin. La ltima expresin lgica evaluada requiere del operador lgico combinacional Y para evitar que el programa pueda dividir por cero y provoque un error en tiempo de ejecucin.
7. Comprobar si un nmero ledo por teclado pertenece al intervalo cerrado [0-10] o no. Escribir un mensaje por pantalla que informe de ello.
PROGRA M c ap 2_7
R EAL : : nu m WR ITE ( * ,*) 'DA M E UN NU MERO' R EAD ( * ,*) n u m IF (num >= 0 .AND. nu m <= 10) TH EN WR IT E ( *,* ) n um,' PERT EN ECE AL IN T ER VAL O [0-1 0]' ELSE W R IT E ( * , * ) n u m , ' N O P ER TENE C E A L INT ER VA L O [ 0 - 1 0 ] ' E N D IF E ND PROGRA M ca p2_ 7
51
PROGRA M c ap 2_8
INTEGER :: num WR IT E ( * ,*) 'DA M E UNA O PC ION' WR ITE ( * ,*) ' 1 PARA EJECU TAR BLOQU E 1' WR ITE ( * ,*) ' 2 PARA EJECU TAR BLOQU E 2' WR IT E ( * ,*) ' 3 PARA SAL IR ' R EAD ( * ,*) n u m S E L ECT C A S E ( n u m) CASE (1) WR ITE ( * ,*) ' SE HACE BLOQU E 1' CASE (2) WR ITE ( * ,*) ' SE HACE BLOQU E 2' CASE (3) WR IT E ( * ,*) 'AD IO S' CA S E D EFAU LT WR IT E ( * ,*) ' O PC ION INCORR ECTA ' E N D SEL EC T E ND PROGRA M ca p2_ 8
Cuando el valor de la variable entera num coincide con algn valor de CASE, el control del programa pasa a ejecutar el bloque de sentencias correspondiente. Si el valor de num no coincide con ningn valor de CASE, se ejecuta el CASE DEFAULT visualizando el mensaje OPCION INCORRECTA. Repite el ejercicio usando la estructura condicional IF y compara con la estructura SELECT CASE.
52
EJERCICIOS PROPUESTOS 1) Programa que acepte el nmero del ao, y muestre "PRESENTE" si el nmero es el ao actual, "PASADO" si es menor o "FUTURO" si es mayor. 2) Programa que pida un nmero natural y muestre si es par o impar. 3) Programa que pida una temperatura y su escala (Celsius/Fahrenheit) y muestre su valor en la otra escala (0 C=32 F y 100 C=212 F). 5 Ecuacin de conversin: C= (F 32) 9 4) Programa que acepte el nmero de un ao e indique si es bisiesto o no. Un ao es bisiesto si es mltiplo de cuatro, pero no de cien. Excepcin a la regla anterior son los mltiplos de cuatrocientos que siempre son bisiestos. Son bisiestos: 1600,1996, 2000, 2004. No son bisiestos: 1700, 1800, 1900, 1998, 2002. 5) Programa que pida la longitud de los lados de un tringulo, compruebe si los datos son correctos, muestre si es equiltero, issceles o escaleno, y el valor de sus ngulos en grados. A saber: los lados de un tringulo son correctos si cada uno de ellos es menor que la suma de los otros dos. Un tringulo es equiltero si sus tres lados son iguales, issceles si dos lados son iguales y escaleno si sus 3 lados son distintos. Teorema del coseno a 2 =b 2 +c 2 2bc cos(b,c). 6) Programa que pida coordenadas cartesianas de un punto e indique en qu cuadrante se encuentra dicho punto, en qu eje o si se trata del origen de coordenadas.
53