Table des matières indexe chapitre suivant

Chapitre 11 : Passage de paramètres

Tables des matières


1. R犨e des paramètres

Dans l'écriture d'un programme, il arrive fréquemment qu'on doive résoudre un même sous計roblème appliqué á des données (éventuellement) différentes. Il y a donc intérêt á définir une fois pour toutes l'algorithme de résolution sur des objets fictifs : c'est la définition d'un sous計rogramme (cfr Ch 6). Il suffit alors, pour résoudre le sous計roblème á un endroit donné du programme, d'appeler le sous計rogramme en spécifiant les objets réels sur lequel l'algorithme doit être appliqué : c'est l'appel du sous計rogramme et le passage des paramètres. Les objets fictifs sont appelés les paramètres formels. Les objets réels sont appelés les paramètres effectifs ou les arguments.
La correspondance entre les paramètres formels et les arguments est faite á l'appel du sous計rogramme par leur position respective dans la liste des paramètres formels d'une part dans la liste des arguments d'autre part.


Diagramme syntaxique

appel de fonction ou de procédure :
identificateur est le nom du sous計rogramme á appeler, et
où chaque expression désigne un paramètre effectif.

Exemple

    program exchange(input,output);
    var x,y : integer;
    procedure swap (var a,b : integer);
    var t : integer;
    begin
        t := a ; a := b ; b := t
    end; {procedure swap}
    begin
        ...
        readln (x,y);
        if x > y then swap(x,y);
        ...
    end {program exchange}.
Lors de l'appel
    swap (x,y)
du sous-programme, la correspondance est établie entre x et a d'une part, y et b d'autre part.


2. Passage des paramètres par adresse ou par valeur

Lorsqu'une variable est passée en argument á un sous-programme, on peut vouloir dans le sous-programme:

Dans le premier cas, on utilise le passage de paramètres par valeur. Dans le deuxième cas, on utilise le passage de paramètres par adresse. Le deuxième cas se distingue du premier cas par la présence du mot clé var préfixant la définition du paramètre formel dans l'en負ête du sous計rogramme (cfr Ch 6).

2.1. Passage par adresse

Exemple
Le but de la procédure

   swap (x,y)
dans l'exemple précédent est d'échanger le contenu des variables x et y. Puisqu'on veut modifier le contenu des variables x et y, il faut faire un passage de paramètres par adresse. D'où la présence du mot clé var dans la définition des paramètres a et b de l'en負ête :
   procedure swap (var a,b: integer);
Lors de l'exécution de la procédure swap (x,y), a désigne le même réceptacle que x et b désigne le même réceptacle que y.

2.2. Passage par valeur

Exemple

    program impression (input,output);
    const N = 100 ;
    type bornes = 1..N ;
         tableau = array [bornes] of real ;
    var a : tableau ;
        imin,imax : bornes ;
    procedure imprimer (x : tableau ; binf, bsup : bornes);
    var i : bornes ;
    begin
        for i := binf to bsup do write(x[i]) ;
        writeln
    end ;
    begin
        ...
        imin := 1 ;
        imax := N ;
        ...
        imprimer (a,imin,imax) ;
        ...
    end.
Le but de la procédure imprimer est d'afficher le contenu de la variable a sans en modifier la valeur. Il convient donc de faire un passage de paramètres par valeur. D'où l'absence du mot clé var dans la définition des paramètres. Il en va de même pour imin et imax.
Lors de l'exécution du programme, les paramètres x, binf et bsup, bien qu'ayant les mêmes valeurs que, respectivement, a, imin, imax, ne désignent pas les mêmes réceptacles que, respectivement, a, imin et imax. C'est pourquoi toute modification de x, binf et bsup dans le corps de la procédure est sans effet en dehors de l'exécution de la procédure.

2.3. Remarques

2.4. Règles relatives aux types des paramètres des sousprogrammes

Les règles relatives aux relations devant exister entre les types des paramètres effectifs et ceux des paramètres formels sont très sévères en PASCAL :

2.4.1. Passage par adresse

Les types doivent être synonymes ou donnés á l'aide du même identificateur de type. Ceci implique qu'on ne peut jamais définir une procédure avec une en負ête comme :

   procedure lecture (var x: array [1..N] of real)   {!!! erreur !!!}
puisque le type de l'argument effectif ne pourra jamais être identique á celui de l'argument formel. Il en va de même pour toute expression de type (cfr Ch 4.3).

2.4.2. Passage par valeur

L'argument est une expression dont le type doit être affectable (cfr Ch 8.2.2) au type du paramètre formel correspondant. Ceci explique qu'une expression de type integer peut être utilisée (c'est regrettable!) dans un appel où la définition avait spécifié un paramètre formel de type real. Cela explique aussi pourquoi on ne peut jamais définir une procédure avec une en負ête comme :

    procedure  lecture  (x:  array  [1..N] of real)  {!!! erreur !!!}
puisque le type de l'argument effectif ne pourra jamais être affectable á celui de l'argument formel. Il en va de même pour toute expression de type (cfr Ch 8.2.2).

2.4.3. Tableaux homologues

La notion de "tableaux homologues" n'existe pas en Turbo-PASCAL. Mais comme elle fait partie du PASCAL standard, elle est reprise ici pour mémoire.

Lorsqu'un tableau est passé en paramètre á un sous計rogramme, son type est entièrement "figé": on connaît le type des éléments ainsi que l'ensemble des indices et donc la taille (nombre d'éléments). Si on veut résoudre un même sous計roblème sur des tableaux de tailles différentes, les techniques vues jusqu'ici obligeraient á définir autant de sous計rogrammes qu'il y a de tableaux de tailles différentes.

Les tableaux homologues permettent de traiter tous les tableaux de tailles différentes par un même sous計rogramme. Un schéma de tableaux homologues précise le type de base du tableau et le type de l'indice, mais pas les bornes de celui苞i. Ces bornes sont représentées par deux identificateurs dont la valeur peut être utilisée dans le corps du sous計rogramme.


3. Diagrammes syntaxiques

spécification du type des paramètres :
schéma de tableau homologue :

Exemple
Déclaration d'une fonction, dont le paramètre formel est un schéma de tableau homologue á une dimension :

         
    function ps (var x,y:array[lb..ub:integer] of real): real;
    var sum: real;
        n: integer;
    begin
        sum := 0.0;
        for n := lb to ub do
            sum := sum + x[n] * y[n];
        ps := sum
    end;
Appel:
    var  u,v: array[1..10] of real;
         a,b: array[45..51] of real;
         res1,res2: real;
         ...

    res1 := ps(u,v);
    ...
    res2 := ps(a,b);
Par contre, l'appel suivant est incorrect :
    res1 := ps(a,u);
car il est impossible d'associer de façon univoque des valeurs á lb et ub.


Table des matières indexe chapitre suivant