elementos de programación fortran

Upload: eternauta-dos-mil-uno

Post on 18-Jul-2015

135 views

Category:

Documents


0 download

DESCRIPTION

Facultad de Ciencias Astronómicas y Geofísicas - UNLP -Elementos de programación FortranPablo J. SantamaríaMarzo 2012 - Versión 0.1

TRANSCRIPT

Facultad de Ciencias Astronmicas y Geofsicas - UNLP -Elementos deprogramacin FortranPablo J. SantamaraMarzo 2012 - Versin 0.12012, Pablo J. Santamara.e-mail: [email protected]:http://gcp.fcaglp.unlp.edu.ar/integrantes:psantamaria:fortran:startLas imgenes que ilustran los captulos son dedominio pblico y fueron obtenidas en los sitioshttp://www.public-domain-image.com yhttp://www.publicdomainpictures.net.EstaobrasedistribuyebajounalicenciadeCreativeCommonsAtribucin-CompartirDerivadasIgual 3.0 Unported. Es decir,se permite compartir, copiar, distribuir, ejecutar ycomunicar pblicamente, hacer obras derivadas eincluso usos comerciales de esta obra, siempre que sereconozca expresamente la autora original y el trabajoderivado se distribuya bajo una licencia idntica a sta.PrefacioFortran es, desde sus inicios, el lenguaje de programacin ampliamente escogido en el mbito de lacomputacin cientca. El primer compilador Fortran data de 1957. Pero al igual que los lenguajes humanos,con el paso del tiempo un lenguaje de programacin va evolucionando adaptndose a las necesidades (y losofa)de la programacin de la poca. En el caso de Fortran, cada cierto perodo de tiempo un comit internacionalja la sintaxis y gramtica del lenguaje originando un estndar. Con un estndar del lenguaje a seguir, todoslos usuarios nos podemos asegurar que los programas funcionaran en cualquier computadora que tenga uncompilador Fortran que lo implemente. Tradicionalmente, los estndares de Fortran se denominan con la fechade su constitucin. El primer estndar fue Fortran 66, al cual le sigui el Fortran 77, el cual introdujo mejorassignicativas al lenguaje (y an hoy contina siendo utilizado en la comunidad cientca). Una mayor revisindel lenguaje fue el Fortran 90. El Fortran 90 contiene como caso particular al Fortran 77 pero va ms allincorporando muchas nuevas caractersticas. Una revisin menor del Fortran 90 condujo al estndar Fortran 95.Los estndars ms recientes, Fortran 2003 y 2008, introducen an ms nuevas caractersticas en el lenguaje.En esta gua trabajaremos con el estandar Fortran 95 y algunas extensiones del Fortran 2003 implementadasen el compilador gfortran, el compilador Fortran de la suite de compiladores GCC. Ms an asumiremosque el usuario acceder al mismo en una computadora personal ejecutando el sistema operativo y utilidadesde usuario GNU/Linux. Puesto que objetivo de esta gua es proporcionar una rpida introduccin al languajehaciendo nfasis en la escritura de cdigo bien estructurado y modular, muchas caractersticas obsoletas o norecomendadas proveniente de estndares previos no son siquiera nombradas. Asi mismo, el carcter introductoriode la gua, no nos permite tampoco extendernos a conceptos y caractersticas ms avanzadas introducidas en losltimos estndares. Sin embargo, espero que esta gua, con los conceptos presentados y sus ejercicios, sea deutilidad a aquellos que comienzan implementar algoritmos en Fortran.Pablo J. Santamara.Marzo 2012.iiindice general1. Primeros pasos 11.1. Primeros pasos en programacin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2. Cuando las cosas fallan. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.3. Estructura general de un programa Fortran. . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.3.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62. Tipos de datos simples 72.1. Tipos de datos simples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.1.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.2. Sentencias de asignacin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.2.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.3. Orden de precedencia de las operaciones aritmticas y conversin implcita de tipo. . . . . . . 122.3.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.4. Entrada y salida por lista. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.4.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.5. Implementando lo aprendido. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153. Estructuras de control 173.1. Estructuras de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.2. Estructura secuencial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.3. Estructura de seleccin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.3.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.4. Estructura de iteracin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.4.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.5. Implementando lo aprendido. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294. Modularizacin 334.1. Programacin modular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334.2. Funciones y subrutinas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.2.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394.3. Compilacin por separado de las unidades del programa. . . . . . . . . . . . . . . . . . . . . 404.4. Implementando lo aprendido. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.5. Subprogramas como argumentos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.5.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434.6. Modulos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434.6.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46vndice general5. Archivos 475.1. Entrada/salida por archivos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.1.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.2. Formatos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.2.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526. Arreglos 556.1. Datos compuestos indexados: arreglos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556.1.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596.2. Asignacion esttica y dinmica de memoria. . . . . . . . . . . . . . . . . . . . . . . . . . . . 596.3. Arreglos en subprogramas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616.3.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627. Precisin 657.1. Representacin de punto otante. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657.1.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687.2. Nmeros de punto otante de simple y doble precisin . . . . . . . . . . . . . . . . . . . . . 687.3. Implementacin en Fortran de los nmeros de punto otante de simple y doble precisin. . . . 687.3.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707.4. Nmeros especiales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707.4.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72viCaptulo 1Primeros pasosHay dos formas de escribir programas sin errores.Slo la tercera funciona.1.1. Primeros pasos en programacin.La resolucin de un problema cientco con una computadora, tarde o temprano, conduce a la escritura de unprograma que implemente la solucin del problema. Un programa es un conjunto de instrucciones, ejecutablessobre una computadora, que permite cumplir una funcin especca. Ahora bien, la creacin del programa nocomienza directamente en la computadora! El proceso comienza en papel diseando un algoritmo para resolverel problema. Un algoritmo es un conjunto de pasos (o instrucciones) precisos, denidos y nitos que a partir deciertos datos conducen al resultado del problema.Caractersticas de un algoritmo.preciso: el orden de realizacin de cada paso est especicado,denido: cada paso est especicado sin ambigedad,nito: el resultado se obtiene en un nmero nito de pasos.entrada/salida: dispone de cero o ms datos de entrada y devuelve uno o ms resultados.1Captulo 1. Primeros pasosInicioLeer radio = 3.141593area = radio2Imprimir areaFinFigura 1.1. Diagrama de ujo para el algoritmo que calcula el rea de un crculo.Para describir un algoritmo utilizaremos un pseudocdigo. Un pseudocdigo es un lenguaje de especicacinde algoritmos donde las instrucciones a seguir se especican de forma similar a como las describiramos connuestras palabras.Consideremos, como ejemplo, el diseo de un algoritmo para calcular el rea de un crculo. Nuestro primerintento, bruto pero honesto, es:Calcular el rea de un crculo.Sin embargo, este procedimiento no es un algoritmo, por cuanto no se especica, como dato de entrada, cul esel crculo a considerar ni tampoco cual es el resultado. Un mejor procedimiento sera:Leer el radio del crculo.Calcular el rea del crculo de radio dado.Imprimir el rea.Sin embargo, ste procedimiento an no es un algoritmo por cuanto la segunda instruccin no especica cmose calcula el rea de un crculo de radio dado. Explicitando la frmula matemtica tenemos nalmente unalgoritmo apropiado:Leer el radio del crculo.Tomar = 3.141593.Calcular rea = radio2.Imprimir el rea.Una manera complementaria de describir un algoritmo es realizar una representacin grca del mismoconocida como diagrama de ujo. El correspondiente diagrama de ujo para el algoritmo anterior se ilustra enla gura 1.1.Una vez que disponemos del algoritmo apropiado, su implementacin en la computadora requiere de unlenguaje de programacin. Un lenguaje de programacin es un lenguaje utilizado para escribir programas decomputadora. Como todo lenguaje, cada lenguaje de programacin tiene una sintaxis y gramtica particularque debemos aprender para poder utilizarlo. Por otra parte, si bien existen muchos lenguajes de programacin21.1. Primeros pasos en programacin.para escoger, un lenguaje adecuado para problemas cientcos es el denominado lenguaje Fortran1. El procesode implementar un algoritmo en un lenguaje de programacin es llamado codicacin y su resultado cdigo oprograma fuente. Siguiendo con nuestro ejemplo, la codicacin del algoritmo en el lenguaje Fortran conduceal siguiente programa:Cdigo 1.1. Clculo del rea de un crculoPROGRAM calcular_area! -------------------------------------------------! Clculo del rea de un crculo de radio dado! -------------------------------------------------! Declaracin de variables! -------------------------------------------------IMPLICIT NONEREAL :: radio ! radio del crculoREAL :: area ! rea del crculoREAL, PARAMETER :: PI = 3.141593 ! nmero pi! -------------------------------------------------! Entrada de datos! -------------------------------------------------WRITE(*,*) Ingrese radio del crculoREAD(*,*) radio! -------------------------------------------------! Calcular area! -------------------------------------------------area = PI*radio**2! -------------------------------------------------! Imprimir resultado! -------------------------------------------------WRITE(*,*) Area = , area! -------------------------------------------------! Terminar! -------------------------------------------------STOPEND PROGRAM calcular_areaAn cuando no conozcamos todava la sintaxis y gramtica del Fortran, podemos reconocer en el cdigoanterior ciertas caractersticas bsicas que se corresponden con el algoritmo original. En particular, notemos quelos nombres de las variables involucradas son similares a la nomenclatura utilizada en nuestro algoritmo, quelos datos de entrada y salida estan presentes (junto a un mecanismo para introducirlos y mostrarlos) y que elclculo del rea se expresa en una notacin similar (aunque no exactamente igual) a la notacin matemticausual. Adems hemos puesto una cantidad de comentarios que permiten comprender lo que el cdigo realiza.Un algoritmo es independiente del lenguaje de programacin.Si bien estamos utilizando Fortran como lenguaje de programacin debemos enfatizar que un algoritmoes independiente del lenguaje de programacin que se utiliza para su codicacin. De este modo unmismo algoritmo puede ser implementado en diversos lenguajes.Disponemos ya de un cdigo para nuestro problema. Ahora bien, cmo lo llevamos a la computadora paraobtener un programa que se pueda ejecutar? Este proceso involucra dos etapas: la edicin y la compilacin.Comencemos, pues, con la edicin. Nuestro cdigo fuente debe ser almacenado en un archivo de texto planoen la computadora. Para ello debemos utilizar un editor de texto, el cual es un programa que permite ingresartexto por el teclado para luego almacenarlo en un archivo. El archivo resultante se conoce como archivo fuente1El nombre es un acrnimo en ingls de formula translation.3Captulo 1. Primeros pasosy para un cdigo escrito en Fortran puede tener el nombre que querramos pero debe terminar con la extensin.f90. Si bien en Linux existen varios editores de texto disponibles, nosotros utilizaremos el editor emacs. Aspara ingresar el cdigo en un archivo que llamaremos area.f90 ingresamos en la lnea de comandos de unaterminal:$ emacs area.f90 &El editor emacs es un editor de texto de propsito general pero que adapta sus posibilidades al contenido delarchivo que queremos guardar. En particular permite que la programacin en Fortran resulte muy cmoda alresaltar con distintos colores las diversas instrucciones que posee el lenguaje y facilitar, adems, la generacinde cdigo sangrado apropiadamente para mayor legibilidad.Nuestro programa fuente, almacenado ahora en el archivo fuente area.f90, no es todava un programaque la computadora pueda entender directamente. Esto se debe a que Fortran es uno ms de los denominadoslenguajes de alto nivel, los cuales estn diseados para que los programadores (es decir, nosotros) puedanescribir instrucciones con palabras similares a los lenguajes humanos (en general, como vemos en nuestrocdigo, en idioma ingls)2. En contraste, una computadora no puede entender directamente tales lenguajes, pueslas computadoras solo entienden lenguajes de mquina donde las instrucciones se expresan en trminos de losdgitos binarios 0 y 1. De este modo, nuestro programa fuente, escrito en un lenguaje de alto nivel, debe sertraducido a instrucciones de bajo nivel para que la computadora pueda ejecutarlo. Esto se realiza con ayuda deun programa especial conocido como compilador. As pues, el compilador toma el cdigo fuente del programa yorigina un programa ejecutable que la computadora puede entender directamente. Este proceso es denominadocompilacin. En Linux el compilador de Fortran es llamado gfortran. As, para compilar el archivo fuentearea.f90 y generar un programa ejecutable, que llamaremos area, escribimos en la lnea de comandos:$ gfortran -Wall -o area area.f90Deberaserclaroquelaopcin-opermitedarelnombreparaelprogramaejecutableresultantedelacompilacin. Por otra parte la opcin -Wall le dice al compilador que nos advierta de posibles errores (nofatales) durante el proceso de compilacin3.Si no se producen errores, habremos creado nuestro primer programa. El programa se puede ejecutar desdela lnea de comandos con slo teclar su nombre:$ ./area1.1.1. EjerciciosEjercicio 1.1Utilizar el editor emacs para almacenar el cdigo 1.1 en el archivo fuente area.f90.Ejercicio 1.2Compile el programa fuente del ejercicio anterior. Verique que se genera, efectivamente, elprograma ejecutable.Ejercicio 1.3Vericar que el programa da resultados correctos. En particular vericar que para un radio iguala la unidad el rea que se obtiene es y que el rea se cuadruplica cuando el radio es igual a 2.Ejercicio 1.4Modicar el programa para que calcule el rea A = ab de una elipse de semiejes a y b.2De hecho, Fortran es el abuelo de todos los lenguajes de alto nivel, pues fue el primero ellos.3Wall signica, en ingls, warnings all.41.2. Cuando las cosas fallan.1.2. Cuando las cosas fallan.Tres tipos de errores se pueden presentar: errores de compilacin, errores de ejecucin y errores lgicos.Los errores de compilacin se producen normalmente por un uso incorrecto de las reglas del lenguaje deprogramacin (tpicamente errores de sintaxis). Debido a ellos el compilador no puede generar el programaejecutable. Por otra parte, los errores de ejecucin se producen por instrucciones que la computadora puedecomprender pero no ejecutar. En tal caso se detiene abruptamente la ejecucin del programa y se imprime unmensaje de error. Finalmente, los errores lgicos se deben a un error en la lgica del programa. Debido a estoserrores, an cuando el compilador nos da un programa ejecutable, el programa dar resultados incorrectos.Todos estos tipos de errores obligan a revisar el cdigo, originando un ciclo de desarrollo del programa queconsta de compilacin, revisin y nueva compilacin hasta que resulten subsanados todos los errores.1.2.1. EjerciciosEjercicio 1.5Procediendo con la compilacin y ejecucin, identicar que tipo de errores se producen en lassiguientes situaciones con nuestro cdigo.a) La sentencia WRITE(*,*) Ingrese el radio del crculo del cdigo es cambiada porWROTE(*,*) Ingrese radio del crculo.b) Durante la ejecucin se ingresa una letra cuando se pide el radio del crculo.c) El valor de la constante PI es asignada a 2.7182818 en el cdigo.1.3. Estructura general de un programa FortranUn programa en Fortran consiste de un programa principal (main, en ingls) y posiblemente varios subpro-gramas. Por el momento asumiremos que el cdigo consta slo de un programa principal. La estructura delprograma principal esPROGRAM nombredeclaraciones de tiposentencias ejecutablesSTOPEND PROGRAM nombreCada lnea del programa forma parte de una sentencia que describe una instruccin a ser llevada a cabo y talessentencias se siguen en el orden que estn escritas. En general, las sentencias se clasican en ejecutables (lascuales realizan acciones concretas como ser clculos aritmticos o entrada y salida de datos) y no ejecutables(las cuales proporcionan informacin sin requerir en s ningn cmputo, como ser las declaraciones de tiposde datos involucrados en el programa). La sentencia (no ejecutable) PROGRAM especica el comienzo delprograma principal. La misma est seguida de un nombre identicatorio para el programa el cual no necesitaser el mismo que el de su cdigo fuente ni el del programa ejecutable que genera el compilador. La sentencia(no ejecutable) END PROGRAM indica el nal lgico del programa principal. La sentencia (ejecutable) STOPdetiene la ejecucin del programa.END PROGRAM y STOP.Es importante comprender la diferencia entre estas dos sentencias. La sentencia END PROGRAM, siendola ltima sentencia del programa principal, indica al compilador la nalizacin del mismo. Por su parte,la sentencia STOP detiene la ejecucin del programa, cuando ste es ejecutado, devolviendo el control alsistema operativo. As mientras slo puede existir una sentencia END PROGRAM para indicar el nal delprograma principal, puede haber ms de una sentenciaSTOP y puede aparecer en cualquier parte delprograma que la necesite. Por otra parte, una sentenciaSTOP inmediatamente antes de una sentencia5Captulo 1. Primeros pasosEND PROGRAM es, en realidad, opcional, puesto que el programa terminar cuando alcance el n. Sinembargo su uso es recomendado para resaltar que la ejecucin del programa termina all.Una sentencia Fortran sobre una lnea puede extenderse hasta 132 caracteres. Si la sentencia es ms largasta puede continuarse en la siguiente linea insertando al nal de la lnea actual el carcter &. De esta manerauna sentencia puede ser continuada sobre 40 lneas, en Fortran 95, o 256 lneas en Fortran 2003.Originalmente la codicacin de un programa Fortran slo poda utilizar letras maysculas. En la actualidadtodos los compiladores aceptan que en el programa haya letras minsculas. Debe tenerse presente, sin embargo,que el compilador Fortran no distinguir entre las letras maysculas y minsculas (excepto en las constantesliterales de carcter).Cualquier oracin precedida de un signo de exclamacin! es un comentario. Un comentario es unaindicacin del programador que permite aclarar o resaltar lo que realiza cierta parte del cdigo. Por lo tanto loscomentarios son de gran ayuda para documentar la operacin de un programa o una parte de ella y deben usarseprofusamente. Ntese que los comentarios son ignorados por el compilador.Es recomendable ser consistente con cierto estilo al escribir un programa Fortran. Aqu adoptaremos elestilo en que las instrucciones de Fortran, tales como PROGRAM, READ, WRITE, son escritas con maysculas,mientras que las variables denidas por el programador son escritas con minsculas. Asimismo los nombres quesean compuestos a partir de varias palabras son unidos con el guin bajo, como ser, mi_primer_programa.Por otra parte, constantes con nombres, utilizadas para valores que no cambian durante la ejecucin del programa,como ser PI para almacenenar el valor del nmero , son escritos con maysculas.1.3.1. EjerciciosEjercicio 1.6Identicar y clasicar las sentencias del programa dado en el cdigo 1.1.Ejercicio 1.7Indicar los errores en el siguiente programa Fortran.PROGRAMent*Un simple programainteger :: entent = 12WRITE(*,*) El valor del entero es ,entEND PROGRAM entSTOP6Captulo 2Tipos de datos simplesDios es realA menos que sea declarado entero.2.1. Tipos de datos simples.Los diferentes objetos de informacin con los que un programa puede operar se conocen colectivamentecomo datos. Todos los datos tienen un tipo asociados a ellos. La asignacin de tipos a los datos permite indicarla clase de valores que pueden tomar y las operaciones que se pueden realizar con ellos. Fortran dispone decinco tipos de datos simples: enteros, reales, complejos, de carcter y lgicos (siendo los cuatro primeros datosde tipo numrico). Esta clasicacin se ilustra en la gura 2.1. Por otra parte, los datos aparecen en el programacomo constantes literales, como variables o como constantes con nombres. Una constante literal es un valor decualquiera de los tipos de datos que se utiliza como tal y por lo tanto permanece invariable. Una variable, encambio, es un dato, referido con un nombre, susceptible de ser modicado por las acciones del programa. Unaconstante con nombre es un valor referenciado con un nombre y su valor permanece jo, es decir, no puede seralterado por las acciones del programa.Existen razones tanto matemticas como computacionales para considerar distintos tipos de datos numricos.Un dato entero permite la representacin exacta de un nmero entero en la computadora (dentro de ciertorango). Un dato real permite la representacin de un nmero real, aunque tal representacin no es exacta, sinoaproximada.7Captulo 2. Tipos de datos simplesFigura 2.1. Tipos de datos simples.Precisin de los datos reales.En las computadoras personales (PC) actuales, un dato de tipo real tiene una precisin de no ms de7 dgitos signicativos y puede representar nmeros reales en el rango de 1038a 1038. Este tema esabordado ms exahustivamente en el captulo 7.Una constante literal entera es un nmero entero, como ser -1, 0, 2, y por lo tanto no puede tener partedecimal. Una constante literal real es un nmero real con punto decimal, como ser 3.14159, -18.8, 0.0056.Nmeros muy grandes o muy pequeos se representan en notacin cientca en la formam.n Ep,donde m.n es un nmero decimal y la E (de exponente) signica multiplicar por 10 a la potencia entera p.As, por ejemplo, 3.49102se codica como 3.49E-2.Constantes literales numricas.Fortran establece la diferencia entre constantes literales enteras y reales por la presencia o ausencia delpunto decimal, respectivamente. Estas dos formas noson intercambiables puesto que se almacenan yprocesan de forma diferente en la computadora.Por razones de claridad y estilo es conveniente utilizar el cero explcitamente al escribir constante realessin parte fraccionaria con parte entera nula. As escribimos11.0 en vez de11. y0.2 en vez de.2.Tambin resulta conveniente codicar el cero real como0.0.Un dato de tipo complejo permite representar un nmero complejo mediante un par ordenado de datosreales: uno que representa la parte real, y otro, la parte imaginaria del nmero complejo. Una constante literalcompleja consiste un par ordenado de constantes literales reales encerradas entre parntesis y separadas por unacoma. Por ejemplo (3.5,4.0) corresponde al nmero complejo con parte real 3.5 y parte imaginaria 4.0.Un dato tipo carcter permite representar caracteres alfanumricos, esto es letras (a, b, A, B, etc.) y dgitos(tal como 6), y caracteres especiales (tales como $, &, *, el espacio en blanco, etc.). Una constante literal decarcter consiste en una secuencia de caracteres encerradas entre apstrofes (comillas sencillas), por ejemplo:AbC, o comillas dobles, "AbC" por ejemplo.82.1. Tipos de datos simples.Finalmente, un dato de tipo lgico es un dato que solo puede tomar un valor entre dos valores posibles:verdadero o falso. Sus valores literales se codican en Fortran como .TRUE. y .FALSE. respectivamente.Las variables son los datos de un programa cuyo valores pueden cambiar durante la ejecucin del mismo.Existen tantos tipos de variables como tipos de datos diferentes. Una variable, en realidad, es una regin dada enla memoria de la computadora a la cual se le asigna un nombre simblico. El nombre simblico o identicadorse llama nombre de la variable mientras que el valor almacenado en la regin de memoria se llama valor de lavariable. La extensin de la regin que ocupa la variable en la memoria viene dada por el tipo de dato asociadocon ella. Una imagen mental til de la situacin es considerar a las variables como cajas o buzones, cada una delas cuales tiene un nombre y contiene un valor.En Fortran los nombres de las variables slo pueden formarse con letras (incluyendo al guin bajo _ comoun carcter vlido) o nmeros pero siempre deben comenzar con una letra. El nmero mximo de caracteresque permite Fortran 95 para formar el nombre de una variables es de 31 caracteres, aunque en Fortran 2003 ellmite es de 63.Sobre los nombres de las variablesConstituye una buena prctica de programacin utilizar nombres de variables que sugieran lo que ellasrepresentan en el contexto del problema considerado. Esto hace al programa ms legible y de ms fcilcomprensin.Antes de ser utilizadas, las variables deben ser declaradas en la seccin de declaracin de tipo de variables.Para ello se utilizan las siguientes sentencias no ejecutables de acuerdo al tipo de dato que almacenarn:INTEGER :: lista de variables enterasREAL :: lista de variables realesCOMPLEX :: lista de variables complejasCHARACTER(tamao) :: lista de variables carcterLOGICAL :: lista de variables lgicasSi la lista de variables cuenta con ms de un elemento, las mismas deben estar separadas por comas. Puedetambin usarse una sentencia de declaracin de tipo por cada variable del programa. Esto ltimo permiteintroducir un comentario para el uso que se har en el programa, construyendo as un til diccionario de datosque permite comprender fcilmente el uso dado a las variables del programa.Declaracin de variables implcita y explcita.Fortran dispone de una (desafortunada) caracterstica cual es la declaracin implcita de tipos: nombresde variables que comienzan con las letras en el rangoa-h,o-z se consideran variables reales, mientrasque el resto, es decir las que comienza con las letras en el rangoi-n, se consideran variables enteras.Este estilo de programacin es altamente desaconsejado ya que es una fuente continua de errores. Por elcontrario, nosotros propiciamos la declaracin explcita de todas las variables utilizadas en el programa.Mas an, con el n de evitar completamente la posibilidad de declaraciones implcitas utilizamos lasentencia IMPLICIT NONE al comienzo de la declaracin de tipo. Con esta sentencia el uso de variablesno declaradas generar un error de compilacin.Finalmente, las constantes con nombres permiten asignar un nombre simblico a una constante literal y,como tal, no podrn ser alteradas. Esto resulta til para nombrar nmeros irracionales tales como o constantesfsicas como la velocidad de la luz c que aparecen repetidamente, y tambin para recongurar valores quepueden intervenir en un algoritmo. La declaracin de una constante con nombre se realiza en su declaracin detipo como sigue:tipo, PARAMETER :: nombre = constante9Captulo 2. Tipos de datos simples2.1.1. EjerciciosEjercicio 2.1La siguiente lista presenta una serie de constantes vlidas o invlidas en Fortran. Indicar si cadauna de ellas es vlida o invlida. En el caso que sea vlida, especicar su tipo. Si es invlida indicar porquerazn.10.0, 100, 000, 123E-5, Es correcto, 3.14159, 3.14159, Distancia =, 17.8E+6, 13.0^2.Ejercicio 2.2Escribir los siguientes nmeros como constantes literales reales.256, 2.56, 43000, 1012, 0.000000492, 10, 1016.Ejercicio 2.3Escribir los siguientes nmeros complejos como constantes literales complejas.i, 3+i, 1.Ejercicio 2.4Indicar cuales de los siguientes son identicadores aceptables para variables en Fortran.gamma, j79-12, epsilon, a5, 5a, is real, is_real, r(2)19, stop, _ok.Palabras reservadas.En la mayora de los lenguajes de programacin las palabras que constituyen instrucciones del lenguaje nopueden ser utilizadas como nombres de variables (se dice que son palabras reservadas). En Fortran, sinembargo, noexisten palabras reservadas y, por lo tanto, por ejemplo, es posible dar el nombrestop auna variable. Esta forma de proceder, sin embargo, no es recomendable porque puede introducir efectosno deseados.Ejercicio 2.5Escriba las declaraciones de tipo apropiadas para declarar la variables enteras i, contador,las variables reales x, y, vx, vy, la variable lgica clave y la variable carcter mensaje (la cual tendr unmximo de 80 caracteres).Ejercicio 2.6Escriba sentencias de declaracin apropiadas para denir como parmetros la velocidad de la luzen el vaco c = 2.9979108m s1y la constante de Plank h = 6.62561034J s.2.2. Sentencias de asignacin.La sentencia de asignacin permite asignar (almacenar) un valor en una variable. La operacin de asignacinse indica tanto en el pseudocdigo de nuestros algoritmos como en un programa Fortran en la forma generalvariable = expresinAqu el signo = no debe ser interpretado como el signo de igualdad matemtico, sino que representa la operacinen la cual el valor de la expresin situada a la derecha se almacena en la variable situada a la izquierda. Porexpresin entendemos aqu un conjunto de variables o constantes conectadas entre s mediante los operadoresque permiten sus tipos.El tipo de dato correspondiente a la expresin debe ser el mismo tipo de dato correspondiente a la variable.Para tipos numricos si ste no es el caso ciertas conversiones de tipo implcitas se realizan (las cuales serndiscutidas enseguida).La operacin de asignacin es una operacin destructiva para la variable del miembro de la izquierda,debido a que cualquier valor almacenado previamente en dicha variable se pierde y se sustituye por el nuevovalor. Por el contrario, los valores de cualesquiera variables que se encuentren en la expresin del miembro dela derecha de la asignacin no cambian sus valores.102.2. Sentencias de asignacin.Smbolo Signicado Ejemplo+ adicin a+b- sustraccin a-bopuesto -b/ divisin a/b*multiplicacin a*b**potenciacin a**bTabla 2.1. Codicacin de los operadores aritmticos en Fortran.En una sentencia de asignacin cualquier cosa distinta de un nombre de variable en el miembro de laizquierda conduce a una sentencia incorrecta.Entre los tipos de expresiones que podemos considerar nos interesan especialmente las expresiones aritmti-cas, las cuales son un conjunto de datos numricos (variables y constantes) unidos por operadores aritmticos yfunciones sobre los mismos. Cuando una expresin aritmtica se evala el resultado es un dato numerico y porlo tanto puede ser asignada una variable de tipo numrico a travs de una sentencia de asignacin aritmtica.Los operadores aritmticos son los usuales, cuya codicacin en Fortran es indicada en la tabla 2.1.Pero adems Fortran dispone de un conjunto de funciones intrnsecas que implementan una gran variedadde funciones matemticas, algunas de las cuales se presentan en la tabla 2.2. Para utilizar una funcin se empleael nombre de la misma seguido por la expresin sobre la que se va a operar (argumento) dentro de un juego deparntesis. Por ejemplo, la sentencia y = ABS(x) calcula el valor absoluto de x y lo asigna a y.Funciones implcitas del compilador gfortran.Una lista de todas las funciones implcitas que proporciona el compiladorgfortan puede verse en lapgina info del mismo, ejecutando en una terminal el comando:$ info gfortrany dirigindonos a la seccin tituladaIntrinsic Procedures. (Para salir de la pgina info simple-mente presionamos la teclaq).2.2.1. EjerciciosEjercicio 2.7Escribir sentencias de asignacin que efecten lo siguiente:a) Incrementar en 1 el valor actual de una variable entera n y remplazar el valor de n por dicho incremento.Una variable entera que se incrementa en una unidad o una cantidad constante se conoce como contador.b) Incrementar en x (siendo x una variable numrica) el valor de la variable numrica suma y reemplazar elvalor de suma por tal incremento. Una variable que acta de esta forma se conoce como un acumulador.c) Asignar a una variable lgica el valor verdadero.d) Intercambiar el valor de dos variables a y b del mismo tipo (Ayuda: el intercambio requiere de una terceravariable).Ejercicio 2.8Considere el siguiente programa Fortran.PROGRAM problemaIMPLICIT NONEREAL :: x,yy = x + 1.0WRITE(*,*) ySTOPEND PROGRAM problema11Captulo 2. Tipos de datos simplesr = SIN(r) seno del ngulo en radianesr = COS(r) coseno del ngulo en radianesr = TAN(r) tangente del ngulo en radianesr = ASIN(r) arco seno (en el rango /2 a+/2)r = ACOS(r) arco coseno (en el rango 0 a+)r = ATAN(r) arco tangente (en el rango /2 a+/2)r = ATAN2(r,r) arco tangente de arg1/arg2 (en el rango a )r = SQRT(r) raz cuadradar = EXP(r) funcin exponencialr = LOG(r) logaritmo naturalr = LOG10(r) logaritmo decimal*= ABS(ir) valor absoluto*= MOD(ir,ir) resto de la divisin de arg1 por arg2*= MAX(ir,ir) devuelve el mximo entre arg1 y arg2*= MIN(ir,ir) devuelve el mnimo entre arg1 y arg2i = INT(r) convierte a un tipo entero truncando la parte decimalr = REAL(i) convierte a tipo realTabla 2.2. Funciones intrnsecas importantes proporcionadas por Fortran. El tipo deldato del argumento y del resultado que admiten es indicado por una letra: i = entero,r = real. Un asterisco en el miembro de la derecha indica que el resultado es delmismo tipo que el argumento.Qu sucede al ejecutarlo varias veces? A qu se debe tales resultados?Variables no inicializadas.Unavariableenel ladoderechodeunasentenciadeasignacindebetenerunvalorantesdequelasentencia de asignacin se ejecute. Hasta que una sentencia no le de un valor a una variable, esa variablenotendrunvalordenido. Unavariablealaquenoselehadadounvalorsedicequenosehainicializado. Entonces si, por ejemplo, x no tiene un valor antes de ejecutarse la sentencia y = x + 1.0,se produce un error lgico. Muchos lenguajes de programacin inicializan automticamente sus variablesnumricas en cero. Sin embargo, este no es el caso de Fortran. As una variable sin inicializar contendresencialmente un valor espurio proveniente de lo que exista en dicho momento en la posicin de memoriacorrespondiente a la variable. Su uso ciertamente conducir a una situacin de error en los datos de salida.En Fortran 95 la inicializacin de una variable puede ser realizada en tiempo de compilacin asignando suvalor en la sentencia de declaracin correspondiente, como ser, por ejemplo,REAL :: x = 0.0.2.3. Orden de precedencia de las operaciones aritmticas y conversin impl-cita de tipo.Cuando en una expresin aparecen dos o ms operadores se requiere de un orden de precedencia de lasoperaciones que permita determinar el orden en que se realizaran las operaciones. En Fortran estas reglas sonlas siguientes:Todas las subexpresiones entre parntesis se evalan primero. Las expresiones con parntesis anidados seevalan de adentro hacia fuera: el parntesis ms interno se evala primero.Dentro de una misma expresin o subexpresin, las funciones se evalan primero y luego los operadores seevalan en el siguiente orden de prioridad: potenciacin; multiplicacin y divisin; adicin, substracciny negacin.Los operadores en una misma expresin o subexpresin con igual nivel de prioridad se evalan deizquierda a derecha, con excepcin de la potenciacin, que se evala de derecha a izquierda.122.3. Orden de precedencia de las operaciones aritmticas y conversin implcita de tipo.As, por ejemplo, a + b*c/d es equivalente a a + ((b*c)/d), mientras que x**y**z es equivalente ax**(y**z).Cuando en una expresin aritmtica los operandos tienen el mismo tipo de dato numrico, el resultado tieneel mismo tipo que stos. En particular, la divisin de dos tipos enteros es un entero, mientras que la divisin dedos tipos reales es un real. Si, en cambio, los operandos tienen tipos numricos distintos, una conversin de tipoimplcita se aplica, llevando el tipo de uno de ellos al otro, siguiendo la siguiente direccin: enteros se conviertena reales, reales se convierten a complejos. La excepcin a esta regla es la potenciacin: cuando la potenciaes un entero el clculo es equivalente a la multiplicacin repetida (por ejemplo, con x real, x**2 = x*x)Sin embargo, si la potencia es de otro tipo numrico el cmputo se realiza implcitamente a travs de lasfunciones logartmica y exponencial (por ejemplo, x**2.0 es calculado como e2.0logx). De la misma manerauna conversin de tipo implcita se realiza cuando en una sentencia aritmtica la expresin y la variable dierenen tipo numrico, en tal caso, la expresin despus de ser evaluada es convertida al tipo de la variable a la quese asigna el valor. Ciertamente, estas conversiones implcitas, producto de la mezcla de tipos en una mismaexpresin o sentencia debe ser consideradas con mucho cuidado. En expresiones complejas conviene hacerlasexplcitas a travs de las apropiadas funciones intrnsecas de conversin de tipo que se detallan en la tabla 2.2.2.3.1. EjerciciosEjercicio 2.9Determinar el valor de la variable real a o de la variable entera i obtenido como resultado de cadauna de las siguientes sentencias de asignacin aritmtica. Indicar el orden en que son realizadas las operacionesaritmticas y las conversiones de tipo implcitas (si existen).a) a = 2*6 + 1b) a = 2/3c) a = 2.0*6.0/4.0d) i = 2*10/4e) i = 2*(10/4)f) a = 2*(10/4)g) a = 2.0*(10.0/4.0)h) a = 2.0*(1.0e1/4.0)i) a = 6.0*1.0/6.0j) a = 6.0*(1.0/6.0)k) a = 1.0/3.0 + 1.0/3.0 + 1.0/3.0l) a = 1/3 + 1/3 + 1/3m) a = 4.0**(3/2)n) a = 4.0**3.0/2.0) a = 4.0**(3.0/2.0)o) i = 19/4 + 5/4p) a = 19/4 + 5/4q) i = 100*(99/100)r) i = 10**(2/3)s) i = 10**(2.0/3.0)Ejercicio 2.10Supongase que las variables reales a,b,c,d,e,f y la variable entera g han sido inicializadascon los siguientes valores:a=3.0, b=2.0, c=5.0, d=4.0, c=5.0, d=4.0, e=10.0, f=2.0, g=3Determine el resultado de las siguientes sentencias de asignacin, indique el orden en que se realizan lasoperaciones.a) resultado = a*b+c*d+e/f**gb) resultado = a*(b+c)*d+(e/f)**gc) resultado = a*(b+c)*(d+e)/f**gEjercicio 2.11Escriba sentencias de asignacin aritmticas para los siguientes expresiones matemticas.a) t = 3103x4,b) y = (x)n,c) x = a(1/n),d) z =xy_x2+y2,e) y =_2x_1/2cosx,f) z = cos1([logx[).13Captulo 2. Tipos de datos simplesg) y = 12 log 1+sinx1sinx,Ejercicio 2.12Considere el siguiente programaPROGRAM testIMPLICIT NONEREAL :: a,b,c! ------------------------READ(*,*) a,bc = ( (a+b)**2 - 2.0*a*b - b**2 )/a**2WRITE(*,*) c! ------------------------STOPEND PROGRAM testCul sera el valor esperado dec, cualquiera sean los valores dea yb ingresados? Ejectue el programaingresando los pares de valores a = 0.5, b = 888.0; a = 0.0001, b = 8888.0 y a = 0.00001, b = 88888.0. A quse debe los resultados obtenidos?2.4. Entrada y salida por lista.Si se desea utilizar un conjunto de datos de entrada diferentes cada vez que se ejecuta un programadebe proporcionarse un mtodo para leer dichos datos. De manera similar, para visualizar los resultados delprograma debe proporcionarse un mecanismo para darles salida. El conjunto de instrucciones para realizarestas operaciones se conocen como sentencias de entrada/salida. En los algoritmos tales instrucciones lasdescribimos en pseudocdigo comoLeer lista de variables de entrada.Imprimir lista de variables de salida.Existen dos modos bsicos para ingresar datos en un programa: interactivo y por archivos. Aqu solo discutiremosel primero, dejando el segundo para otra prctica. En el modo interactivo el usuario ingresa los datos por tecladomientras ejecuta el programa. La sentencia Fortran apropiada para sto esREAD(*,*) lista de variablesdonde la lista de variables, si contiene ms de un elemento, est separada por comas. Con el n de guiar alusuario en la entrada de datos interactiva es conveniente imprimir un mensaje indicativo previo a la lectura delos datos. Por ejemplo,WRITE(*,*) Ingrese radio del crculoREAD(*,*) radioPara dar salida a los datos por pantalla utilizamos la sentenciaWRITE(*,*) lista de variablesNuevamente podemos utilizar constantes literales de carcter para indicar de que trata el resultado obtenido. Porejemplo,WRITE(*,*) Area del crculo = , area142.5. Implementando lo aprendido.2.4.1. EjerciciosEjercicio 2.13Escribir la sentencia de entrada (para leer por teclado) y la sentencia de salida (por pantalla)para los siguientes datos:a) 0.1E13b) (0.0,1.0)c) Hola mundo!d) 3 1.5 -0.6e) .TRUE.2.5. Implementando lo aprendido.Los siguientes ejercicios plantean diversos problemas. Para cada uno de ellos se debe disear un algoritmoapropiado el cual debe ser descrito en pseudocdigo y gracado por su diagrama de ujo. Luego implementardicho algoritmo como un programa Fortran. Testear el programa utilizando datos de entrada que conducen aresultados conocidos de antemano.Ejercicio 2.14Dado los tres lados a, b y c de un tringulo, calcular su rea A por la frmula de Hern,A =_s(s a)(s b)(s c),donde s = (a+b+c)/2.Ejercicio 2.15Dadas las coordenadas polares (r, ) de un punto en el plano R2, se desea calcular sus coorde-nadas rectangulares (x, y) denidas por_x = r cos,y = r sin.Ejercicio 2.16Calcular el rea A y el volumen Vde una esfera de radio r,A = 4r2, V= 43r3.Implementar el algoritmo de manera de minimizar el nmero de multiplicaciones utilizadas.Eciencia de un algoritmo.Una manera de medir la eciencia de un algoritmo (y un programa) es contabilizar el nmero de operacionesutilizadas para resolver el problema. Cuanto menor sea este nmero ms eciente ser el algoritmo (y elprograma).Ejercicio 2.17La temperatura medida en grados centgrados tC puede ser convertida a la escala Farenheit tFsegn la frmula:tF= 95tC +32Dado un valor decimal de la temperatura en la escala centgrada se quiere obtener su valor en la escalaFahrenheit.Ejercicio 2.18La magnitud de la fuerza de atraccin gravitatoria entre dos masas puntuales m1 y m2, separadaspor una distancia r est dada por la frmulaF = G m1m2r2,donde G=6.673108cm3s2g1es la constante de gravitacin universal. Se desea evaluar, dada la masas dedos cuerpos y la distancia entre ellos, la fuerza de gravitacin. El resultado debe estar expresados en dinas; unadina es dimensionalmente igual a un g cm s2.Ntese que las unidades de una frmula deben ser consistentes,por lo cual, en este problema, las masas deben expresarse en gramos y la distancia en centmetros.15Captulo 3Estructuras de controlSe encuentra un programador muerto en la baadera.En una de sus manos hay una botella de shampoo que dice:Modo de uso: Aplicar, enjuagar, repetir.3.1. Estructuras de controlLas estructuras de control permiten especicar el orden en que se ejecutaran las instrucciones de unalgoritmo. Todo algoritmo puede disearse combinando tres tipos bsicos de estructuras de control:secuencial: las instrucciones se ejecutan sucesivamente una despus de otra,de seleccin: permite elegir entre dos conjuntos de instrucciones dependiendo del cumplimiento (o no) deuna condicin,de iteracin: un conjunto de instrucciones se repite una y otra vez hasta que se cumple cierta condicin.Combinando estas tres estructuras bsicas es posible producir un ujo de instrucciones ms complejo peroque an conserve la simplicidad inherente de las mismas. La implementacin de un algoritmo en base a estostres tipos de estructuras se conoce como programacin estructurada y este estilo de programacin conduce aprogramas ms fciles de escribir, leer y modicar.17Captulo 3. Estructuras de controlABCFigura 3.1. Estructura secuencial.3.2. Estructura secuencial.La estructura de control ms simple est representada por una sucesin de operaciones donde el ordende ejecucin coincide con la aparicin de las instrucciones en el algoritmo (o cdigo del programa). Lagura 3.1 ilustra el diagrama de ujo correspondiente a esta estructura. En Fortran una estructura secuencial essimplemente un conjunto de sentencias simples unas despus de otra.3.3. Estructura de seleccin.La estructura de seleccin permite que dos conjuntos de instrucciones alternativas puedan ejecutarse segnse cumpla (o no) una determinada condicin. El pseudocdigo de esta estructura es descrito en la forma si. . . entonces . . . sino . . . , ya que si p es una condicin y A y B respectivos conjuntos de instrucciones, la seleccinse describe como sip es verdadero entonces ejecutar las instrucciones A, sino ejecutar las instrucciones B.Codicamos entonces esta estructura en pseudocdigo como sigue.Si condicin entoncesinstrucciones para condicin verdaderasinoinstrucciones para condicin falsafin_siEl diagrama de ujo correspondiente se ilustra en la gura 3.2. En Fortran su implementacin tiene la siguientesintaxis:IF (condicin) THENsentencias para condicin verdaderaELSEsentencias para condicin falsaENDIFSangrado (indentacin)Mientras que la separacin de lneas en la codicacin de una estructura de control es sintcticamentenecesaria, el sangrado en los conjuntos de sentencias es opcional. Sin embargo, la sangra favorece lalegibilidad del programa y, por lo tanto, constituye una buena prctica de programacin.183.3. Estructura de seleccin.B ACondicinV FFigura 3.2. Estructura de seleccin.Operador Signicado< menor que> mayor que== igual a= mayor o igual que/= distinto aTabla 3.1. Operadores relacionales.Operador Signicado.NOT. negacin.AND. conjuncin.OR. disyuncin (inclusiva).EQV. equivalenciaTabla 3.2. Operadores lgicos.La condicin en la estructura de seleccin es especicada en Fortran por una expresin lgica, esto es, unaexpresin que devuelve un dato de tipo lgico: verdadero (.TRUE.) o falso (.FALSE.). Una expresin lgicapuede formarse comparando los valores de expresiones aritmticas utilizando operadores relacionales y puedencombinarse usando operadores lgicos. El conjunto de operadores relacionales involucra a las relaciones deigualdad, desigualdad y de orden, las cuales son codicadas en Fortran como se indica en la tabla 3.1. Por otrolado, los operadores lgicos bsicos son la negacin, la conjuncin, la disyuncin (inclusiva) y equivalencia,cuya codicacin en Fortran se indica en la tabla 3.2. El operador .NOT. indica la negacin u opuesto dela expresin lgica. Una expresin que involucra dos operandos unidos por el operador .AND. es verdaderasi ambas expresiones son verdaderas. Una expresin con el operador .OR. es verdadera si uno cualquiera oambos operandos son verdaderos. Finalmente en el caso de equivalencia lgica la expresin es verdadera siambos operandos conectados por el operador .EQV. son ambos verdaderos.1.Cuando en una expresin aparecen operaciones aritmticas, relacionales y lgicas, el orden de precedenciaen la evaluacin de las operaciones es como sigue:1. Operadores aritmticos.2. Operadores relacionales.3. Operadores lgicos, con prioridad: .NOT., .AND. y .OR., .EQV..Operaciones que tienen la misma prioridad se ejecutan de izquierda a derecha. Por supuesto, las prioridadespueden ser modicadas mediante el uso de parntesis.En muchas circunstancias se desea ejecutar un conjunto de instrucciones slo si la condicin es verdaderay no ejecutar ninguna instruccin si la condicin es falsa. En tal caso, la estructura de control se simplica,codicndose en pseudocdigo como sigue (y con un diagrama de ujo como se indica en la gura 3.3)Si condicin entoncesinstrucciones para condicin verdaderafin_si1Estos enunciados no son ms que las conocidas tablas de verdad de la lgica matemtica.19Captulo 3. Estructuras de controlACondicinV FFigura 3.3. Estructura de seleccin sin seccin sino.La sintaxis correspondiente en Fortran esIF (condicin) THENsentencias para condicin verdaderaENDIFSi, adems, slo debe realizarse una sentencia ejecutable cuando la condicin es verdadera, Fortran permitecodicar esta situacin en un if lgico:IF (condicin) sentencia ejecutableOtra circunstancia que se suele presentar es la necesidad de elegir entre ms de una alternativa de ejecucin.En este caso podemos utilizar la estructura multicondicional cuya lgica se puede expresar en la forma si. . . entonces sino si . . . sino . . . . El pseudocdigo correspondiente es descrito como sigue (y su diagrama de ujose ilustra en la gura 3.4)Si condicin 1 entoncesinstrucciones para condicin 1 verdaderasino si condicin 2 entoncesinstrucciones para condicin 2 verdadera...sino si condicin N entoncesinstrucciones para condicin N verdaderasinoinstrucciones para todas las condiciones falsasfin_siAqu, cada condicin se prueba por turno. Si la condicin no se se satisface, se prueba la siguiente, pero si lacondicin es verdadera, se ejecutan las instrucciones correspondientes para tal condicin y luego se va al nalde la estructura. Si ninguna de las condiciones son satisfechas se ejecutan las instrucciones especicadas en elbloque correspondientes al sino nal. Debera quedar claro entonces que para que un estructura condicional seaeciente sus condiciones deben ser mutuamente excluyentes. La codicacin de esta estructura en Fortran seindica a continuacin.IF (condicin 1) THENsentencias para condicin 1 verdaderaELSEIF (condicin 2) THENsentencias para condicin 2 verdadera...ELSEIF (condicin N) THENsentencias para condicin N verdaderaELSEsentencias para todas las condiciones falsaENDIF203.3. Estructura de seleccin.cond. 1Bloque 1cond. 2Bloque 2cond. NBloque N Bloque F. . .VVVFFFFigura 3.4. Estructura multicondicional.Consideremos, como ejemplo de una estructura de seleccin, el diseo e implementacin de un algoritmopara calcular las races de una ecuacin cuadrticaax2+bx +c = 0,esto es,x1,2 = bb24ac2a.La naturaleza de estas races depender del signo del discriminante =b24ac, lo cual nos lleva a implementaruna estructura de seleccin: si > 0 las races sern nmeros reales, de lo contrario sern nmeros complejosconjugados uno del otro. Por otra parte, al ingresar los coecientes, deberamos asegurarnos que el coeciente ano es nulo, pues, de lo contario la frmula conducira a una divisin por cero. Nuevamente, una estructura dedecisin permite vericar sto. El pseudocdigo de nuestro algoritmo es el siguiente.Leer a, b, cSi a = 0 entoncesEscribir La ecuacin no es cuadrtica.Salir.fin_si.Calcular = b24ac.Si 0 entoncesCalcular x1= (b+)/2aCalcular x2= (b)/2asinoCalcular x1= (b+ i)/2aCalcular x2= x1fin_si.Imprimir x1y x2.A continuacin damos una implementacin de este algoritmo. Ntese que no utilizamos variables complejassino dos variables reales que contendrn la parte real y la parte imaginaria de las posibles races complejas.21Captulo 3. Estructuras de controlCdigo 3.1. Clculo de las races de la ec. cuadrticaPROGRAM ecuadratica! ------------------------------------------------------------------! Se calculan las races de la ecuacin cuadrtica ax**2+bx+c=0! ------------------------------------------------------------------! Declaracin de tipos! ------------------------------------------------------------------IMPLICIT NONEREAL :: a,b,c ! coeficientes de la ecuacinREAL :: discr ! discriminante de la ecuacinREAL :: x1,x2 ! variables para solucionesREAL :: term, den! ------------------------------------------------------------------! Entrada de datos! ------------------------------------------------------------------WRITE(*,*) Ingrese coeficientes a,b,cREAD(*,*) a,b,cIF( a == 0 ) THENWRITE(*,*) La ecuacin no tiene trmino cuadrticoSTOPENDIF! ------------------------------------------------------------------! Bloque de procesamiento y salida! ------------------------------------------------------------------discr = b**2 - 4.0*a*cden = 2.0*aterm = SQRT(ABS(discr))IF (discr >= 0 ) THENx1 = (-b+term)/denx2 = (-b-term)/denWRITE(*,*) x1 = , x1WRITE(*,*) x2 = , x2ELSEx1 = -b/denx2 = term/denWRITE(*,*) x1 = (, x1, ,, x2, )WRITE(*,*) x1 = (, x1, ,, -x2, )ENDIF! ------------------------------------------------------------------! Terminar! ------------------------------------------------------------------STOPEND PROGRAM ecuadratica3.3.1. EjerciciosEjercicio 3.1Dadas las variables con los valores que se indican:a = 2.0 d = 2.5 i = 2 f = .FALSE.b = 5.0 e = -4.0 j = 3 t = .TRUE.c = 10.0 k = -2deducir el valor lgico de cada una de las expresiones lgicas siguientes. Indicar el orden en que se evalan.a) t .AND. f .OR. .FALSE.b) a**i+b = e+c/d-a**j223.3. Estructura de seleccin.d) (b*j+3.0) == (d-e) .AND. (.NOT. f)Ejercicio 3.2Implemente una estructura de decisin para vericar si un nmero es negativo o no negativo(positivo o cero).Ejercicio 3.3Implemente una estructura de decisin para determinar si un nmero entero es par o impar(Ayuda: utilice la funcin MOD(x,y), la cual devuelve el resto de la divisin de x por y).Ejercicio 3.4Dada una esfera de radio R, considerando su centro como origen de coordenadas se quieredeterminar si un punto de coordenadas (x, y, z) est dentro o fuera de la esfera. Implemente un algoritmo paraste problema.Ejercicio 3.5Considrese en el plano un rectngulo dado por las coordenadas (xS, yS) de su vrtice superiorizquierdo y las coordenadas (xI, yI) de su vrtice inferior derecho. Se quiere determinar si un punto (x, y) delplano est dentro o fuera del rectngulo. Implemente la solucin en un algoritmo.Ejercicio 3.6Dado tres nmeros reales distintos se desea determinar cual es el mayor. Implemente un algoritmoapropiado (Ayuda: considere ya sea un conjunto de estructuras de seleccin anidadas o bien dos estructuras deseleccin en secuencia).Estructuras de seleccin anidadasLa sentencia que comienza en el bloque de instrucciones verdadero o falso de la estructura de seleccinpuedesercualquiera, inclusootrasentenciaIF-THEN-ELSE. Cuandostoocurreenunaoambasbifurcaciones de la estructura, se dice que las sentenciasIF estn anidadas.Ejercicio 3.7Compile y ejecute el siguiente programa. A qu puede atribuirse el resultado que se obtiene?PROGRAM test_igualdadIMPLICIT NONEREAL :: aa = 2.0IF (1.0/a == 0.5) THENWRITE(*,*) 1/2 es igual a 0.5ELSEWRITE(*,*) 1/2 es distinto a 0.5ENDIFa = 10.0IF (1.0/a == 0.1) THENWRITE(*,*) 1/10 es igual a 0.1ELSEWRITE(*,*) 1/10 es distinto a 0.1ENDIFSTOPEND PROGRAM test_igualdadIgualdad entre datos reales.Las cantidades reales que son algebraicamente iguales pueden producir un valor lgico falso cuando secomparan los respectivos datos reales con== ya que la mayora de los nmeros reales no se almacenanexactamente en la computadora.Ejercicio 3.8Implemente un algoritmo que intercambie los valores de dos nmeros reales si estn en ordencreciente pero que no realice ninguna accin en caso contrario.Ejercicio 3.9Implementar el clculo del valor absoluto de un nmero real con un if lgico.23Captulo 3. Estructuras de controlEjercicio 3.10Implementar una estructura multicondicional para la evaluacin de la funcinf (x) =___exsi x 1.Ejercicio 3.11Un examen se considera desaprobado si la nota obtenida es menor que 4 y aprobado en casocontrario. Si la nota est entre 7 y 9 (inclusive) el examen se considera destacado, y entre 9 y 10 (inclusive)sobresaliente. Implementar un algoritmo para indicar el estatus de un examen en base a su nota.3.4. Estructura de iteracin.La estructura de control iterativa permite la repeticin de una serie determinada de instrucciones. Esteconjunto de instrucciones a repetir se denomina bucle (loop, en ingls) y cada repeticin del mismo se denominaiteracin. Podemos diferenciar dos tipos de bucles:Bucles donde el nmero de iteraciones es jo y conocido de antemano.Bucles donde el numero de iteraciones es desconocido de antemano. En este caso el bucle se repitemientras se cumple una determinada condicin (bucles condicionales).Para estos dos tipos de bucles disponemos de sendas formas bsicas de la estructura de control iterativa.Comencemos con un bucle cuyo nmero de iteraciones es conocido a priori. La estructura iterativa, en talcaso, puede expresarse en pseudocdigo como sigue.Desde ndice = valor inicial hasta valor final hacerinstrucciones del buclefin_desdeEl diagrama de ujo correspondiente se ilustra en la gura 3.5.El ndice es una variable entera que, actuando como un contador, permite controlar el nmero de ejecucionesdel ciclo.Los valor inicial y valor nal son valores enteros que indican los lmites entre los que vara ndice alcomienzo y nal del bucle.Est implcito que en cada iteracin la variable ndice toma el siguiente valor, incrementndose en unaunidad. En seguida veremos que en Fortran se puede considerar incrementos mayores que la unidad e inclusonegativos.El nmero de iteraciones del bucle es N = valor nal - valor inicial +1.Dentro de las instrucciones del bucle no es legal modicar la variable ndice. Asimismo, al terminar todaslas iteraciones el valor de la variable no tiene porque tener un valor denido, por lo tanto, la utilidad de lavariable ndice se limita a la estructura de iteracin.En Fortran la estructura repetitiva se codica como sigue.DO ndice = valor inicial, valor final, incrementosentencias del bucleENDDO243.4. Estructura de iteracin.Se repitiN veces?Instruccionesdel bucleFVFigura 3.5. Estructura de iteracin.Aqu ndice es una variable entera, mientras que valor inicial, valor nal e incremento pueden ser variables,constantes o expresiones enteras y pueden ser negativos. Si incremento no se especica se asume igual a launidad. El nmero de iteraciones del bucle est dado porN = m ax [ (valor nal valor inicial +incremento)/incremento ] , 0 ,donde [ ] denota tomar la parte entera, descartando cualquier fraccin decimal. Slo si N es mayor que 0 seejecutar el bucle.Consideremos ahora los bucles condicionales. Aqu, el nmero de iteraciones no es conocido a priori, sinoque el bucle se repite mientras se cumple una determinada condicin. En este caso, la estructura iterativa sedescribe en pseudocdigo de la siguiente forma (y su diagrama de ujo se ilustra en la gura 3.6)Mientras condicin hacerinstrucciones del buclefin_mientrasLa condicin se evala antes y despus de cada iteracin del bucle. Si la condicin es verdadera lasinstrucciones del bucle se ejecutarn y, si es falsa, el control pasa a la instruccin siguiente al bucle.Si la condicin es falsa cuando se ejecuta el bucle por primera vez, las instrucciones del bucle no seejecutarn.Mientas que la condicin sea verdadera el bucle continuar ejecutndose indenidamente. Por lo tanto,para terminar el bucle, en el interior del mismo debe tomarse alguna accin que modique la condicin demanera que su valor pase a falso. Si la condicin nunca cambia su valor se tendr un bucle innito, la cual no esuna situacin deseable.En Fortan un bucle condicional se codica como sigue.DO WHILE (condicin)sentencias del bloqueENDDOdonde condicin es una expresin lgica.Fortran, adems del DO WHILE, dispone de una estructura ms general para bucles condicionales, cuyacodicacin es la siguiente:DOsentencias del bloque pre-condicinIF (condicin) EXITsentencias del bloque post-condicinENDDO25Captulo 3. Estructuras de controlCondicinInstruccionesdelbucleVFFigura 3.6. Estructura de iteracin condicional.CondicinInstruccionespre-testInstruccionespost-testVFFigura 3.7. Estructura de iteracin condicional general.El pseudocdigo correspondiente puede ser descrito como sigue (y su diagrama de ujo se ilustra en lagura 3.7):Repetirinstrucciones pre-condicinSi condicin terminar repetirinstrucciones post-condicinfin_repetirLas sentencias correspondientes tanto a los bloques previo y posterior al test de la condicin son ejecutadasindenidamente mientras la condicin sea falsa. Cuando la condicin resulta verdadera la repeticin es terminaday la ejecucin contina con la sentencia que sigue a la estructura de control. Ntese que si la condicin esverdadera cuando se inicia el bucle por primera vez, las sentencias del bloque pre-condicin sern ejecutadasuna vez y luego el control es transferido a la sentencia siguiente a la estructura, sin ejecutarse ninguna de lasinstrucciones correspondientes al bloque posterior a la condicin.Un bucle condicional DO WHILEDO WHILE (condicin)sentencias del bloqueENDDOes equivalente a un bucle condicional general de la formaDOIF (.NOT. condicin) EXITsentencias del bloqueENDDOEsto es, la condicin lgica que controla la repeticin del bucle es evaluada al comienzo del bucle y es lanegacin lgica a la condicin que controla al bucle DO WHILE.Un bucle condicional general de la formaDOsentencias del bloqueIF (condicin) EXITENDDO263.4. Estructura de iteracin.repetir las sentencias del bloque hasta que la condicin se haga verdadera. Pero debido a que la condicin severica despus de que el cuerpo del bucle se ha ejecutado, las instrucciones correspondientes se ejecutarn almenos una vez sin importar si la condicin es verdadera o falsa. Este tipo de bucle condicional es conocidocomo repetir hasta que (repeat-until).Consideremos, como ejemplo de estructura de iteracin, la determinacin de la suma de los n primerosenteros positivos, esto es, el valor de ni=1i. Aqu un bucle iterativo DO permite calcular la suma puesto elnmero de trminos a sumar es conocido de antemano. El siguiente pseudocdigo muestra el algoritmo querealiza la suma.Leer nIniciar suma = 0Desde i = 1 hasta n hacerTomar suma = suma + ifin_desdeEscribir sumaTerminarNtese la inicializacin a cero de la variablesuma utilizada como acumulador para la suma pedida. Laimplementacin en Fortran es como sigue.Cdigo 3.2. Suma de los n primeros enteros positivosPROGRAM sumar! ------------------------------------------------------------------! Se calcula la suma de los n primeros enteros positivos! ------------------------------------------------------------------! Declaracin de tipos! ------------------------------------------------------------------IMPLICIT NONEinteger :: n ! nmero de trminos a sumarinteger :: suma ! valor de la sumainteger :: i ! indice del bucle! ------------------------------------------------------------------! Entrada de datos! ------------------------------------------------------------------WRITE(*,*) Ingrese el nmero de enteros positivos a sumarREAD(*,*) n! ------------------------------------------------------------------! Bloque de procesamiento! ------------------------------------------------------------------suma = 0DO i=1,nsuma = suma + iENDDO! ------------------------------------------------------------------! Salida de datos! ------------------------------------------------------------------WRITE(*,*) Suma = , suma! ------------------------------------------------------------------! Terminar! ------------------------------------------------------------------STOPEND PROGRAM sumarConsidrese ahora el problema de determinar el primer valor n para el cual la suma ni=1 excede a 10000.En este problema no puede utilizarse un bucle DO ya que el nmero de trminos a sumar no es conocido deantemano. Es claro, entonces, que debemos utilizar un bucle condicional, tal como se muestra en el siguientepseudocdigo.27Captulo 3. Estructuras de controlIniciar n = 0Iniciar suma = 0Mientras suma10000 hacerTomar n = n +1Tomar suma = suma + nfin_mientrasEscribir nTerminarLa implementacin en Fortran de este algoritmo se muestra a continuacin.Cdigo 3.3. Determinar valor a partir del cual la suma de los n primeros enteros positivos excede un lmitePROGRAM sumar! ------------------------------------------------------------------! Se determina el primer valor de n para el cual la suma de los n! primeros enteros positivos excede a 10000.! ------------------------------------------------------------------! Declaracin de tipos! ------------------------------------------------------------------IMPLICIT noneINTEGER :: n ! nmero de trminos a sumarINTEGER :: suma ! valor de la sumaINTEGER :: limite = 10000 ! limite superior de la suma! ------------------------------------------------------------------! Bloque de procesamiento! ------------------------------------------------------------------suma = 0n = 0DO WHILE (suma 0, entonces existe una nica raz real, x1, dada por x1 = u1 +v1,dondeu1 = sign_q2 +_q2 +1/3, v1 = sign_q2_q21/3,Si = 0, tendremos tres races reales (siendo al menos dos iguales), x1 , x2 = x3, dadas porx1 = 2u1, x2 = x3 =u1dondeu1 = sign_q2_q213303.5. Implementando lo aprendido.Finalmente, si < 0, habr tres races reales (distintas) x1, x2, x3, dadas porx1 = 21/3cos_3_, x2 = 21/3cos_3+ 23_, x3 = 21/3cos_3+ 43_donde =_p327, cos=q2Teniendo en cuenta lo anterior implemente un algoritmo (y su programa) para calcular las races reales de lasecuaciones cbicas del tipo x3+ px +q = 0. Compruebe el programa con los siguientes casos triviales:x3= 0, x31 = 0, x3x = 0Finalmente, encuentre las races reales de la ecuacinx33.5292x +2.118176 = 0(Rta: Redondeado a cinco decimales, las races son x1 = 1.43167, x2 =2.1272, x3 = 0.69552)31Captulo 4ModularizacinDivide et vinces.(Divide y vencers) Julio Cesar4.1. Programacin modularFrente a un problema complejo una de las maneras ms ecientes de disear (e implementar) un algoritmopara el mismo consiste en descomponer dicho problema en subproblemas de menor dicultad y stos, a su vez,en subproblemas ms pequeos y as sucesivamente hasta cierto grado de renamiento donde cada subproblemainvolucre una sola tarea especca bien denida y, preferiblemente, independiente de los otros. El problemaoriginal es resuelto, entonces, combinando apropiadamente las soluciones de los subproblemas.En una implementacin computacional, cada subproblema es implementado como un subprograma. De estemodo el programa consta de un programa principal (la unidad del programa de nivel ms alto) que llama asubprogramas (unidades del programa de nivel ms bajo) que a su vez pueden llamar a otros subprogramas. Lagura 4.1 representa esquemticamente la situacin en un diagrama conocido como diagrama de estructura.Por otra parte en un diagrama de ujo del algoritmo, un subprograma es representado como se ilustra en lagura 4.2 el cual permite indicar que la estructura exacta del subprograma ser detallada aparte en su respectivodiagrama de ujo.Este procedimiento de dividir el programa en subprogramas ms pequeos se denomina programacinmodular y la implementacin de un programa en subprogramas que van desde lo ms genrico a lo ms33Captulo 4. ModularizacinFigura 4.1. Diagrama de estructura de un algo-ritmo o programa modularizado.Figura 4.2. Representacin de un subprogramaen un diagrama de ujo.particular por sucesivos renamientos se conoce como diseo descendente (top-down, en ingls).Un diseo modular de los programas provee la siguientes ventajas:El programa principal consiste en un resumen de alto nivel del programa. Cada detalle es resuelto en lossubprogramas.Los subprogramas pueden ser planeados, codicados y comprobados independientemente unos de otros.Un subprograma puede ser modicado internamente sin afectar al resto de los subprogramas.Un subprograma, una vez escrito, pueden ser ejecutado todas las veces que sea necesario a travs de unainvocacin al mismo.Una vez que un subprograma se ha escrito y comprobado, se puede utilizar en otro programa (reusabili-dad).No reinventar la rueda.Esta es una regla bsica de la programacin. Aqu la expresin reinventar la rueda se utiliza para referirsealasituacinenquesedesperdiciatiempoyrecursosenlaimplementacindeunasolucinaunproblema que ya ha sido resuelto apropiadamente.4.2. Funciones y subrutinas.Fortran provee dos maneras de implementar un subprograma: funciones y subrutinas. Estos subprogramaspueden ser intrnsecos, esto es, provistos por el compilador o externos1. Ya hemos mencionado (y utilizado)las funciones intrnsecas que provee el propio lenguaje. Por otra parte los subprogramas externos pueden serescritos por el propio usuario o bien formar parte de un paquete o biblioteca de subprogramas (library, eningls) desarrollado por terceros. En lo que sigue consideraremos la creacin de subprogramas externos propios.Para ello presentamos, como ejemplo, una versin modularizada del cdigo 1.1para el clculo del rea de uncrculo tratado en el captulo 1.Cdigo 4.1. Implementacin modular del cdigo para calcular el rea de un crculoPROGRAM principal!----------------------------------------! Declaracin de variables!----------------------------------------1Fortran tambin proporciona subprogramas internos, los cuales son procedimientos contenidos dentro de otra unidad de programa,pero ellos no sern considerados aqu.344.2. Funciones y subrutinas.IMPLICIT NONEREAL :: radio, area!----------------------------------------! Declaracin de subprogramas utilizados!----------------------------------------INTERFACESUBROUTINE leer_radio(radio)IMPLICIT NONEREAL, INTENT(OUT) :: radioEND SUBROUTINE leer_radioFUNCTION calcular_area(radio)IMPLICIT NONEREAL :: calcular_areaREAL, INTENT(IN) :: radioEND FUNCTION calcular_areaSUBROUTINE imprimir_area(a)IMPLICIT NONEREAL, INTENT(IN) :: aEND SUBROUTINE imprimir_areaEND INTERFACE!----------------------------------------! Invocar subprogramas!----------------------------------------CALL leer_radio(radio)area = calcular_area(radio)CALL imprimir_area(area)!----------------------------------------! Terminar!----------------------------------------STOPEND PROGRAM principalSUBROUTINE leer_radio(radio)!----------------------------------------! Declaracin de argumentos formales!----------------------------------------IMPLICIT NONEREAL, INTENT(OUT) :: radio!----------------------------------------! Ingreso de datos!----------------------------------------WRITE(*,*) Ingrese radioREAD(*,*) radio!----------------------------------------! Retornar!----------------------------------------RETURNEND SUBROUTINE leer_radioFUNCTION calcular_area(radio)!----------------------------------------! Declaracin de tipo de la funcin y! de los argumentos formales!----------------------------------------IMPLICIT NONEREAL :: calcular_areaREAL, INTENT(IN) :: radio!----------------------------------------! Declaracin de variables!----------------------------------------35Captulo 4. ModularizacinREAL, PARAMETER :: PI = 3.14159!----------------------------------------! Clculo de la funcin!----------------------------------------calcular_area = PI*radio**2!----------------------------------------! Retornar!----------------------------------------RETURNEND FUNCTION calcular_areaSUBROUTINE imprimir_area(a)!----------------------------------------! Declaracin de argumentos formales!----------------------------------------IMPLICIT NONEREAL, INTENT(IN) :: a!----------------------------------------! Salida de datos!----------------------------------------WRITE(*,*) Area =, a!----------------------------------------! Retornar!----------------------------------------RETURNEND SUBROUTINE imprimir_areaComo vemos subrutinas y funciones comparten caractersticas comunes, por cuanto son subprogramas,pero poseen tambin ciertas diferencias. Desde el punto de vista de la implementacin de un subprograma, ladiferencia fundamental entre una funcin y una subrutina es que las funciones permiten devolver un nico valora la unidad del programa (programa principal o subprograma) que la invoca mientras que una subrutina puededevolver cero, uno o varios valores. La forma sintctica de una funcin y una subrutina es como sigue:FUNCTION nombre (argumentos)declaracin de tipo de nombredeclaraciones de tiposentenciasnombre = expresinRETURNEND FUNCTION nombreSUBROUTINE nombre (argumentos)declaraciones de tiposentenciasRETURNEND SUBROUTINE nombreA continuacin detallamos las caractersticas comunes y distintivas de subrutinas y funciones.Un programa siempre tiene uno y slo un programa principal. Subprogramas, ya como subrutinas ofunciones, pueden existir en cualquier nmero.Cada subprograma es por s mismo una unidad de programa independiente con sus propias variables,constantesliteralesyconstantesconnombres. PorlotantocadaunidadtienesusrespectivassentenciasIMPLICIT NONE y de declaraciones de tipo. Ahora, mientras que el comienzo de un programa principal esdeclarado con la sentencia PROGRAM, el comienzo de una subrutina est dado por la sentencia SUBROUTINEy, para una funcin, por la sentencia FUNCTION. Cada una de estas unidades del programa se extiende hasta surespectiva sentencia END PROGRAM|SUBROUTINE|FUNCTION, la cual indica su n lgico al compilador.Los subprogramas deben tener un nombre que los identique. El nombre escogido debe seguir las reglasde todo identicador en Fortran. Ahora bien, como una funcin devuelve un valor el nombre de una funcintiene un tipo de dato asociado el cual debe, entonces, ser declarado dentro del cuerpo de la FUNCTION. Por elcontrario, al nombre de una subrutina no se le puede asignar un valor y por consiguiente ningn tipo de datoest asociado con el nombre de una subrutina.364.2. Funciones y subrutinas.Alcance de los identicadores. En Fortran los nombres del programa principal y de los subprogramas songlobales, esto es, conocidos por todas las unidades del programa. Por lo tanto, tales nombres deben ser nicos alo largo de todo el programa. Los restantes identicadores (correspondientes a nombres de variables, constantescon nombres y funciones intrnsecas) dentro de una unidad de programa son locales al mismo. Esto signicaque una unidad de programa desconoce la asociacin de un identicador con un objeto local de otra unidady por lo tanto el mismo nombre pueden ser utilizado en ambas para designar datos independientes. As, porejemplo, en nuestro cdigo, la constante con nombre PI slo es conocida por la funcin calcular_area,mientras que el identicador radio utilizado en el programa principal y dos de los subprogramas se reeren avariables distintas.El nombre del subprograma es utilizado para la invocacin del mismo. Ahora bien, una funcin es invocadautilizando su nombre como operando en una expresin dentro de una sentencia, mientras que una subrutina seinvoca en una sentencia especca que utiliza la instruccin CALL.Al invocar un subprograma el control de instrucciones es transferido de la unidad del programa que realizala invocacin al subprograma. Entonces las respectivas instrucciones del subprograma se ejecutan hasta que sealcanza una sentencia RETURN, momento en el cual el control vuelve a la unidad del programa que realiz lainvocacin. Ahora bien, en la invocacin de una funcin el control de instrucciones retorna a la misma sentenciaque realiz el llamado, mientras que en una subrutina el control retorna a la sentencia siguiente a la del llamado.La forma de compartir informacin entre una unidad de programa y el subprograma invocado es a travsde una lista de argumentos. Los argumentos pueden ya sea pasar informacin de la unidad del programa alsubprograma (argumentos de entrada), del subprograma hacia la unidad de programa (argumentos de salida) obien en ambas direcciones (argumentos de entrada/salida).Los argumentos utilizados en la declaracin de una subrutina o funcin son conocidos como argumentosformales o cticios y consisten en una lista de nombres simblicos separados por comas y encerrada entreparntesis. La lista puede contar con cualquier nmero de elementos, inclusive ninguno, pero, por supuesto,no puede repetirse ningn argumento formal. Si no hay ningn argumento entonces los parntesis pueden seromitidos en las sentencias de llamada y denicin de una subrutina, pero para una funcin, por el contrario,siempre deben estar presentes. En Fortran la distincin entre argumentos formales de entrada, salida y entrada/-salida es especicada a travs del atributo INTENT(tipo) en la sentencia de declaracin de los mismos, dondetipo puede tomar los valores IN, OUT INOUT, respectivamente. En particular en una funcin los argumentosformales son utilizados solamente como argumentos de entrada, por lo que los argumentos de la misma siempredeben ser declarados con el atributo INTENT(IN). Ntese que es el nombre de la funcin en s mismo elque es utilizado para devolver un valor a la unidad de programa que lo invoc. De este modo, el nombre deuna funcin puede ser utilizada como una variable dentro de la misma y debe ser asignada a un valor antes deque la funcin devuelva el control. Considerando nuestro ejemplo, vemos que el argumento formal radio enla denicin de la subrutina leer_radio acta como un argumento de salida, mientras que el argumentoformal a, de la subrutina imprimir_area, acta como un argumento de entrada. Por su parte en la funcincalcular_area, vemos que el argumento formal radio acta efectivamente como un dato de entrada yque la devolucin del valor de la funcin es dada por una sentencia en donde se asigna el valor apropiado acalcular_area.Los argumentos que aparecen en la invocacin de un subprograma son conocidos como argumentosactuales. La asociacin entre argumentos actuales y formales se realiza cada vez que se invoca el subprogramay de este modo se transere la informacin entre la unidad del programa y el subprograma. La correspondenciaentre los argumentos actuales y los formales se basa en la posicin relativa que ocupan en la lista. No existecorrespondencia a travs de los nombres (esto es, los nombres de variables en los argumentos formales y actualesno deben ser necesariamente los mismos, por ejemplo, en nuestro cdigo el argumento formal a de la subrutinaimprimir_area se corresponde con el argumento actual area del programa principal a travs de la llamadacorrespondiente). Pero, el tipo de dato de un argumento actual debe coincidir con el tipo de dato del argumentoformal correspondiente. Un argumento formal de salida (y de entrada/salida) es una variable en el subprogramacuyo valor ser asignado dentro del mismo y slo puede corresponderse con un argumento actual que sea una37Captulo 4. Modularizacinvariable (del mismo tipo, por supuesto) en la unidad de programa que invoca al subprograma. Un argumentoformal de entrada, por otra parte, es una variable que preserva su valor a travs de todo el subprograma y puedecorresponderse a un argumento actual de la unidad del programa que pueden ser no slo una variable sinotambin a una expresin (incluyendo una constante). Si al argumento actual es una expresin, sta es evaluadaantes de ser transferida.Pasaje por referencia.En programacin existen varias alternativas para implementar la manera en la cual los argumentos actualesy formales son transmitidos y/o devueltos entre las unidades de programa. Fortran, independientementede si los argumentos son de entrada, salida o entrada/salida, utiliza el paradigma de pasaje por referencia.En este mtodo en vez de pasar los valores de los argumentos a la funcin o subrutina (pasaje por valor ),sepasaladireccindememoriadelosargumentos.Estosignicaqueel argumentoactual yformalcomparten la misma posicin de memoria y por lo tanto, cualquier cambio que realice el subprograma en elargumento formal es inmediatamentevistoen el argumento actual. Por este motivo los argumentos queactuarn como datos de entrada deben ser declarados en el subprograma con el atributoINTENT(IN),ya que de este modo cualquier intento de modicar su valor dentro del subprograma originar un error decompilacin.Interfaz implcita y explcita. De acuerdo a la nota anterior, es claro que la lista de argumentos actualesen la llamada de un subprograma debe corresponderse con lista de argumentos formales en nmero, tipo yorden2. Ahora bien, debido a que cada subprograma externo es una entidad completamente independiente deotra (inclusive del programa principal), el compilador asume que tal correspondencia de argumentos es siemprecorrecta. Se dice entonces que los subprogramas externos tienen una interfaz implcita. Esto implica que siexiste un error de correspondencia en la invocacin del subprograma, el programa an compilar, pero generarresultados inconsistentes y errneos. Para que el compilador pueda vericar la consistencia de las llamadasa los subprogramas debe hacerse explcita las interfaces de los mismos. Una manera de proveer una interfazexplcita de un subprograma consiste en utilizar un bloque de interfaz en la unidad de programa que efecta lallamada3. La forma de un bloque de interfaz para una subrutina y funcin externas esINTERFACESUBROUTINE nombre_subrutina(argumentos)IMPLICIT NONEdeclaracin de argumentosEND SUBROUTINE nombre_subrutinaFUNCTION nombre_funcin(argumentos)IMPLICIT NONEdeclaracin de nombre_funcindeclaracin de argumentosEND FUNCTION nombre_funcinEND INTERFACEEsto es, se declaran las cabeceras (del ingls, header) de cada una de las subrutinas y funciones externasque utilizar la unidad de programa en cuestin. Ntese que la cabecera incluye solamente el nombre delsubprograma y la declaracin de los argumentos formales, por lo que no incluye la declaracin de variableslocales ni instrucciones ejecutables. El bloque de interfaz es colocado en la unidad de programa que invocaal subprograma en la parte reservada para la declaracin de tipos. El programa principal de nuestro ejemplomuestra claramente como denir una interfaz explcita para los tres subprogramas utilizados. Ntese que cadainterfaz, an cuando est contenida dentro de una unidad de programa, es una entidad separada de la misma,as que el mismo nombre de variable puede aparecer en la interfaz y la unidad de programa que la incluyesin causar ningn conicto. Con la informacin proporcionada por el bloque interfaz, el compilador puede2Fortran permite construir subprogramas con argumentos opcionales y con nombre, pero esta caracterstica avanzada no serconsiderada aqu.3Una forma alternativa de hacer explcita la interfaz de un subprograma consiste en construir un mdulo de procedimientos como sever ms adelante.384.2. Funciones y subrutinas.entonces vericar la consistencia en las llamadas de los subprogramas y en caso de error abortar la compilacinindicando el origen del mismo.Bajo circunstancias normales, las variables locales de un subprograma resultan en un estado indenido tanpronto como el control vuelve a la unidad de programa que lo llam. En aquellas (raras) circunstancias en quedebe asegurarse que una variable local preserve su valor entre sucesivas llamadas al subprograma se utiliza elatributo SAVE en la declaracin de tipo tal variable. Pero adems, cualquier variable local que es inicializadaen su declaracin de tipo preserva tambin su valor entre llamadas, sin necesidad de especicar el atributoSAVE en la misma.4.2.1. EjerciciosEjercicio 4.1Ampliar el cdigo del ejemplo implementando una funcin para calcular el permetro del crculo.Ejercicio 4.2Escribir una subrutina que permita el intercambio de dos variables reales. Explicar por qu talsubrutina funciona.Ejercicio 4.3En el plano una rotacin de ngulo alrededor del origen transforma las coordenadas (x, y) deun punto en nuevas coordenadas (x/, y/) dadas por_x/ = xcos +ysin,y/ =xsin +ycos.Implementar: (a) funciones, (b) una subrutina, para realizar tal rotacin.Ejercicio 4.4Identicar los errores cometidos en los siguientes subprogramas o en la invocacin de las mismos.PROGRAM mainIMPLICIT NONEREAL :: a,bINTERFACESUBROUTINE silly(input,output)IMPLICIT noneREAL, INTENT(IN) :: inputREAL, INTENT(OUT) :: outputEND SUBROUTINE sillyEND INTERFACE!--------------------------a = 0.0CALL silly(a,b)WRITE(*,*) a, b!--------------------------STOPEND PROGRAM mainSUBROUTINE silly(input,output)IMPLICIT NONEREAL, INTENT(IN) :: inputREAL, INTENT(OUT) :: output!--------------------------output = 2.0*inputinput = -1.0!--------------------------RETURNEND SUBROUTINE sillyPROGRAM mainIMPLICIT NONEINTERFACESUBROUTINE funny(output)IMPLICIT NONEREAL, INTENT(OUT) :: outputEND SUBROUTINE funnyEND INTERFACE!--------------------------CALL funny(1.0)!--------------------------STOPEND PROGRAM mainSUBROUTINE funny(output)IMPLICIT NONEREAL, INTENT(OUT) :: output!--------------------------output = 2.0!--------------------------RETURNEND SUBROUTINE funny39Captulo 4. ModularizacinEjercicio 4.5El siguiente ejercicio muestra que, sin una interfaz explcita, la invocacin a un subprograma conun argumento incorrecto produce resultados indeseables. Considere el siguiente programa:PROGRAM mainIMPLICIT NONEREAL :: x = 1.0CALL display(x)END PROGRAM mainSUBROUTINE display(i)IMPLICIT NONEINTEGER, INTENT(IN) :: iWRITE(*,*) iEND SUBROUTINE displayCompila el programa? Cul es el resultado obtenido? Que resultado hubiera esperado? Escriba un bloqueinterfaz para la subrutina en el programa principal y vuelva a compilar el programa. Qu se obtiene?4.3. Compilacin por separado de las unidades del programa.En la prctica parecera que las diversas unidades que conforman un programa deben ser guardadas enun nico archivo fuente para proceder a su compilacin. Ciertamente nada impide proceder siempre de estaforma. Sin embargo, es posible compilar el programa a partir de las distintas unidades que lo conforman cuandostos son guardados en archivos fuente separados. Por ejemplo, consideremos nuevamente nuestro cdigomodularizado para el clculo del rea del crculo. Asumiendo que el programa principal es guardado en elarchivo fuente area.f90 mientras que los subprogramas son guardados en los archivos leer-radio.f90,calcular-area.f90, imprimir-area.f90 respectivamente, el programa ejecutable area puede sercompilado con la siguiente lnea de comandos$ gfortran -Wall -o area area.f90 leer-radio.f90 calcular-area.f90 \imprimir-area.f90Ms an las distintas unidades pueden ser compiladas separadamente y luego unidas para generar el programaejecutable. Para ello utilizamos el compilador con la opcin -c sobre cada unidad del programa como sigue:$ gfortran -Wall -c area.f90$ gfortran -Wall -c leer-radio.f90$ gfortran -Wall -c calcular-area.f90$ gfortran -Wall -c imprimir-area.f90Estos comandos generan, para cada archivo fuente, un nuevo archivo con el mismo nombre pero con extensin.o. Estos archivos, conocidos como archivos objeto, contienen las instrucciones de mquina que corresponden alos archivos fuente. El programa ejecutable resulta de la unin de los archivos objetos (procedimiento conocidocomo linking), lo cual se logra con la siguiente lnea de comandos:$ gfortran -o area area.o leer-radio.o calcular-area.o imprimir-area.oAunque esta forma de proceder puede parecer innecesaria para pequeos programas, resulta de gran versatilidadpara la compilacin de programas que son construidos a partir de un gran nmero de subprogramas. Esto se debea que si se efectan cambios sobre unas pocas unidades del programa, slo ellas necesitan ser recompiladas.Por supuesto, para obtener el ejecutable nal, el proceso de linking debe repetirse. Todo este proceso puede serautomatizado con herramientas apropiadas como ser la utilidad make.404.4. Implementando lo aprendido.4.4. Implementando lo aprendido.Los siguientes ejercicios plantean diversos problemas. Disear un algoritmo apropiado como se indiqueimplementando su pseudocdigo (con su respectivo diagrama de ujo) para luego codicarlo en Fortran.Ejercicio 4.6Implementar un subprograma apropiado (funcin o subrutina) para expresar un ngulo dado engrados, minutos y segundos en radianes y viceversa.Ejercicio 4.7Implementar una funcin para el clculo del factorial de un nmero entero positivo, n!, el cual esdenido en forma recursiva segn:n! =_1 si n = 0,n(n1)! si n > 0.Utilizar tal funcin para determinar el factorial de los 35 primeros enteros positivos.Observacin 1: En vez del procedimiento recursivo calcular el factorial como n! = 1 2 3 (n1)n.Observacin 2: Es probable que deba implementar nuevamente la funcin para que devuelva un valor real.Explicar por qu esto es as.Ejercicio 4.8Dado dos enteros no negativos n y r con n r implementar una funcin para el clculo delcoeciente binomial_nr_=n!r!(nr)!.a) Testee la funcin calculando _10_, _42_ y _2511_.b) Utilice la funcin para imprimir las N primeras las del tringulo de Tartaglia o Pascal.Observacin: En vista de los resultados del ejercicio anterior considere no utilizar la funcin factorial. Para ellonote que:_nr_= n(n1)(n2) (nr +1)r!= n(n1)(n2) (nr +1)1 2 (r 1)r.Ejercicio 4.9Escribir una funcin que devuelva un valor lgico (esto es, verdadero o falso) segn un nmeroentero positivo dado es primo o no. Observacin: Recordar que un entero positivo p es primo si es divisibleslo por si mismo y la unidad. El mtodo ms simple para determinar si p es primo consiste en vericar si noes divisible por todos los nmeros sucesivos de 2 a p1. Debido a que el nico primo par es el 2, se puedemejorar el mtodo separando la vericacin de la divisibilidad por 2 y luego, si p no es divisible por 2, testear ladivisibilidad por los enteros impares existentes entre 3 y p1.a) Utilice la funcin para determinar los N primeros nmeros primos.b) Utilice la funcin para imprimir los factores primos de un entero positivo dado.c) Mejore la rapidez