Skip to content

Procédures : subroutines et fonctions

Subroutines et fonctions

Procédure : subroutine ou function

SUBROUTINE identificateur(arguments)
   déclarations arguments et variables locales
   instructions exécutables
END SUBROUTINE identificateur
PURE type FUNCTION identificateur(arguments)
   déclarations arguments et variables locales
   instructions exécutables
END FUNCTION identificateur

Exemples :

SUBROUTINE PLOUF(A, B)
   déclarations arguments a et b
   déclarations variables locales
   instructions exécutables
END SUBROUTINE PLOUF
PURE REAL FUNCTION F(X)
   déclaration argument x
   déclarations variables locales
   instructions exécutables
END FUNCTION F

Les trois modes de communication d'un argument

modes de communication d'un argument

Donnée de la procédure :

  • attribut intent(in)
  • non modifiable
  • obligatoire pour chaque argument d'une fonction pure

Résultat de la procédure :

  • attribut intent(out)
  • valeur initiale indéterminée

Donnée-résultat :

  • attribut intent(inout)
  • la valeur initiale vient de l'argument effectif
  • modifiable

Exemple :

pure real function foeew(t)
   real, intent(in):: t
   real, parameter:: r3les = 17.269
   real, parameter:: r4les = 35.86
   real, parameter:: rtt = 273.16

   !-----------------

   foeew = exp(r3les \* (t - rtt) / (t - r4les))
end function foeew

Correspondance arguments effectif et muet

correspondance arguments effectif et muet

Le type d'un argument effectif doit être le même que celui de l’argument muet correspondant.

Variables locales

  • Ce sont les variables déclarées dans une procédure, autres que les arguments.
  • Elles sont inaccessibles à l'extérieur de la procédure.
  • La valeur d'une variable locale est perdue d'un appel de la procédure à l'appel suivant. Une variable locale est donc non définie au début de chaque exécution de la procédure.

Appel d'une procédure

  • Pour une subroutine :
CALL identificateur(arguments effectifs)
  • Pour une fonction : identificateur(arguments effectifs) apparaît à l'intérieur d'une expression. Exemple :
print *, foeew(273.) * 100.

Modules

  • Placer chaque procédure dans un "module".
  • Choisir un nom pour le module (forcément différent du nom de la procédure).

Exemple :

module plouf_m
   implicit none
contains
   subroutine plouf(…)
      …
   end subroutine plouf
end module plouf_m

Déclarer implicit none au niveau du module plutôt que dans la procédure.

Utilisation d'une procédure de module : déclaration use.

USE nom de module, ONLY: nom de procédure

use avant les autres déclarations.

Utilisation d'une procédure de module

Argument tableau

  • Dans la procédure, seul le rang de l'argument muet tableau est déclaré. Un caractère : par dimension. Le profil est imposé par l'argument effectif.
subroutine foo(a)
   real, intent(…):: a(:, :, :)
  • À l'appel : correspondance obligatoire du rang entre arguments effectif et muet.
  • Rappel : correspondance obligatoire du type entre arguments effectif et muet (pour les arguments tableaux comme pour les arguments scalaires).
  • Possibilité dans la procédure de connaître la taille dans chaque dimension de l'argument avec la fonction size. Exemples :

real, intent(…):: x(:)
size(x)

real, intent(…):: a(:, :)
size(a, 1) et size(a, 2)

Exemple d'utilisation de size : fonction calculant le déterminant d'une matrice.

real, intent(in):: a(:, :)
if (size(a, 1) /= size(a, 2)) then
   print *, "erreur"
   stop 1
end if
  • Et si le profil du tableau est « logiquement connu » à l’écriture de la procédure ? Si le profil est contraint par la signification du tableau, déclarer quand même seulement le rang avec les caractères : et, éventuellement, programmer la contrainte en utilisant les fonctions size ou shape.

Exemple : argument tableau contenant une valeur mensuelle pour chaque mois de l'année.

integer, intent(…): ave_temper(:) ! (12)
! moyenne mensuelle de température

Éventuellement :

if (size(ave_temper) /= 12) then
   print *, "erreur"
   stop 1
end if

Argument tableau de taille inconnue à l'appel

  • Comment programmer une procédure qui a en argument un tableau dont la taille est déterminée à l'intérieur de la procédure elle-même ?
  • Exemple : une procédure qui lit dans un fichier un tableau de taille quelconque et renvoie ce tableau en argument.
  • Attribut allocatable pour l’’argument muet (et toujours un caractère “ : ” par dimension). Exemple :
real, allocatable, intent(…):: a(:,:)
  • L’argument effectif correspondant doit aussi avoir l’attribut allocatable.
  • Si l’argument muet a l’attribut intent(out) alors il est dans l’état « non alloué » au début de la procédure.

Argument optionnel

Attribut optional dans la déclaration de l'argument muet. Dans la procédure, on test si l'argument a été fourni avec la fonction intrinsèque present. Exemple :

pure real function spline(x, y, yp1, ypn)
   ! interpolation par spline cubique
   real, intent(in):: x(:), y(:)
   real, intent(in), optional:: yp1, ypn
   ! yp1 et ypn : dérivées aux bords
   ! Si une dérivée au bord est absente :
   ! dérivée seconde nulle
   …
   if (present(yp1)) then
      …
end function spline

Appel d'une procédure avec argument optionnel :

  • Rappel : nous avons vu jusqu'à maintenant la correspondance par position entre argument effectif et argument muet. Exemple :
print *, spline(u, v, 4, 8)
  • Autre possibilité : la correspondance par “mot-clef” entre argument effectif et argument muet. Elle permet de sauter un argument effectif optionnel. Le mot-clef est le nom de l'argument muet. Exemple :
print *, spline(u, v, ypn=8)

Argument procédure

Un argument d'une procédure peut être lui-même une procédure.

Exemple : fonction cherchant le zéro d'une fonction quelconque.

function rtsafe(funcd, x1, x2, xacc)

Le résultat rtsafe est la valeur de x qui annule funcd.

Déclarer l'interface de l'argument muet procédure : ses propres arguments, les propriétés du résultat si c'est une fonction. Entre interface et end interface. Exemple :

function rtsafe(funcd, x1, x2, xacc)
   interface
      real function funcd(x)
         real, intent(in):: x
      end function funcd
   end interface
   real, intent(in):: x1, x2, xacc
   real rtsafe
   …