Programación · Lenguajes de programación
Tutorial de Fortran para principiantes
Respuesta corta
Fortran es un lenguaje compilado y de tipado estático creado para el cálculo numérico y científico. El Fortran moderno (Fortran 90 y los estándares posteriores) tiene código fuente de formato libre, módulos, arreglos dinámicos y potentes operaciones sobre arreglos completos, y los compiladores lo convierten en código máquina muy rápido. Instala el compilador gratuito gfortran, guarda el código en un archivo .f90 y compílalo con gfortran hello.f90 -o hello.
Qué es Fortran y quién lo usa
Fortran («formula translation») lo desarrolló en IBM un equipo dirigido por John Backus en la década de 1950 y es uno de los lenguajes de programación más antiguos que siguen en uso activo. Está estandarizado por ISO; entre las revisiones principales están Fortran 90, 95, 2003, 2008, 2018 y 2023. El antiguo estilo de formato fijo (FORTRAN 77 en mayúsculas, con el código empezando en la columna 7) todavía se compila, pero el código nuevo usa la sintaxis de formato libre que se muestra aquí.
Fortran se usa donde importa el cálculo numérico intensivo: modelos del tiempo y del clima, dinámica de fluidos computacional, simulaciones de física y química, y muchos programas que se ejecutan en supercomputadoras. Las versiones de referencia de las bibliotecas de álgebra lineal BLAS y LAPACK, que se usan por debajo de herramientas como NumPy y MATLAB, están escritas en Fortran.
Instala un compilador y ejecuta Hola, mundo
gfortran, parte de GCC, es gratuito y está disponible en Linux (paquete gfortran), macOS (gcc de Homebrew) y Windows (MSYS2 o WSL). ifx de Intel y LLVM Flang son otros compiladores. El Fortran Package Manager (fpm) puede crear y compilar proyectos.
program hello
implicit none
print *, "Hello, world!"
end program hellogfortran hello.f90 -o hello
./hello
# Hello, world!print * usa salida dirigida por lista, que elige el espaciado por ti (fíjate en el espacio inicial). Fortran no distingue mayúsculas de minúsculas: PRINT, Print y print son lo mismo.
Variables y tipos básicos
Todas las declaraciones van al principio de una unidad de programa, antes de las instrucciones ejecutables. Escribe siempre implicit none: sin ello, los nombres no declarados que empiezan por I a N son enteros de forma silenciosa y todos los demás son reales.
| Tipo | Declaración de ejemplo | Notas |
|---|---|---|
| integer | integer :: count = 3 | Normalmente de 32 bits; integer(int64) para 64 bits |
| real | real :: x | Normalmente de precisión simple |
| real(real64) | real(real64) :: y | Doble precisión, la opción habitual en ciencia |
| complex | complex :: z = (1.0, 2.0) | Números complejos integrados |
| logical | logical :: done = .false. | .true. / .false., operadores .and., .or., .not. |
| character | character(len=20) :: name | Cadena de longitud fija, rellenada con espacios |
program types
use, intrinsic :: iso_fortran_env, only: int64, real64
implicit none
integer :: count = 3
integer(int64) :: big = 9000000000_int64
real(real64) :: third
logical :: done = .false.
character(len=:), allocatable :: name
third = 1.0_real64 / 3.0_real64
name = "Ana"
print *, count, big, third, done, name
end program typesEl sufijo _real64 establece el kind (precisión) de un literal. Sin él, 1.0 es una constante de precisión simple, que pierde dígitos al asignarse a una variable de doble precisión.
Control de flujo
program control
implicit none
integer :: i, total, score
total = 0
do i = 1, 10
if (mod(i, 2) == 0) cycle ! skip even numbers
total = total + i
end do
print *, "sum of odd numbers:", total ! 25
score = 85
if (score >= 90) then
print *, "A"
else if (score >= 80) then
print *, "B"
else
print *, "C"
end if
select case (score)
case (90:)
print *, "excellent"
case (80:89)
print *, "good"
case default
print *, "keep going"
end select
end program controldo i = 1, 10 incluye ambos extremos, y un tercer valor opcional establece el paso (do i = 10, 1, -1). cycle salta a la siguiente iteración y exit sale del bucle. También están disponibles do while (condition) y un do simple con exit. Los comentarios empiezan con !.
Funciones, subrutinas y módulos
Fortran tiene dos tipos de procedimientos: una función devuelve un valor y se usa en expresiones; una subrutina se llama con call y devuelve resultados mediante sus argumentos. Pon los procedimientos en un módulo para que el compilador pueda comprobar cada llamada.
module geometry
implicit none
contains
function circle_area(r) result(a)
real, intent(in) :: r
real :: a
a = 3.14159 * r**2
end function circle_area
subroutine swap(a, b)
integer, intent(inout) :: a, b
integer :: tmp
tmp = a
a = b
b = tmp
end subroutine swap
end module geometry
program demo
use geometry
implicit none
integer :: x, y
x = 1
y = 2
print *, circle_area(2.0) ! about 12.566
call swap(x, y)
print *, x, y ! 2 1
end program demoLos argumentos se pasan por referencia, así que un procedimiento puede cambiar las variables de quien lo llama. intent(in), intent(out) e intent(inout) documentan y hacen cumplir lo que puede hacer cada argumento. ** es el operador de potencia.
Arreglos: la característica distintiva de Fortran
Los arreglos son centrales en Fortran. Los índices empiezan en 1 por defecto (se permite cualquier límite inferior), la aritmética funciona sobre arreglos completos sin bucles, los slices usan a(start:end) y muchas funciones intrínsecas operan directamente sobre arreglos.
program arrays
implicit none
integer :: i
real :: a(5), b(5)
real, allocatable :: c(:)
integer :: m(2, 3)
a = [(real(i), i = 1, 5)] ! 1.0 2.0 3.0 4.0 5.0
b = 2.0 * a + 1.0 ! whole-array arithmetic
print *, b(2:4) ! 5.0 7.0 9.0
print *, sum(a), maxval(b) ! 15.0 11.0
allocate(c(10))
c = 0.0
print *, size(c) ! 10
deallocate(c)
m = reshape([1, 2, 3, 4, 5, 6], [2, 3])
print *, m(2, 1) ! 2 (column-major order)
end program arraysLos arreglos multidimensionales se almacenan en orden de columnas: el primer índice cambia más rápido en memoria, lo contrario que en C. Para ir más rápido, haz que el bucle más interno recorra el primer índice. Otras funciones intrínsecas útiles son matmul, dot_product, transpose, minval y count. El Fortran moderno ofrece además bucles do concurrent y coarrays para programas paralelos.
Manejo de errores
Fortran no tiene excepciones. Las instrucciones que pueden fallar aceptan un argumento de estado: iostat para entrada y salida, stat para allocate. Comprueba el valor y reacciona; si lo omites, un error detiene el programa. error stop termina el programa con un error.
program parse
implicit none
character(len=20) :: text
integer :: n, ios
text = "abc"
read(text, *, iostat=ios) n
if (ios /= 0) then
print *, "not a number: ", trim(text)
else
print *, "n =", n
end if
end program parseLeer de una variable de tipo carácter, como arriba, se llama lectura interna y es la forma habitual de convertir una cadena en un número.
Un programa pequeño y completo: media y desviación estándar
module stats
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
pure function mean(x) result(m)
real(dp), intent(in) :: x(:)
real(dp) :: m
m = sum(x) / size(x)
end function mean
pure function std_dev(x) result(s)
real(dp), intent(in) :: x(:)
real(dp) :: s
s = sqrt(sum((x - mean(x))**2) / (size(x) - 1))
end function std_dev
end module stats
program main
use stats
implicit none
real(dp) :: values(5)
values = [2.0_dp, 4.0_dp, 4.0_dp, 5.0_dp, 7.0_dp]
print '(a, f6.3)', "mean = ", mean(values)
print '(a, f6.3)', "std dev = ", std_dev(values)
end program main
! mean = 4.400
! std dev = 1.817La declaración x(:) es un arreglo de forma supuesta, por lo que las funciones aceptan arreglos de cualquier longitud. pure promete que una función no tiene efectos secundarios. El formato '(a, f6.3)' imprime una cadena seguida de un número real de 6 caracteres de ancho con 3 decimales.
Siguientes pasos
- fortran-lang.org: la sección Learn, con un tutorial de inicio rápido y buenas prácticas.
- El manual de GNU Fortran (gfortran), para las opciones del compilador y los procedimientos intrínsecos.
- Prueba el Fortran Package Manager (fpm) para crear proyectos y usar bibliotecas como la biblioteca estándar de Fortran (stdlib).
- Compila con advertencias y comprobaciones en tiempo de ejecución mientras aprendes, por ejemplo
gfortran -Wall -fcheck=all.
Preguntas frecuentes
¿Fortran se sigue usando hoy?
Sí. Fortran sigue muy usado en computación científica y de alto rendimiento, sobre todo en simulaciones de clima, tiempo, física e ingeniería, y el estándar del lenguaje se sigue actualizando.
¿Cuál es la diferencia entre los archivos .f y .f90?
Por convención, los archivos .f y .for usan el antiguo formato fijo de FORTRAN 77, en el que las columnas importan, mientras que los archivos .f90 usan código fuente de formato libre. La extensión .f90 se usa para código de formato libre de cualquier estándar moderno, no solo de Fortran 90.
¿Por qué Fortran es rápido?
El lenguaje se diseñó para el trabajo numérico: los arreglos están integrados, las reglas de aliasing permiten a los compiladores optimizar de forma agresiva y décadas de trabajo en compiladores lo respaldan. Un C o C++ bien escrito puede alcanzar una velocidad similar.
¿Los arreglos de Fortran empiezan en 0 o en 1?
Empiezan en 1 por defecto, pero puedes elegir cualquier límite inferior; por ejemplo, real :: a(0:9) declara diez elementos indexados de 0 a 9.