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.
appel de fonction ou de procédure :
où 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.
Lorsqu'une variable est passée en argument á un sous-programme, on peut vouloir dans le sous-programme:
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.
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.
Exemple
imin := 1; imax := N; imprimer (a,1,N); imprimer (a,1,N-1); imprimer (a,imin,imax); imprimer (a,imin+1,imax div 2);
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 adresseLes 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.
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.