Table des matières indexe chapitre suivant

Chapitre 12 : Procédures et fonctions

Tables des matières


1. Différence entre procédure et fonction

Une fonction ne se distingue d'une procédure que par le fait qu'elle renvoie une valeur. Tout ce qui a été dit á propos du passage des paramètres est valable pour les procédures et fonctions. Dans ce qui suit, on insiste sur les spécificités des fonctions.


2. Renvoi d'une valeur par une fonction

Le renvoi de cette valeur se fait selon le mécanisme suivant : lors de toute exécution d'une fonction, une instruction d'affectation ayant comme identificateur de variable l'identificateur de la fonction doit être exécutée (il peut y en avoir plusieurs); la valeur de la dernière expression affectée á l'identificateur de la fonction est la valeur renvoyée par la fonction. Le type de la valeur renvoyée est le type spécifié par l'identificateur de type de l'en­tête de la fonction (cfr Ch 6). Ce type peut être un type simple ou un type pointeur.

Notes

  1. Le mécanisme décrit est la seule manière de renvoyer la valeur d'une fonction.
  2. C'est le seul cas, avec l'appel récursif de la fonction (cfr Ch 14) où l'on peut utiliser l'identificateur de la fonction dans la partie instruction de sa déclaration.
Puisqu'une fonction renvoie une valeur, l'appel de la fonction ne peut avoir lieu que dans une expression.

Exemple
Recherche séquentielle d'un élément dans un vecteur (où bornes est le type 1..N, et tableau le type array [bornes] of integer).

 
    function recherche (x : tableau; e : integer) : Boolean;
    var i : bornes;
        trouve : Boolean;
    begin
        trouve := false;
        i := 1;
        while (i <= N) and not trouve do
            if x [i] = e then trouve := true
                         else i := i + 1;
        recherche := trouve
    end; {function recherche}
On remarque :
  1. la valeur renvoyée par la fonction est de type Boolean comme indiqué dans l'en­tête.
  2. l'identificateur de la fonction apparaît bien dans une partie gauche d'une instruction d'affectation.
  3. l'affectation "recherche := trouve" sera toujours exécutée, que l'élément recherché soit trouvé ou non; la fonction renverra toujours bien une valeur.
  4. l'affectation "recherche := trouve" affecte une valeur booléenne á l'identificateur de la fonction, ce qui concorde avec le type présent dans l'en­tête de la fonction.
  5. l'utilisation de la variable "trouve" est indispensable. En effet, on n'aurait pas pu écrire
        begin
            recherche := false; {correct}
            i := 1;
            while (i <= n) and not recherche {incorrect} do
                if x[i] = e then recherche := true {correct}
                            else i := i + 1
        end;
    L'apparition de l'identificateur de fonction dans une expression comme
        (i <= n) and not recherche
    s'apparenterait á un appel récursif, ce qui ici


3. Effet de bord

Tout ce qui concerne les paramètres dans le Chapitre 1 de cette Partie est valable aussi bien pour les procédures que pour les fonctions. Il est donc possible de passer des paramètres d'une fonction par adresse. Dès lors, une fonction peut modifier les variables qui lui sont passées en argument. Tant les procédures que les fonctions peuvent modifier les variables qui leur sont globales (cfr Ch 13). Les deux derniers types de modification sont appelés des effets de bord du sous­programme. Il est fortement déconseillé d'en faire usage car cela rend généralement la compréhension du programme plus difficile. De plus, la réutilisation d'un tel programme dans un autre contexte (dans un autre programme) est compromise, car ce nouveau programme doit contenir les mêmes variables globales.


4. Usage des procédures et fonctions comme paramètres

Le premier chapitre de cette Partie présente le passage de paramètres selon deux schémas : passage par valeur et passage par adresse.
Une troisième classe est autorisée en Pascal : les procédures et les fonctions peuvent être passées en paramètres á un sous-programme.
Lors de la déclaration du sous­programme, en Pascal standard, l'en­tête devra contenir dans la liste des paramètres formels un ou des en­têtes de procédures ou de fonctions, suivant les diagrammes syntaxiques donnés en Ch 6.1

En Turbo-PASCAL, il est également possible de passer des sous-programmes en paramètre, mais la syntaxe de déclaration n'est pas celle qui vient d'être évoquée. On doit en effet utiliser la syntaxe suivante qui est propre au Turbo-PASCAL :

Notation :
par la suite, le paramètre formel (procédure ou fonction) dont l'en­tête apparaît dans la liste des paramètres d'un sous­programme sera appelé "paramètre procédural". L'usage de procédures et de fonctions comme paramètres permet de généraliser leur emploi et d'écrire des sous­programmes dont l'effet est déterminé á l'exécution.

Exemple
Déclaration d'une procédure qui calcule et imprime une succession de valeurs que prend une fonction réelle en x, pour x variant entre une borne inférieure réelle binf jusqu'á une borne supérieure réelle bsup par pas de delta :

    procedure table ( function f (x : real) : real; binf, bsup, delta : real);
    var abs : real ;
        j : integer ;
    begin
        abs := binf;
        for j := 0 to trunc((bsup-binf)/delta) do
        begin
            writeln(abs,f(abs));
            abs := abs + delta
        end
    end;
Appel :
    table (EXP, 0.0, 1.0, 0.01);
    table (MYSIN, 0.0, 10.0, 0.5);
    table (F, a, b, step);
où EXP, MYSIN et F sont des fontions dont l'en­tête est de la forme
    function ... (val : real) : real 
et où a, b, step sont des variables de type real.

Remarque : les paramètres effectifs, lors de l'appel d'un sous­ programme ayant pour paramètre formel une fonction, ne peuvent pas être des fonctions prédefinies (cfr Partie I), comme par exemple sin ou cos.

Règles relatives au passage des fonctions et procédures en paramètres
La liste des paramètres formels du paramètre procédural et la liste des paramètres formels de la fonction ou procédure qui apparaît parmi les arguments lors de l'appel doivent correspondre, c'est­á­dire respecter les règles suivantes :

  1. Les deux listes doivent avoir le même nombre de paramètres formels; plus précisément :
    1. le nombre de paramètres passés par valeur doit être le même; ces paramètres doivent être de même type et doivent occuper les mêmes positions dans la liste des paramètres formels
    2. le nombre de paramètres passés par adresse doit être le même; ces paramètres doivent être de même type et doivent occuper les mêmes positions dans la liste des paramètres formels.
  2. Les paramètres formels peuvent être des paramètres procéduraux avec des listes de paramètres formels qui correspondent (selon les règles 1,2 et 3); les positions occupées par ces paramètres procéduraux doivent être les mêmes dans les deux listes.
  3. Les paramètres formels peuvent spécifier le même nombre de tableaux homologues (cfr Ch 11.2.4.3) de mêmes types de base et d'indice, de même degré de compactage (packed) et occupant les mêmes positions dans la liste des paramêtres formels.
Aucune règle ne porte sur les identificateurs dénotant les paramètres formels dans les deux listes.


Table des matières indexe chapitre suivant
Free Web Hosting