Resumen Teoría Programación Científica Avanzada PDF
Document Details
Uploaded by Deleted User
2024
Tags
Summary
Este documento resume la teoría de programación científica avanzada, centrándose en la introducción a Fortran 66, 77 y 90. Se incluyen conceptos iniciales de informática, historia y evolución de Fortran, así como elementos del lenguaje.
Full Transcript
Teorı́a Programación Cientı́fica Avanzada December 30, 2024 1 Introducción a Fortran 1.1 Conceptos iniciales de la informática Un ordenador esta estructurado de la siguiente manera; posee una arquitectura que se divide en dos: HARDWARE y S...
Teorı́a Programación Cientı́fica Avanzada December 30, 2024 1 Introducción a Fortran 1.1 Conceptos iniciales de la informática Un ordenador esta estructurado de la siguiente manera; posee una arquitectura que se divide en dos: HARDWARE y SOFTWARE (+ sistema operativo). Se usa lenguaje máquina , y lenguajes de ensambladores. Los lenguajes de programación de alto nivel son estructurados y orientados a obje- tivos concretos, es decir que se usan los distintos lenguajes dependiendo para que. Lenguajes cronológicamente: Fortran, C, Python, C++, Java... 1.2 Historia y Evolución de Fortran El primer lenguaje de alto nivel fue Fortran 66, la primera versión de Fortran, un lenguaje de programación orientado concretamente a matemáticos y fı́sicos. Se creó en 1950. 1.2.1 Evolución Fortran 66 Fortran 77 Fortran 90 (versión usada en clase) 1.2.2 Crı́ticas a Fortran 77 Lenguaje no estructurado. No recursivo: La recursión, que es la capacidad de una función para llamarse a sı́ misma, no estaba soportada en Fortran 77, limitando la flexibilidad del lenguaje para resolver ciertos problemas de forma eficiente. Memoria dinámica: La memoria dinámica permite asignar memoria de forma flexible durante la ejecución del programa. Fortran 77 no soportaba esta caracterı́stica, mientras que versiones posteriores como Fortran 90 introdujeron esta capacidad. 1 Apuntes de Fortran Lenguaje de Programación 2024-25 Ausencia de punteros (pointers): Los punteros son variables que almacenan di- recciones de memoria, lo que permite manipular estructuras de datos complejas. Fortran 77 no tenı́a soporte para punteros, lo que limitaba la flexibilidad en la manipulación de datos dinámicos y estructuras complejas. 1.3 Elementos del lenguaje Caracteres normales: ABCDEFG... XYZ, 1234567890, Sı́mbolo de subrayado: Caracteres especiales: espacio en blanco " ", =, +, -, *, **, /, (), coma, punto, $, ‘, ", :, ! (para comentarios), %, &, ; (para separar argumentos), , ¿?, /= (significa distinto). 1.3.1 Tener cuidado con los espacios En las variables no pueden haber espacios, deben comenzar por letras y solo pueden contener (subrayados/guiones bajos), y caracteres como números después de una letra. No es igual PRINT que PR INT, cuidado con el espaciado. 1.3.2 Comandos básicos: mostrar y leer PRINT*, "texto", variable: Muestra un texto o variable. READ*, variable: Lee una variable desde la entrada estándar. SQRT(): Función para obtener la raı́z cuadrada de un número dentro de los paréntesis. 1.3.3 Compilación de programas simples sin módulos Compilación: gfortran ejemplo.f90 -o ejemplo.exe Ejecución:./ejemplo.exe 1.3.4 Forma general de un programa Fortran Los programas Fortran están divididos en lı́neas (cada lı́nea tiene un máximo de 132 caracteres). Por regla general, solo debe haber una instrucción por lı́nea; si se quieren escribir más de una, se deben separar con ; (punto y coma). Hay mucha bibliografı́a de fácil acceso para aprender más sobre Fortran. Usamos ! para poner comentarios, normalmente antes del programa, pero realmente se pueden poner en cualquier parte. 2 Apuntes de Fortran Lenguaje de Programación 2024-25 2 Tipos de datos, expresiones y asignaciones en For- tran 2.1 Definición de tipo de dato Un dato es un conjunto de valores y su representación, es decir, el tipo de dato depende de si es entero, real, carácter, valor lógico (true or false), etc. Tenemos dos tipos de datos: DATOS INTRÍNSECOS: – REAL, INTEGER, COMPLEX:: definimos el tipo de variable como estos tipos de números. Es necesario poner el tipo de dato seguido de dos puntos: INTEGER:: variable. – CHARACTER(LEN=longitud cadena):: cadena – LOGICAL:: variable (esta variable se igualará más adelante a.TRUE. o.FALSE.). DATOS DERIVADOS: – Matrices, vectores o tipos de datos definidos por el programador. 2.2 Especificaciones sobre los diferentes tipos de datos 2.2.1 Tipo de dato ENTERO Subconjunto de números enteros (el rango depende de la implementación). Un nombre que comience por una letra entre i-n es una variable entera. Se usan operadores como +, -, *, / y **. OJO! / es la división entera. Si se quiere el resto de una división, usar MOD(i,j). El número máximo que admite un entero mediante HUGE(i) o RANGE(i). Orden de operadores: el habitual, de izquierda a derecha. Uso de paréntesis para indicar otro orden. 2.2.2 Tipo de dato REAL Subconjunto de números reales (el rango depende de la implementación). Uso del punto decimal (2.48) o del formato exponencial (248E-2). Un nombre que comience por una letra entre a-h o z es una variable real. Al asignar variables reales a enteras, se convierten en números OJO!. Usando j=INT(a) es lo mismo que j=a. Usando a=REAL(j) es a=j. Uso de operadores idéntico. Orden de operadores idéntico. La potencia no puede usarse en un caso como (-2.48)**3.4. OJO! Operando un real y un entero, el resultado es real. El uso de paréntesis junto con INT y REAL previene errores. 3 Apuntes de Fortran Lenguaje de Programación 2024-25 2.2.3 Tipo de Dato COMPLEX Indicado para números complejos. Ejemplo: COMPLEX :: i, j, k. i = (3.8, 1.2); j = i**2 - (2.4, 1.8); K = SQRT(i) OJO!. Funciones especı́ficas: CONJG(), REAL(), INT(a), AIMAG(), ABS(). k = CMPLX(2,3) construye un número complejo. Si un número complejo interviene en una operación, el resultado es siempre un número complejo. 2.2.4 Tipo de Dato lógico Tipo de datos no numérico, indicado para evaluar la verdad de una expresión. Una variable lógica solo puede tener el valor verdadero (.TRUE.) o falso (.FALSE.). Se declaran con LOGICAL :: variable. Ejemplo: LOGICAL :: error = diferencia < 0, lo que hace que error tenga valor verdadero si la diferencia es menor que cero. Operadores lógicos:.NOT.,.AND.,.OR.,.EQV.,.NEQV.. Si se combinan operadores, la prelación es la misma que la indicada antes. Mejor hacerlo con paréntesis. Los operadores relacionales (como.LT.,.LE.,.GT.,.GE.,.EQ.,.NE.) no pueden aplicarse directamente a variables lógicas, ya que estas no están destinadas a ser comparadas relacionalmente. Sin embargo, los operadores lógicos (como.AND.,.OR.,.NOT.,.EQV.,.NEQV.) sı́ se utilizan para construir expresiones lógicas a partir de valores o variables lógicas. Diferencia entre = y ==: El doble igual == implica que estás comparando, mientras que un solo igual = indica que estás asignando un valor a algo. 2.2.5 Tipo de Dato Carácter Sirven para almacenar cadenas de caracteres. Se declaran como CHARACTER(longitud) :: variable. Ejemplo: CHARACTER(6) :: cadena, final. Ejemplo de uso: – cadena = "ab". – READ *, otra. – final = TRIM(cadena) // " " // TRIM(otra). – WRITE (*,*) "resultado es ", TRIM(final). 4 Apuntes de Fortran Lenguaje de Programación 2024-25 Forma general de declaración: – CHARACTER(longitud), PARAMETER :: variable = expresión. – CHARACTER(40) :: cadena = ’ojo "no usar" cosas "raras"’. – CHARACTER(40) :: cadena = "ojo ""no usar"" cosas ""raras""". Operador // para concatenar cadenas. Operadores == y /= para comparación. Funciones: – CHAR(Posición): Devuelve el carácter correspondiente al código ASCII de la posición especificada. Por ejemplo, CHAR(65) devuelve el carácter A, ya que 65 es el código ASCII de la letra A. – ICHAR(caracter): Devuelve el código ASCII del carácter dado. Por ejemplo, ICHAR(’A’) devuelve 65. – LEN(cadena): Devuelve la longitud de una cadena de caracteres. Por ejemplo, LEN("Hola") devuelve 4. Para comparar cadenas: – LGT: Devuelve.TRUE. si la primera cadena es lexicográficamente mayor que la segunda (según el orden alfabético). – LGE: Devuelve.TRUE. si la primera cadena es lexicográficamente mayor o igual que la segunda. – LLT: Devuelve.TRUE. si la primera cadena es lexicográficamente menor que la segunda. – LLE: Devuelve.TRUE. si la primera cadena es lexicográficamente menor o igual que la segunda. Subcadenas en cadenas: Son cadenas dentro de cadenas. Ejemplo: – cadena = "abcdef". – cadena(2:4) es "bcd". – cadena(4:) es "def". – cadena(:2) es "ab". 2.2.6 Tipo de Dato definido por el usuario Son tipos derivados de los tipos anteriores. Se declaran con TYPE. Ejemplo: TYPE datos. CHARACTER(40) :: nombre. INTEGER :: edad. CHARACTER(1) :: sexo. END TYPE datos. 5 Apuntes de Fortran Lenguaje de Programación 2024-25 Se definen variables de ese tipo con TYPE(datos) :: individuo. Para acceder a los componentes de individuo, usamos individuo%nombre o individuo%edad. Se pueden definir tipos derivados de otros tipos derivados. 2.2.7 Instrucciones de declaración explı́cita REAL :: cualquiercosa, declara cualquiercosa como real. INTEGER :: cualquiercosa, declara cualquiercosa como entero. Deben aparecer al principio del programa, tras PROGRAM, y antes de cualquier otra instrucción tipo. 2.2.8 REAL de DOBLE PRECISIÓN REAL(KIND=2) :: producto, diferencia. 4.65 D-9 es la doble precisión de 4.65 E-9. Usamos la doble precisión cuando trabajamos con muchas cifras significativas, bien con números muy grandes o muy pequeños. 2.2.9 IMPLICIT IMPLICIT sirve para cambiar la acción de declaración por defecto. Ejemplo: IMPLICIT REAL (b-d,p-t) y IMPLICIT INTEGER(a,e,i,o,u). (realmente el IMPLICIT no lo hemos usado en clase, ¿entra?). 3 Procedimiento intrı́nsecos en Fortran 3.1 El concepto de función El concepto más general de función matemática es: f : Cn → Cm (y1 , y2 ,... , yn ) = f (x1 , x2 ,... , xn ) Para usar una función en matemáticas hace falta: Darle un nombre (letra como sı́mbolo). Indicar el número y tipo de variables independientes. Indicar el número y tipo de variables dependientes. Indicar qué es lo que hace esa función. 6 Apuntes de Fortran Lenguaje de Programación 2024-25 El concepto de función en Programación es exactamente el mismo que en matemáticas. Una función tiene un nombre y unos argumentos. Invocándola por su nombre (llamar a la función desde un programa) y dando valores a los argumentos, nos proporciona un valor. En todos los lenguajes de programación existen funciones predefinidas (pueden usarse solo llamándolas por su nombre) y funciones definidas por el programador (para usarlas primero debe crearlas el programador). En Fortran, las funciones predefinidas se engloban en lo que se llaman procedimientos intrı́nsecos. 3.2 Procedimientos Intrı́nsecos en Fortran Los procedimientos intrı́nsecos en Fortran incluyen: Funciones predefinidas. Funciones creadas por el programador (no predefinidas). Subrutinas (tema posterior). 3.2.1 Tipos de funciones predefinidas Matemáticas. Numéricas. Carácter. Para usar funciones predefinidas, lo fundamental es conocer: El nombre de la función. Cuántos y qué tipos de parámetros pueden recibir. Cuántos y qué tipos de resultados pueden devolver. 3.2.2 Funciones Matemáticas SQRT, SIN, COS, EXP, LOG: argumento real o complejo, resultado real o complejo. LOG10, TAN, SINH, COSH, TANH, ASIN, ACOS, ATAN: solo tienen argumento real. Los ángulos siempre en radianes. 3.2.3 Funciones Numéricas MOD (módulo): argumento entero o real, resultado del mismo tipo. REAL: extrae parte real de un complejo o convierte un entero a real. ABS: argumento entero, real o complejo, resultado igual. AIMAG: argumento complejo, resultado real. 7 Apuntes de Fortran Lenguaje de Programación 2024-25 CMPLX: argumentos entero o real, resultado complejo. INT: argumento real o complejo, resultado entero. CONJG: argumento complejo, resultado complejo. 3.2.4 Funciones de Carácter LEN(cadena): Devuelve un número entero que representa la longitud total de la ca- dena de caracteres, incluidos los espacios en blanco al final. Por ejemplo, LEN("Hola ") devuelve 5. LEN TRIM(cadena): Similar a LEN, pero elimina los espacios en blanco finales antes de contar. Por ejemplo, LEN TRIM("Hola ") devuelve 4. IACHAR(caracter): Devuelve el código ASCII entero del carácter dado. Por ejem- plo, IACHAR(’A’) devuelve 65. ACHAR(código): Es la inversa de IACHAR. Dado un código ASCII (entero), devuelve el carácter correspondiente. Por ejemplo, ACHAR(65) devuelve ’A’. LGE(cadena1, cadena2): Devuelve.TRUE. si cadena1 es lexicográficamente mayor o igual que cadena2 (según el orden ASCII). Por ejemplo, LGE("Hola", "Adiós") devuelve.TRUE.. LGT(cadena1, cadena2): Devuelve.TRUE. si cadena1 es lexicográficamente mayor que cadena2. Por ejemplo, LGT("Hola", "Adiós") devuelve.TRUE.. LLE(cadena1, cadena2): Devuelve.TRUE. si cadena1 es lexicográficamente menor o igual que cadena2. Por ejemplo, LLE("Hola", "Mundo") devuelve.TRUE.. LLT(cadena1, cadena2): Devuelve.TRUE. si cadena1 es lexicográficamente menor que cadena2. Por ejemplo, LLT("Hola", "Mundo") devuelve.TRUE.. ADJUSTL(cadena): Devuelve la cadena ajustada hacia la izquierda, es decir, elimina los espacios en blanco iniciales y los rellena al final. Por ejemplo, ADJUSTL(" Hola") devuelve "Hola ". ADJUSTR(cadena): Devuelve la cadena ajustada hacia la derecha, eliminando los espacios en blanco finales y colocándolos al inicio. Por ejemplo, ADJUSTR("Hola ") devuelve " Hola". INDEX(cadena1, cadena2): Busca la primera aparición de cadena2 en cadena1. Devuelve un entero que representa la posición inicial de cadena2 dentro de cadena1. Si no se encuentra, devuelve 0. Por ejemplo, INDEX("Hola Mundo", "Mundo") de- vuelve 6. 8 Apuntes de Fortran Lenguaje de Programación 2024-25 3.3 Tabla ASCII básica Letras mayúsculas (’A’ a ’Z’) tienen valores del 65 al 90. Letras minúsculas (’a’ a ’z’) tienen valores del 97 al 122. Los números (’0’ a ’9’) tienen valores del 48 al 57. Otros caracteres, como espacios o sı́mbolos (’ ’, ’!’, ’@’, etc.), tienen valores menores que las letras. 3.4 Reglas de comparación 1. Se comparan las cadenas carácter por carácter, comenzando por el primer carácter. 2. El orden lexicográfico sigue el valor ASCII de cada carácter: Un carácter con un valor ASCII mayor hace que la cadena sea considerada mayor. Si el primer carácter de ambas cadenas es igual, se compara el siguiente, y ası́ sucesivamente. 3. Si una cadena es un prefijo exacto de la otra (por ejemplo, "Hola" y "HolaMundo"), la cadena más corta se considera menor. 4 Control de Ejecución En Fortran las instrucciones deben ejecutarse en orden secuencial. En las versiones prim- itivas esto no era ası́, lo que conducı́a a que Fortran fuera un lenguaje no estructurado. Para que Fortran sea estructurado y sea posible hacer cualquier tipo de programa, se necesitan construcciones condicionales y construcciones iterativas. Construcciones condicionales: if case Construcciones iterativas: do Construcción condicional if: Instrucción if: IF(expr.lógica) instrucción IF (r < 0 AND s < 0) t = SQRT(r * s) 9 Apuntes de Fortran Lenguaje de Programación 2024-25 Construcción if: IF (expr.lógica) THEN... ELSE IF (expr.lógica) THEN... ELSE... END IF Construcción condicional case: SELECT CASE (expresión de control) CASE (valor o lista de valores)... CASE (valor o lista de valores)... CASE DEFAULT... END SELECT Los valores deben separarse por coma (para valores discretos) o por : (para rangos continuos). Construcción iterativa do: Estructura general: DO... IF(expr.lógica) EXIT ! Para salir del bucle. OBLIGATORIA IF(expr.lógica) CYCLE ! Para reiniciar el bucle, vuelve a DO... END DO Construcción iterativa do while: DO WHILE (expr.lógica)... END DO Otra forma de usar do: DO i = j, k, incremento ! Controla el número de veces que se itera... END DO 10 Apuntes de Fortran Lenguaje de Programación 2024-25 Anidamiento de bucles do: DO i = j, k, incremento... DO s = r, t, incremento... END DO END DO STOP y PAUSE: Estas instrucciones son útiles para depurar: STOP: Detiene la ejecución del programa. PAUSE: Detiene temporalmente. Ejemplo: IF (tiempo > maximo_tiempo) STOP 5 Procedimientos, Funciones y Subrutinas Procedimientos: Subrutinas y Funciones Un programa Fortran puede ser un conjunto de programas: el principal y otros que realicen tareas especı́ficas (subrutinas). Una subrutina es un programa Fortran cuya primera lı́nea debe comenzar por SUBROUTINE en lugar de PROGRAM y finaliza con END SUBROUTINE. Desde el programa principal, las subrutinas se ejecutan con CALL. Es imprescindible usar CONTAINS y definir claramente los argumentos formales y actuales, además de las variables locales. Cuidado con el anidamiento de subrutinas. Ejemplo de Uso de Subrutinas Versión única: PROGRAM Orden INTEGER numero1, numero2 PRINT *, "Introduce 2 numeros" READ *, numero1, numero2 IF (numero1 < numero2) THEN numero1 = numero2 END IF PRINT *, "El mayor es ", numero1 END PROGRAM Orden Versión con Subrutinas: 11 Apuntes de Fortran Lenguaje de Programación 2024-25 PROGRAM Orden INTEGER numero1, numero2 CALL entrar_datos CALL ordena_datos CALL mostrar_resultado CONTAINS SUBROUTINE entrar_datos PRINT *, "Introduce 2 numeros" READ *, numero1, numero2 END SUBROUTINE entrar_datos SUBROUTINE ordena_datos IF (numero1 < numero2) THEN numero1 = numero2 END IF END SUBROUTINE ordena_datos SUBROUTINE mostrar_resultado PRINT *, "El mayor es ", numero1 END SUBROUTINE mostrar_resultado END PROGRAM Orden Ámbito de Variables El alcance de las variables puede cambiar dependiendo de su declaración en las subrutinas. Por ejemplo: PROGRAM Ambito INTEGER :: a = 1, b = 1 PRINT *, a, b CALL cambiar_a PRINT *, a, b CALL cambiar_ab PRINT *, a, b CONTAINS SUBROUTINE cambiar_a INTEGER :: b = 1 a = a + 2 b = b + 2 END SUBROUTINE cambiar_a SUBROUTINE cambiar_ab a = a + 5 b = b + 5 END SUBROUTINE cambiar_ab END PROGRAM Ambito 12 Apuntes de Fortran Lenguaje de Programación 2024-25 Funciones Las funciones se usan para calcular un valor determinado y deben devolver un valor obligatoriamente. Se declaran tras CONTAINS en el programa principal: FUNCTION Nombre (Argumento1, Argumento2,...) RESULT (VariableResultado)... END FUNCTION Nombre Ejemplo: PROGRAM Ejemplo INTEGER :: i = 3, j PRINT *, cuadrado(i) j = cuadrado(i + 2) PRINT *, j CONTAINS FUNCTION cuadrado(x) RESULT(y) INTEGER :: x, y y = x * x END FUNCTION cuadrado END PROGRAM Ejemplo Paso de Argumentos En Fortran, los argumentos se pasan siempre por referencia. Para prevenir problemas, se recomienda el uso de INTENT con IN, OUT o INOUT: INTEGER, INTENT(IN) :: x Argumentos Opcionales Es posible definir argumentos opcionales usando OPTIONAL y verificarlos con PRESENT: FUNCTION cuadrado(x, s) RESULT(y) INTEGER :: x, y INTEGER, OPTIONAL :: s y = x * x IF (PRESENT(s)) THEN y = y + s * s END IF END FUNCTION cuadrado Recursividad Fortran soporta funciones recursivas mediante la palabra clave RECURSIVE: PROGRAM recursivo INTEGER :: i READ *, i PRINT *, "El factorial es", factorial(i) 13 Apuntes de Fortran Lenguaje de Programación 2024-25 CONTAINS RECURSIVE FUNCTION factorial(x) RESULT(resultado) INTEGER, INTENT(IN) :: x INTEGER :: resultado IF (x == 0) THEN resultado = 1 ELSE resultado = x * factorial(x - 1) END IF END FUNCTION factorial END PROGRAM recursivo 6 Arrays en Fortran Usados para almacenar vectores y matrices Se declaran usando DIMENSION: REAL, DIMENSION (25) :: x, y, z INTEGER, DIMENSION (5,5) :: matriz Se puede llegar hasta 7 dimensiones. La forma de almacenar un array no se corresponde con nuestra lógica matemática. Para referirse a un elemento de un array basta con indicar su posición. Ejemplos: x(10), matriz(2,3). Inicialización de arrays INTEGER :: X(3), Y(2), Z(5) X = (/ 1, 2, 3 /) Y = 4 Z = (/ X, Y /) En este caso, Z serı́a: 1, 2, 3, 4, 4. Operaciones sobre arrays Para realizar una operación en todos los elementos de un array: – Elemento a elemento. – Operación única sobre el array completo. CHARACTER :: matriz(8), vector(8) m = v (Asignación completa). Ejemplo de lectura de un array: 14 Apuntes de Fortran Lenguaje de Programación 2024-25 INTEGER, DIMENSION :: matriz(2,4) READ *, matriz Esto es equivalente a: DO i = 1, 2 DO j = 1, 4 READ *, matriz(i,j) END DO END DO Ejemplo interesante INTEGER :: matriz(2,3) DO i = 1, 2 DO j = 1, 3 READ *, matriz(i,j) END DO END DO DO i = 1, 2 DO j = 1, 3 PRINT *, matriz(i,j) END DO END DO PRINT *, matriz READ *, matriz PRINT *, matriz Secciones de un array Declaración de un array con rangos especı́ficos: INTEGER, DIMENSION :: matriz(2010:2013, 2:6) ! Array 4x5 INTEGER, DIMENSION :: Parcial(2) Parcial = matriz(2010:2013:2, 3) Extraer una submatriz: INTEGER, DIMENSION(2:5,3:5) :: matriz INTEGER, DIMENSION(2,2) :: vector READ *, matriz vector = matriz(3:4,3:4) PRINT *, vector Arrays de cadenas Ejemplo: 15 Apuntes de Fortran Lenguaje de Programación 2024-25 CHARACTER(10) :: matriz(8) matriz(1:5) ! Cinco primeras cadenas. matriz(1)(1:5) ! Cinco primeros caracteres de la primera cadena. CHARACTER(10) :: nombre(2) READ *, nombre(1) READ *, nombre(2) PRINT *, nombre(1)(1:3) PRINT *, nombre(2)(2:4) Funciones con argumentos y resultados tipo array Ejemplo 1: PROGRAM array REAL :: aux(2) ! Cambiar a aux(5) si es necesario. READ *, aux PRINT *, doble(aux) CONTAINS FUNCTION doble(vector) RESULT(longitud) REAL :: vector(:) REAL :: longitud longitud = SQRT(SUM(vector * vector)) END FUNCTION doble END PROGRAM array Ejemplo 2: PROGRAM array REAL :: aux(3) READ *, aux PRINT *, doble(aux) CONTAINS FUNCTION doble(vector) RESULT(vector2) REAL :: vector(:), vector2(3) vector2 = vector * 3 END FUNCTION doble END PROGRAM array Ejemplo 3: PROGRAM array REAL :: aux(2,2) READ *, aux PRINT *, doble(aux) CONTAINS FUNCTION doble(vector) RESULT(vector2) REAL :: vector(:,:), vector2(2,2) vector2 = vector * 3 END FUNCTION doble END PROGRAM array 16 Apuntes de Fortran Lenguaje de Programación 2024-25 Concepto general de memoria dinámica en Fortran 1. Declaración de arrays dinámicos: REAL, ALLOCATABLE :: matriz(:,:), vector(:) CHARACTER, ALLOCATABLE, DIMENSION(:,:,:) :: cadena 2. Durante la ejecución: ALLOCATE(vector(15)) ALLOCATE(cadena(10,5,4)) 3. Especificar lı́mites de ı́ndices: ALLOCATE(cadena(1:10, 3:7, 20:23)) 4. Uso del atributo STAT: INTEGER estado ALLOCATE(vector(5), matriz(3,4), STAT = estado) El valor de estado será 0 si todo ha ido bien. 5. Ejemplo de asignación dinámica: REAL, ALLOCATABLE :: matriz(:,:), vector(:) PRINT *, "DIMENSIONES DE LA MATRIZ?" READ *, i, j ALLOCATE(matriz(i,j)) ALLOCATE(vector(j)) READ *, matriz PRINT *, matriz vector = matriz(1,:) PRINT *, vector DEALLOCATE(vector) 7. Otras Cuestiones en Fortran: Módulos Módulos Los módulos son la forma de dividir el código de un programa Fortran en varios archivos. Son ideales para realizar un programa entre un equipo de programadores. Lo habitual es: 1. El programa principal sólo contiene definiciones de variables, llamadas a fun- ciones y salidas del programa. 17 Apuntes de Fortran Lenguaje de Programación 2024-25 2. Las funciones necesarias se encuentran en uno o varios módulos (archivos difer- entes). Un módulo es un programa Fortran. La única diferencia es que comienza por MODULE nombre del módulo y finaliza con END MODULE nombre del módulo, en lugar de PROGRAM y END PROGRAM. Ejemplo de Módulos Archivo principal: ejemplo.f90 PROGRAM eje USE auxiliar INTEGER :: a, b, c READ *, a, b c = suma(a, b) PRINT *, "La suma de ", a, " y ", b, " es", c END PROGRAM eje Archivo de módulo: funcion.f90 MODULE auxiliar CONTAINS FUNCTION suma(x, y) RESULT(z) INTEGER :: x, y INTEGER :: z z = x + y END FUNCTION suma END MODULE auxiliar Para generar el programa: 1. Compilar el módulo: gfortran -c funcion.f90 Esto generará el archivo funcion.o. 2. Compilar el programa principal con el módulo: gfortran ejemplo.f90 funcion.o Esto generará el archivo ejecutable a.out. 18 Apuntes de Fortran Lenguaje de Programación 2024-25 Ejemplo de Módulos con Tipos Definidos por el Usuario Archivo: datos.f90 MODULE Tipodatos TYPE dato REAL :: a REAL :: b REAL :: resultado END TYPE dato TYPE(dato) :: r END MODULE Tipodatos Archivo: funciones.f90 MODULE auxiliar CONTAINS FUNCTION suma(x, y) RESULT(z) REAL :: x, y REAL :: z z = x + y END FUNCTION suma FUNCTION producto(x, y) RESULT(z) REAL :: x, y REAL :: z z = x * y END FUNCTION producto END MODULE auxiliar Archivo: ejemplo.f90 PROGRAM Ejemplo1 USE Tipodatos USE auxiliar READ *, r%a, r%b r%resultado = suma(r%a, r%b) PRINT *, "SUMA =", r%resultado r%resultado = producto(r%a, r%b) PRINT *, "PRODUCTO =", r%resultado END PROGRAM Ejemplo1 Para generar un ejecutable: 1. Compilar el archivo de datos: gfortran -c datos.f90 19 Apuntes de Fortran Lenguaje de Programación 2024-25 2. Compilar el archivo de funciones: gfortran -c funciones.f90 3. Compilar el programa principal: gfortran -o ejemplo.exe ejemplo.f90 datos.o funciones.o 4. Ejecutar el programa:./ejemplo.exe Ficheros Los ficheros permiten guardar datos generados por un programa Fortran en uno o varios archivos. Para trabajar con ficheros, es necesario conocer: 1. Cómo crear un archivo. 2. Cómo escribir datos en él. 3. Cómo leer datos de él. 4. Cómo cerrar un archivo. El concepto de registro es importante: Es la unidad básica de lectura y/o escritura y la define el propio programa. La lectura/escritura siempre se lleva a cabo por registro. Las 4 instrucciones básicas de Fortran para manejar archivos son: 1. OPEN 2. READ 3. WRITE 4. CLOSE Además, existen otras instrucciones complementarias que pueden ayudar en tareas especı́ficas. 20 Apuntes de Fortran Lenguaje de Programación 2024-25 Manejo de Ficheros en Fortran Abrir un Fichero: OPEN Sintaxis: OPEN(opciones) UNIT = ee: Identifica la unidad de entrada/salida (obligatorio). FILE = nom: Nombre del fichero a abrir. STATUS = tp: Estado del fichero: – ’NEW’: Crea un fichero nuevo. – ’OLD’: Abre un fichero existente. – ’UNKNOWN’: Determina automáticamente si es nuevo o existente. – ’SCRATCH’: Crea un fichero temporal. Ejemplo: OPEN(10, FILE=’DATOS.DAT’, STATUS=’OLD’) ! Abre fichero existente. OPEN(20, FILE=’RESUL.DAT’, STATUS=’NEW’) ! Crea fichero nuevo. Leer un Fichero: READ Sintaxis: READ(opciones) lista UNIT = ee: Conecta la lectura al fichero abierto con OPEN. FMT = f: Define el formato de lectura (* para formato libre). Lista: Variables a leer, separadas por comas. Ejemplo: READ(UNIT=10, *) A, B ! Lee A y B con formato libre desde el fichero. Escribir en un Fichero: WRITE Sintaxis: WRITE(opciones) lista UNIT = ee: Conecta la escritura al fichero abierto con OPEN. FMT = f: Define el formato de escritura (* para formato libre). Lista: Variables a escribir, separadas por comas. Ejemplo: WRITE(UNIT=20, *) A, B ! Escribe A y B en el fichero con formato libre. 21 Apuntes de Fortran Lenguaje de Programación 2024-25 Cerrar un Fichero: CLOSE Sintaxis: CLOSE(opciones) UNIT = ee: Unidad del fichero a cerrar (obligatorio). STATUS = st: – ’KEEP’: Mantiene el fichero después de cerrarlo. – ’DELETE’: Borra el fichero al cerrarlo. Ejemplo: CLOSE(UNIT=10) ! Cierra el fichero con unidad 10. CLOSE(20, STATUS=’DELETE’) ! Cierra y borra el fichero. Otras Sentencias para Ficheros END FILE(UNIT=ee): Marca el fin del fichero. REWIND(UNIT=ee): Posiciona la lectura/escritura al inicio del fichero. BACKSPACE(UNIT=ee): Retrocede un registro en el fichero. Ejemplos: END FILE(20) ! Marca el fin del fichero con unidad 20. REWIND(10) ! Reinicia la posición de lectura en el fichero. BACKSPACE(10) ! Retrocede un registro en el fichero. Ejemplo Completo PROGRAM TELFO INTEGER I, J, TF(4, 2) OPEN(10, FILE=’DATOS.DAT’, STATUS=’OLD’) OPEN(20, FILE=’RESUL.RES’, STATUS=’NEW’) DO I=1,4 DO J=1,2 READ(10, *) TF(I, J) ! Leer datos. WRITE(20, *) ’PISO=’, I, ’TELEFONO=’, TF(I, J) ! Escribir datos. ENDDO ENDDO CLOSE(10) CLOSE(20) END 22 Apuntes de Fortran Lenguaje de Programación 2024-25 8. Metodologı́a para el Autoaprendizaje de Cualquier Lenguaje de Programación Introducción ¿Con qué objetivo quiero aprender un lenguaje de programación nuevo? Desarrollo concreto Trabajo Otros motivos Decisión: Lenguaje X Esquema de Autoaprendizaje 1. ¿Cómo se compila un archivo con instrucciones en el lenguaje X? 2. ¿Cómo se usan/especifican todos los tipos de datos en X? Constantes y variables Operadores 3. ¿Cómo se usan/especifican las instrucciones de control en X? 4. Ejercicio: Intentar recrear programas hechos en otro lenguaje en X. Nota: ¡Con esto ya se conoce un 75% del lenguaje X! El 25% restante son las pecu- liaridades especı́ficas de X. Ejemplo: Aprender C Partiendo de Fortran 1. Diferencias Generales: Una lı́nea por instrucción: igual, pero terminando con ;. Mayúsculas y minúsculas: todo en minúsculas. PROGRAM en Fortran corresponde a int main() en C. END PROGRAM en Fortran corresponde a } en C. 2. Compilación: Fortran: gfortran archivo.f90 -o salida C: gcc archivo.c -o salida 3. Entrada y Salida: En Fortran: PRINT *, A READ *, A 23 Apuntes de Fortran Lenguaje de Programación 2024-25 En C: printf("%d", A); // Enteros scanf("%d", &A); // Enteros printf("%f", A); // Reales scanf("%f", &A); // Reales Tipos de Datos Predefinidos: – INTEGER en Fortran equivale a int en C. – REAL en Fortran equivale a float o double en C. – CHARACTER en Fortran equivale a char en C. ∗ CHARACTER(50) en Fortran equivale a char en C. Definidos por el Usuario: – TYPE nombre y END TYPE en Fortran corresponde a struct nombre {} en C. – Declaración de variables: typedef struct nombre variable; Operadores Aritméticos: – La mayorı́a son iguales entre Fortran y C. – Excepción: el operador MOD en Fortran es % en C. Relacionales: – La mayorı́a son iguales. – Excepción: /= en Fortran es != en C. Lógicos: – Cambian todos: ∗ AND en Fortran es && en C. ∗ OR en Fortran es || en C. – Además, C incluye más operadores. 24 Apuntes de Fortran Lenguaje de Programación 2024-25 Instrucciones de Control Esquemas Condicionales: – Fortran: IF (condición) THEN... ELSE... ENDIF – C: if (condición) {... } else {... } Selectores Múltiples: – Fortran: SELECT CASE (variable) CASE (valor1)... CASE (valor2)... DEFAULT... END SELECT – C: switch (variable) { case valor1:... break; case valor2:... break; default:... } Esquemas Iterativos: – Fortran: 25 Apuntes de Fortran Lenguaje de Programación 2024-25 DO i = 1, 5... END DO – C: for (i = 1; i 3)) PRINT *, "ELIGE OPCIÓN:" PRINT *, " 1. Mı́nimo" PRINT *, " 2. Múltiplo de 3" PRINT *, " 3. Salir" READ *, opcion SELECT CASE (opcion) CASE (1) ! Calcular el mı́nimo de la matriz minimo = mat(1, 1) DO i = 1, 3 DO j = 1, 2 IF (mat(i, j) < minimo) THEN minimo = mat(i, j) END IF END DO END DO ! Mostrar el resultado con formato WRITE(*, "(A20,F10.2)") "El mı́nimo es:", minimo 29 Apuntes de Fortran Lenguaje de Programación 2024-25 opcion = 0 CASE (2) ! Verificar si hay al menos un múltiplo de 3 DO i = 1, 3 DO j = 1, 2 IF (MOD(mat(i, j), 3.0) == 0) THEN verdad =.TRUE. EXIT END IF END DO END DO ! Mostrar resultado IF (verdad.EQV..TRUE.) THEN PRINT *, "Al menos hay un múltiplo de 3" ELSE PRINT *, "No hay múltiplos de 3" END IF opcion = 0 CASE (3) PRINT *, "Programa Terminado" EXIT CASE DEFAULT PRINT *, "Opción errónea, vuelva a elegir" opcion = 0 END SELECT END DO END PROGRAM matriz 30