&yGLJR)XHQWH 7LSRV\ (VWUXFWXUDV GH&RQWURO +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Contenidos del Curso 1.- Introducción &yGLJR IXHQWH WLSRV \ HVWUXFWXUDV GH FRQWURO 3.- Procedimientos y Módulos 4.- Proceso de vectores 5.- Punteros 6.- Nuevas características de entrada/salida 7.- Procedimientos intrínsecos 8.- Características redundantes 9.- Desarrollos futuros +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ &yGLJR)XHQWH7LSRV\ (VWUXFWXUDVGH&RQWURO m m m m m m m ËQGLFH 2.1 Formato del código fuente 2.2 Especificaciones 2.3 implicit none 2.4 Valores de clase (Kind) 2.5 Tipos derivados 2.6 Sentencias de control 2.7 Ejercicios +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Código Fuente m m m m m m Las líneas pueden tener hasta 132 caracteres Se permiten letras minúsculas Identificadores hasta 31 caracteres (incluyendo el subrayado, underscore) (El primer carácter ha de ser una letra). Usar identificadores significativos!! Se usa punto y coma (;) para separar diferentes sentencias en la misma línea Los comentarios pueden comenzar con exclamación (!) El Ampersand (&) se usa como signo de continuación m El juego de caracteres incluye + < > ; ! ?% - “ & m Nuevos operadores relacionales: < <= == /= >= +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ > )RUWUDQ Código Fuente (MHPSOR SURJUDP programa_en_formato_libre !nombres largos con subrayado ! No hay columnas especiales LPSOLFLWQRQH !Mayúsculas y minúsculas UHDO :: tx, ty, tz !Comentario final !Varias sentencias por línea tx = 1.0; ty = 2.0; tz = tx * ty; !Las líneas se pueden partir SULQW *, & tx, ty, tz HQGSURJUDP programa_en_formato_libre +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Especificaciones Una especificación es una forma (extendida) de declaración donde se colocan juntas todas las características de una entidad WLSR>>DWULEXWR@@OLVWD m El tipo puede ser integer, real, complex, logical o character con un valor de clase opcional: integer [([kind=]kind-value)] character [(actual-parameter-list)] type (type-name) m El atributo puede ser parameter private target dimension(extent-list) optional external m Se pueden inicializar especificaciones +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ public pointer allocatable intent(inout) save intrinsic variables )RUWUDQ en las Especificaciones (MHPSORV real :: a = 2.61828, b = 3.14159 ! Dos variables reales declaradas e ! inicializadas integer, parameter :: N = 100, M = 1000 ! Declaración e inicialización de dos ! constantes enteras character (len = 8) :: ch ! Declaración de una cadena de caracteres ! de longitud 8 integer, dimension(-3:5, 7) :: ia ! Declaración de un vector de enteros con ! límite inferior negativo integer, dimension(-3:5,7) :: ia, ib, ic(5,5) ! Vectores de 9x7 componentes ! Los índices de ic varían en [1,5] [1, 5] +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ implicit none m m m En Fortran77 los tipos implícitos permiten la utilización de variables no declaradas. Esto ha sido la causa de muchos errores de programación LPSOLFLW QRQH obliga a declarar todas las variables que se utilizan en un programa LPSOLFLW QRQH puede ir precedida en una unidad de programa solamente por sentencias use y format +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Valores de clase m Hay 5 tipos intrínsecos: real, integer, complex, character y logical m Cada tipo puede tener asociado un valor entero no negativo llamado el parámetro de clase de tipo (Kind). El parámetro de clase es un entero no negativo. m Se trata de una característica útil para escribir código portable que requiera una precisión numérica determinada m Los valores de clase dependen de la máquina en cuestión, pero todo procesador ha de soportar al menos 2 clases para real y complex y 1 para integer, logical y character m Hay diversas funciones intrínsecas para obtener y establecer los parámetros de clase +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Valores de clase UHDO real (kind=wp)::ra real(wp)::ra ! o bien: m Declara una variable, ra, cuya precisión está determinada por el parámetro de clase wp m Los valores de clase son dependientes del sistema m Una variable real de 8 bytes (64 bits) habitualmente tiene un valor de clase 8 ó 2 m Una variable real de 4 bytes (32 bits) habitualmente tiene un valor de clase de 4 ó 1 +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Valores de clase m La función intrínseca kind, que tiene un parámetro de cualquier tipo intrínseco devuelve la clase de tipo de su parámetro. Por ejemplo: real(kind = 2) :: x ! x declarada de clase de tipo 2 real :: y ! y declarada de clase de tipo ! por defecto integer :: i,j i = kind(x) ! i=2 j = kind(y) ! j tiene el valor por ! defecto de los reales ! El valor de j depende ! del sistema +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Valores de clase UHDO m m La función intrínseca selected_real_kind tiene dos parámetros enteros opcionales, p y r El valor p especifica el número de dígitos decimales y r especifica el mínimo rango de exponente que se desea La función selected_real_kind (p, r) devuelve el valor de clase que se ajusta o que excede los requisitos dados por p y r. Si más de un valor de clase satisface los requisitos el valor que se devuelve es el que tenga la mínima precisión decimal. Si la precisión no está disponible se retorna -1. Si el rango no está disponible, -2 http:/ / www.ccti.ull.es/ cpu/ f90/ f90_reference_manual_9.txt +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Valores de clase UHDO m El uso de kind con esta función da una gran portabilidad: integer, parameter ::idp=kind(1.0D) real(kind=idp) ::ra m La variable ra se declara de doble precisión. m Nótese que el valor de clase depende del sistema integer, parameter :: IDP = kind(1.0D) complex (kind=IDP) :: raiz1, raiz2 +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Valores de clase LQWHJHU m Los enteros habitualmente tienen 16, 32 ó 64 bits m Para declarar un entero de forma que dependa del sistema, indique el valor de clase asociado con el rango de enteros que se desea: integer, parameter :: & I8=selected_INT_kind(8) integer(kind=I8) :: ia, ib, ic m Las variables ia, ib, ic tomarán valores en el rango de al menos [-108, 108] si lo permite el procesador +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Valores de clase program mayores implicit none integer, parameter :: & I8 = selected_INT_kind(8) integer(kind=I8) :: ia print *, huge(ia), kind(ia) end program mayores m Este código imprime el mayor entero disponible para este tipo de enteros, y su valor de clase integer, parameter :: & I10 = selected_real_kind(10, 200) real(kind=I10) :: a print *, range(a), precision(a), kind(a) m Imprime el rango del exponente, los dígitos de precisión y el valor de clase de la variable a +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Tipos derivados m Son definidos por el usuario m Pueden contener diferentes tipos intrínsecos (básicos) y otros tipos derivados m Las componentes se acceden usando el símbolo (%) m El único operador predefinido para tipos derivados es el de asignación (= ) m Se pueden estudiaremos operadores) (re)definir con la +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ operadores sobrecarga )RUWUDQ (los de Tipos derivados m (MHPSORV Definición de la forma del tipo derivado: type matricula character (len=2) :: letra integer :: numero character (len=2) :: prov end type matricula m Declaración de variables de ese tipo: type(matricula) :: coche1, coche2 matricula :: coche1 !Incorrecto! m Asignar un valor constante a coche1: coche1 = matricula(’AG', 2227, ’TF') m Uso de % para asignar una componente de coche2: coche2%letra = ’BZ' +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Tipos derivados m (MHPSORV Definir un vector de un tipo derivado: type (matricula), dimension(n) :: coches m Definir un tipo derivado conteniendo otro: type household character (len=1) :: name character (len=50) :: address type(matricula) :: car end type household m Declarar una estructura de tipo household: type(household) :: myhouse m Utilizar % para referenciar una componente letra: myhouse%car%letra = ’BZ’ m Una constante de un tipo derivado: type puntos::origin=puntos(0.0, 0.0, 0.0) +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control m Fortran 90 posee tres constructores de bloque: if do case m Todos ellos pueden ser anidados y puede dárseles nombres para incrementar la legibilidad y fiabilidad +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control m LI La Forma general de un if es: [name:] if (logical expression) then block else if (logical expression) then [name] block]... [else [name] block] end if [name] (MHPSOR seleccion: if (i < 0) then call negativo else if (i==0) then seleccion call cero else select call positivo end if seleccion +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control %XFOHVGR m Forma general: [name:] do [control clause] block end do [name] m La cláusula de control puede ser: • Una cláusula de control de iteración count = inicial, final [, incr] • una cláusula de control while while (expr. logica) • ninguna +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control m %XFOHVGR Clausula de control de iteración: fils: do i = 1, n cols: do j = 1, m a(1, j) = i + j end do cols end do fils m Cláusula de control while: cierto: do while (i <= 100) ... Body of loop ... end do true +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control %XFOHVGR m Uso de exit y cycle: • Se sale de un bucle con exit • cycle transfiere control al end do • exit y cycle, por defecto se refieren al bucle más interno pero pueden referirse a un bucle con nombre +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control %XFOHVGR m Uso de exit y cycle: exter: do i = 1,n interm: do j = 1,m intern: do k = 1,l ... if (a(i,j,k)<0) exit exter if (j==5) cycle interm ! Salta fuera ! Omite j==5 y ! hace j=6 if (i==5) cycle ! ! ! ! Salta el resto Del bucle interno Y pasa a su Siguiente iteración ... end do intern end do interm end do exter +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control m %XFOHVGR Sin cláusula de control: do read(*, *) x if (x < 0) exit y = sqrt(x) ... end do m Nótese que esta forma puede tener el mismo efecto que un bucle do-while +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control m FDVH Es una forma estructurada de seleccionar diferentes opciones, dependiendo del valor de una única expresión m Sirve para reemplazar a: • Un goto calculado (Fortran77) • Repetidos if ... then ... else m Forma General: [name:] select case (expression) [case (selector)[name] block] . . . end select [name] +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control FDVH m La expresión ha de ser de tipo character, logical o integer m El selector ha de ser default o bien uno ó más valores del mismo tipo que la expresión: • Un único valor • Un rango de valores separados por : (solamente integer o character) • Una lista de valores o rangos. El valor mayor o menor del rango puede omitirse +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ Estructuras de Control FDVH m Ejemplo: colour: select case (ch) case (‘C’, ‘D’, ‘G’:’M’) colour = ‘red’ case (‘X’:) colour = ‘green’ case default colour = ‘blue’ end select colour m Por compatibilidad con Fortran77, la sentencia goto sigue estando disponible, pero es preferible usar if, do, case, exit y cycle en su lugar +HUUDPLHQWDV\/HQJXDMHVGH3URJUDPDFLyQ )RUWUDQ