Fortran - Procedure
UN procedureè un gruppo di istruzioni che eseguono un'attività ben definita e possono essere richiamate dal programma. Le informazioni (o dati) vengono passate al programma chiamante, alla procedura come argomenti.
Esistono due tipi di procedure:
- Functions
- Subroutines
Funzione
Una funzione è una procedura che restituisce una singola quantità. Una funzione non dovrebbe modificare i suoi argomenti.
La quantità restituita è nota come function value, ed è indicato dal nome della funzione.
Syntax
La sintassi di una funzione è la seguente:
function name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end function [name]
L'esempio seguente mostra una funzione denominata area_of_circle. Calcola l'area di un cerchio con raggio 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
Quando compili ed esegui il programma sopra, produce il seguente risultato:
The area of a circle with radius 2.0 is
12.5663710
Si prega di notare che -
Devi specificare implicit none sia nel programma principale che nella procedura.
Viene chiamato l'argomento r nella funzione chiamata dummy argument.
L'opzione risultato
Se si desidera che il valore restituito venga memorizzato con un nome diverso dal nome della funzione, è possibile utilizzare l'estensione result opzione.
È possibile specificare il nome della variabile di ritorno come -
function name(arg1, arg2, ....) result (return_var_name)
[declarations, including those for the arguments]
[executable statements]
end function [name]
Sottoprogramma
Una subroutine non restituisce un valore, tuttavia può modificare i suoi argomenti.
Syntax
subroutine name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end subroutine [name]
Chiamare una subroutine
È necessario richiamare una subroutine utilizzando il call dichiarazione.
L'esempio seguente mostra la definizione e l'uso di uno scambio di subroutine, che modifica i valori dei suoi argomenti.
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
Quando compili ed esegui il programma sopra, produce il seguente risultato:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
Specificare l'intento degli argomenti
L'attributo intent consente di specificare l'intenzione con cui vengono utilizzati gli argomenti nella procedura. La tabella seguente fornisce i valori dell'attributo intent:
Valore | Usato come | Spiegazione |
---|---|---|
in | intento (in) | Utilizzato come valori di input, non modificato nella funzione |
su | intento (fuori) | Utilizzati come valore di output, vengono sovrascritti |
dentro fuori | intent (inout) | Gli argomenti vengono utilizzati e sovrascritti |
Il seguente esempio dimostra il concetto:
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
Quando compili ed esegui il programma sopra, produce il seguente risultato:
The value of the discriminant is
17.0000000
Procedure ricorsive
La ricorsione si verifica quando un linguaggio di programmazione consente di chiamare una funzione all'interno della stessa funzione. Si chiama chiamata ricorsiva della funzione.
Quando una procedura chiama se stessa, direttamente o indirettamente, viene chiamata procedura ricorsiva. È necessario dichiarare questo tipo di procedure precedendo la parolarecursive prima della sua dichiarazione.
Quando una funzione viene utilizzata in modo ricorsivo, il result deve essere utilizzata l'opzione.
Di seguito è riportato un esempio, che calcola fattoriale per un dato numero utilizzando una procedura ricorsiva -
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
Procedure interne
Quando una procedura è contenuta all'interno di un programma, viene chiamata procedura interna del programma. La sintassi per contenere una procedura interna è la seguente:
program program_name
implicit none
! type declaration statements
! executable statements
. . .
contains
! internal procedures
. . .
end program program_name
Il seguente esempio dimostra il concetto:
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
Quando compili ed esegui il programma sopra, produce il seguente risultato:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000