next up previous contents index
Next: Programmation applicative et programmation Up: No Title Previous: Instruction conditionnelle if

Appel de fonction

      

Deux fonctions sont en jeu : la fonction appelante et la fonction appelée. La fonction appelante évalue un appel de fonction , c'est-à-dire une expression formée à partir du nom de la fonction appelée et d'une liste d'arguments placés entre << ( >> et << ) >>, par exemple pgcd(6,15). Le nombre des arguments (dans l'appel) et le nombre des paramètres (dans la définition de la fonction) doivent être identiques[*] : un appel à pgcd(6) est illégal. Le type d'un argument doit être compatible avec le type du paramètre correspondant ; si les types de l'argument et du paramètre correspondant sont numériques, une conversion implicite de l'argument vers le type du paramètre est effectuée.

L'évaluation d'un appel de fonction commence par l'évaluation de ses arguments. Par exemple,

  int a = 6, b = 9;
  int d = pgcd(a,a+b);

les arguments a et a+b sont d'abord évalués à 6 et 15. Il y a ensuite invocation de la fonction appelée. On représentera une invocation par le symbole $\to$ : main() $\to$pgcd(6,15). Il y a alors création d'un bloc d'activation   de la fonction appelée, qui a pour but l'exécution du corps de cette fonction, et dont le contenu sera détaillé un peu plus loin.

Quand l'exécution du corps de la fonction appelée est terminée, la fonction appelée retourne à la fonction appelante. Si le type du résultat de la fonction appelée est différent de void, la fonction retourne une valeur (une fonction peut retourner une valeur d'un type de base, d'un struct ou d'un pointeur d'un type quelconque, mais ne peut pas retourner une fonction ou un tableau).

La valeur retournée est celle de l'expression figurant dans l'instruction return exécutée (le corps de la fonction peut contenir plusieurs return, mais une seule sera exécutée, puisque la fonction retourne aussitôt après). Le type de cette expression doit être compatible avec le type de retour de la fonction ; si ces types sont numériques, il y a conversion implicite de la valeur de l'expression vers le type de retour : par exemple un << return 3; >> dans une fonction déclarée retourner un double ne retournera pas l'entier 3, mais le double 3.0.

On notera le retour d'une valeur v a la fonction appelée par le symbole $\stackrel{v}{\to}$ ou par $\stackrel{v}{\gets}$ : pgcd(6,15) $\stackrel{3}{\to}$ main(), ou main() $\stackrel{3}{\gets}$ pgcd(6,15).

Une procédure , c'est-à-dire une fonction dont le type du résultat est void, retourne à l'appelante, mais ne retourne pas de valeur[*].

  

Un bloc d'activation a, comme les autres objets du programme, une existence en mémoire et une durée de vie. La zone mémoire qui lui est attribuée comporte, entre autres, les objets suivants :

     

Ce bloc est placé dans une partie de la mémoire appelée la pile . La durée de vie de ce bloc est l'exécution du corps de la fonction : il est empilé à l'invocation, et dépilé au retour. Ce mode d'allocation est appelé allocation automatique , ou allocation sur la pile ; il est utilisé par Pascal comme par C, mais pas par Fortran 77.

   

Cette description des opérations réalisées lors de l'appel d'une fonction spécifie la relation entre argument (d'appel) et paramètre (de définition), ce qu'on appelle le mode de passage des arguments. C a un unique mode, qui est le passage par valeur : pour chaque paramètre d'une fonction, et pour chaque invocation, il y a création d'une variable locale dans son bloc d'activation et   initialisation de cette variable locale par la valeur de l'argument correspondant.

Les affectations à un paramètre ne peuvent donc pas modifier la valeur de l'argument correspondant. Il faudra procéder autrement si l'on souhaite réellement faire modifier la valeur d'une variable par une fonction.


next up previous contents index
Next: Programmation applicative et programmation Up: No Title Previous: Instruction conditionnelle if
Jean-Philippe Chancelier
9/29/1998