Fortran - Procedimientos
UN procedurees un grupo de declaraciones que realizan una tarea bien definida y pueden invocarse desde su programa. La información (o datos) se pasa al programa de llamada, al procedimiento como argumentos.
Hay dos tipos de procedimientos:
- Functions
- Subroutines
Función
Una función es un procedimiento que devuelve una sola cantidad. Una función no debe modificar sus argumentos.
La cantidad devuelta se conoce como function value, y se indica con el nombre de la función.
Syntax
La sintaxis de una función es la siguiente:
function name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end function [name]
El siguiente ejemplo demuestra una función denominada area_of_circle. Calcula el área de un círculo con radio r.
program calling_func
real :: a
a = area_of_circle(2.0)
Print *, "The area of a circle with radius 2.0 is"
Print *, a
end program calling_func
! this function computes the area of a circle with radius r
function area_of_circle (r)
! function result
implicit none
! dummy arguments
real :: area_of_circle
! local variables
real :: r
real :: pi
pi = 4 * atan (1.0)
area_of_circle = pi * r**2
end function area_of_circle
Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:
The area of a circle with radius 2.0 is
12.5663710
Tenga en cuenta que -
Debes especificar implicit none tanto en el programa principal como en el procedimiento.
El argumento r en la función llamada se llama dummy argument.
La opción de resultado
Si desea que el valor devuelto se almacene con un nombre diferente al nombre de la función, puede usar el result opción.
Puede especificar el nombre de la variable de retorno como -
function name(arg1, arg2, ....) result (return_var_name)
[declarations, including those for the arguments]
[executable statements]
end function [name]
Subrutina
Una subrutina no devuelve un valor, sin embargo, puede modificar sus argumentos.
Syntax
subroutine name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end subroutine [name]
Llamar a una subrutina
Necesita invocar una subrutina usando el call declaración.
El siguiente ejemplo demuestra la definición y uso de un intercambio de subrutinas, que cambia los valores de sus argumentos.
program calling_func
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
end program calling_func
subroutine swap(x, y)
implicit none
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
Especificar la intención de los argumentos
El atributo intent le permite especificar la intención con la que se utilizan los argumentos en el procedimiento. La siguiente tabla proporciona los valores del atributo de intención:
Valor | Usado como | Explicación |
---|---|---|
en | intención (en) | Usados como valores de entrada, no cambiados en la función |
afuera | intención (fuera) | Usados como valor de salida, se sobrescriben |
En fuera | intención (inout) | Los argumentos se utilizan y se sobrescriben |
El siguiente ejemplo demuestra el concepto:
program calling_func
implicit none
real :: x, y, z, disc
x = 1.0
y = 5.0
z = 2.0
call intent_example(x, y, z, disc)
Print *, "The value of the discriminant is"
Print *, disc
end program calling_func
subroutine intent_example (a, b, c, d)
implicit none
! dummy arguments
real, intent (in) :: a
real, intent (in) :: b
real, intent (in) :: c
real, intent (out) :: d
d = b * b - 4.0 * a * c
end subroutine intent_example
Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:
The value of the discriminant is
17.0000000
Procedimientos recursivos
La recursividad ocurre cuando un lenguaje de programación le permite llamar a una función dentro de la misma función. Se llama llamada recursiva de la función.
Cuando un procedimiento se llama a sí mismo, directa o indirectamente, se denomina procedimiento recursivo. Debe declarar este tipo de procedimientos anteponiendo la palabrarecursive antes de su declaración.
Cuando una función se utiliza de forma recursiva, la result se debe utilizar la opción.
A continuación se muestra un ejemplo, que calcula el factorial para un número dado mediante un procedimiento recursivo:
program calling_func
implicit none
integer :: i, f
i = 15
Print *, "The value of factorial 15 is"
f = myfactorial(15)
Print *, f
end program calling_func
! computes the factorial of n (n!)
recursive function myfactorial (n) result (fac)
! function result
implicit none
! dummy arguments
integer :: fac
integer, intent (in) :: n
select case (n)
case (0:1)
fac = 1
case default
fac = n * myfactorial (n-1)
end select
end function myfactorial
Procedimientos internos
Cuando un procedimiento está contenido dentro de un programa, se denomina procedimiento interno del programa. La sintaxis para contener un procedimiento interno es la siguiente:
program program_name
implicit none
! type declaration statements
! executable statements
. . .
contains
! internal procedures
. . .
end program program_name
El siguiente ejemplo demuestra el concepto:
program mainprog
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
contains
subroutine swap(x, y)
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
end program mainprog
Cuando compila y ejecuta el programa anterior, produce el siguiente resultado:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000