Fortran - Procédures

UNE procedureest un groupe d'instructions qui exécutent une tâche bien définie et peuvent être appelées à partir de votre programme. Les informations (ou données) sont transmises au programme appelant, à la procédure sous forme d'arguments.

Il existe deux types de procédures -

  • Functions
  • Subroutines

Fonction

Une fonction est une procédure qui renvoie une seule quantité. Une fonction ne doit pas modifier ses arguments.

La quantité retournée est appelée function value, et il est indiqué par le nom de la fonction.

Syntax

La syntaxe d'une fonction est la suivante -

function name(arg1, arg2, ....)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

L'exemple suivant illustre une fonction nommée area_of_circle. Il calcule l'aire d'un cercle de rayon 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

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

The area of a circle with radius 2.0 is
   12.5663710

Veuillez noter que -

  • Vous devez spécifier implicit none tant dans le programme principal que dans la procédure.

  • L'argument r dans la fonction appelée est appelé dummy argument.

L'option résultat

Si vous souhaitez que la valeur renvoyée soit stockée sous un autre nom que le nom de la fonction, vous pouvez utiliser le result option.

Vous pouvez spécifier le nom de la variable de retour comme -

function name(arg1, arg2, ....) result (return_var_name)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

Sous-programme

Un sous-programme ne renvoie pas de valeur, mais il peut modifier ses arguments.

Syntax

subroutine name(arg1, arg2, ....)    
   [declarations, including those for the arguments]    
   [executable statements]  
end subroutine [name]

Appel d'un sous-programme

Vous devez appeler un sous-programme en utilisant le call déclaration.

L'exemple suivant illustre la définition et l'utilisation d'un swap de sous-programme, qui modifie les valeurs de ses arguments.

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

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000

Spécification de l'intention des arguments

L'attribut intent vous permet de spécifier l'intention avec laquelle les arguments sont utilisés dans la procédure. Le tableau suivant fournit les valeurs de l'attribut intent -

Valeur Utilisé comme Explication
dans intention (dans) Utilisé comme valeur d'entrée, non modifié dans la fonction
en dehors intention (sortie) Utilisé comme valeur de sortie, ils sont écrasés
inout intention (inout) Les arguments sont à la fois utilisés et écrasés

L'exemple suivant illustre le concept -

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

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

The value of the discriminant is
   17.0000000

Procédures récursives

La récursivité se produit lorsqu'un langage de programmation vous permet d'appeler une fonction à l'intérieur de la même fonction. Il est appelé appel récursif de la fonction.

Lorsqu'une procédure s'appelle elle-même, directement ou indirectement, on parle de procédure récursive. Vous devez déclarer ce type de procédures en précédant le motrecursive avant sa déclaration.

Lorsqu'une fonction est utilisée de manière récursive, le result l'option doit être utilisée.

Voici un exemple, qui calcule factorielle pour un nombre donné en utilisant une procédure récursive -

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

Procédures internes

Lorsqu'une procédure est contenue dans un programme, elle est appelée procédure interne du programme. La syntaxe pour contenir une procédure interne est la suivante -

program program_name     
   implicit none         
   ! type declaration statements         
   ! executable statements    
   . . .     
   contains         
   ! internal procedures      
   . . .  
end program program_name

L'exemple suivant illustre le concept -

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

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000