1. Rappel de la structure d’un programme Pascal
3. Déclarations des types en Pascal
4.1 Instruction d'affectation5. Fonctions et procédures en Pascal
4.2 Instruction de condition
4.3 Instruction d'itération while…do
4.4 Instruction d'itération repeat…until
4.5 Instruction d'itération for…do
4.6 Instruction case…of
6. Paramètres en Pascal
7. Fonction ou procédure ?6.1 Lecture seulement
6.2 Accès direct
8. Visibilités des variables
9. Variables dynamiques ou pointeurs
10. Récursivité en programmation
Nous allons utiliser une description d’un Pascal réduit à l’aide des diagrammes syntaxiques.Un programme Pascal est composé de la façon suivante :
![]()
- Soit donc d'une partie en-tête ( nom , paramètres ) :
![]()
- d'une partie corps (ou Bloc) :
![]()
- et se termine par un point :
![]()
Exemples d'en-tête :
1°) program exemple_01 ( input, output ) ;
2°) program exemple_02 ;
Le langage Pascal étant structuré, un bloc est composé de sections ou paragraphes bien séparés :
- les étiquettes ou label,
- les constantes ou const,
- les types ou type,
- les variables ou var,
- les fonctions et les procédures,
- les instructions exécutables.
![]()
En pratique un bloc Pascal contient deux parties : des déclarations et des instructions
![]()
Exemple de programme avec Bloc :
![]()
Liste de tous les opérateurs en Pascal.
Ce sont les règles de composition qui précisent la priorité retenue entre les différents opérateurs du langage. Ces priorités sont réparties en 4 niveaux :
- plus haut niveau de priorité 4 : opérateur unaire not
- niveau de priorité 3 : opérateurs multiplicatifs
- niveau de priorité 2 : opérateurs additifs
- plus bas niveau de priorité 1 : opérateurs relationnels
2.1 Les opérateurs multiplicatifs
![]()
Opérateur Types des opérandes Type du résultat
* multiplication real ou integer real ou integer * intersection Ens=set of T0 Ens=set of T0 / division real ou integer real div quotient euclidien integer integer mod reste euclidien integer integer and et logique boolean boolean
2.2 Les opérateurs additifs2.3 Les opérateurs relationnels
![]()
Opérateur Types des opérandes Type du résultat
+ addition real ou integer real ou integer + union Ens=set of T0 Ens=set of T0 - soustraction real ou integer real ou integer - différence Ens=set of T0 Ens=set of T0 or ou logique boolean boolean ATTENTION :
Lorsqu'ils sont unaires les opérateurs "+" et "-" indiquent le signe de la variable.
![]()
Opérateur Types des opérandes Type du résultat
< inférieur strict type scalaire boolean > supérieur strict type scalaire boolean <= inférieur ou égal type scalaire boolean <= inclusion large Ens=set of T0 boolean = égal type scalaire boolean = égal type pointeur boolean = égal Ens=set of T0 boolean >= supérieur ou égal type scalaire boolean >= contient large Ens=set of T0 boolean <> différent type scalaire boolean <> différent type pointeur boolean <> différent Ens=set of T0 boolean in appartient Ens=set of T0 boolean in appartient type intervalle boolean
Liste de tous les opérateurs selon le type de données en Pascal :
![]()
opérateurs sur les entiers
![]()
opérateurs sur les réels
![]()
opérateurs sur les ensembles : set of
![]()
opérateurs sur les booléens
![]()
opérateurs de comparaison sur un type T
Sert à associer un identificateur
à une valeur de constante, non modifiable dans le reste du programme.
Exemple :
program exemple_03 ;
const
x=12; <------------
constante de type integer.
a2=true;
<------------ constante de type boolean.
y='h'; <------------
constante de type char.
r2=25.36;
<------------ constante de type real.
.
.
.
Il existe 3 identificateurs
de constantes prédéfinis : True , False , et
Nil .
3. Déclarations des types en Pascal
Les types sont utilisés
pour créer de nouveaux domaines de définition de variables.
Une déclaration d'un nouveau type de données sert associer un identificateur à
un type de données, construit par l'utilisateur. Cette construction
élaborée à l'aide de constructeur de type détermine
l'ensemble des valeurs possibles des variables de ce nouveau type.
On classe les types en 3 catégories :
Type
< déclaration de type >
![]()
3.1 Déclarations des types simples
Cette déclaration est
composée des :
A) Type simple :
< Type simple >
![]()
B) Types simples / Les types scalaires ( 2 sortes ) :
Les types prédéfinis :
Les types énumérés
:
identif0 = ( identif1,identif2,....,identifk
)
Il s'agit ici d'une définition
en extension des éléments du type. Les identifn sont des constantes
symboliques du type et doivent être tous différents dans la
même énumération, et ne peuvent se retrouver ni dans
une autre énumération, ni redéfinis ailleurs.
| Ce type est doté d'une fonction spécifique : ord qui dénote le numéro d'ordre d'un élément dans l'ensemble des valeurs du type (attention l'ordre est construit de gauche à droite et la numérotation débute à la valeur 0). |
Exemple :
Type
jour = (lundi,
mardi, mercredi, jeudi, vendredi, samedi, dimanche ) ;
| lundi | mardi | mercredi | jeudi | vendredi | samedi | dimanche |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |
Ainsi :
ord(jeudi) = 3
ord( lundi) = 0
REMARQUE :
| Les types scalaires sauf
le type real bénéficient de 2 fonctions succ et pred
succ : T -----> T / succ (ai) = ai+1 (successeur dans T , lorsqu'il existe) pred : T ----->
T / pred (ai) = ai-1 (prédécesseur dans T, lorsqu'il
existe ) |
C) Types simples / Les types intervalles :
Il peut être défini
comme un intervalle fermé borné d'un autre type scalaire, sauf
real.
Exemples :
Type
jour = (lundi
, mardi , mercredi , jeudi , vendredi , samedi , dimanche ) ;
mois = 1..12
;
week_end
= vendredi..dimanche ;
lettre_min
= 'a'..'z' ;
lettre_maj
= 'A'..'Z' ;
3.2 Déclarations des types structurés
Type structuré / Tableau |
Le type tableau est défini
par le constructeur de type array[ ] of. C'est une structure homogène,
formée d'un nombre fixe de composants qui sont tous du même
type de base. Tous les composants d'un tableau sont désignés
par des indices, qui sont des expressions appartenant au type indice
du tableau.
| Un tableau est en fait une structure de donnée à accès aléatoire , c'est à dire que tous ses composants peuvent être sélectionnés et atteints de manière égale. Ils sont rangés dans l'ordre des indices. |
Un tableau à n dimensions
(un vecteur est représenté par un tableau à une dimension,
une matrice par un tableau à deux dimensions...) est défini
par n types d'indices séparés par des virgules.
| Un type indice est un type simple sauf real et integer. |
Exemple :
Type
jour = (lundi,
mardi, mercredi, jeudi, vendredi, samedi, dimanche ) ;
mois = 1..12
;
week_end =
vendredi..dimanche ;
lettre_min
= 'a'..'z' ;
lettre_maj
= 'A'..'Z' ;
tableau_01
= array[jour] of mois;
tableau_02
= array[jour] of array[1..30] of mois;
tableau_03
= array[jour,1..30] of mois;
tableau_04
= array[lettr_min,0..5,jour,boolean] of char;
var
T1 : tableau_01;
T2 : tableau_02;
T3 : tableau_03;
T4 : tableau_04;
etc.....
ATTENTION:
| Notons ici que malgré
la similitude de construction des deux types tableau_02 et tableau_03 (ce
sont des types de matrices où l'indice ligne varie dans le type jour,
et l'indice colonne varie dans le type 1..30), ce ne sont pas des types
identiques, car ils sont déclarés séparément.
Donc dans l'exemple précédent, T2 et T3 ne sont pas des tableaux du même type. |
Accès aux variables d'un type tableau
Il faut, afin de pouvoir accéder
à un composant d'un tableau, utiliser des indices obligatoirement
de même type et en même nombre qu'indiqués dans la déclaration.
Exemple : (en reprenant les déclarations précédentes)
var
T1 : tableau_01;
T2 : tableau_02;
T3 : tableau_03;
T4 : tableau_04;
m : mois;
j : jour;
k : 1..30;
L,b: boolean;
n : integer;
c : lettre_min;
Les écritures suivantes sont licites :
j:= jeudi; k:= 20; c:='f'; L:=false;
b:=true; n:=2;
T1[mardi]:= 8; T1[j]:= 10;
T2[mardi,5]:= 8; T2[mardi] [5]:=
8; T2[j,k-3]:= 8; T2[j] [k-3]:= 8;
T3[mardi,5]:= 8; T3[mardi] [5]:=
8; T3[j,k]:= 8; T3[j] [k]:= 8;
T4['t',3,samedi,true]:= 'h'; T4['t'][3][samedi][true]:=
'h';
T4[c,n+2,j,L or b]:= '+';
...... etc
Un type ensemble est défini
d'un manière extensive par le constructeur set of, le domaine
des valeurs de ses éléments par son type de base.
| le type composant est un type simple sauf real et integer. |
C'est un ensemble fini et l'on peut construire tous ses sous-ensembles :
Exemple :
Type
couleur = (noir,blanc);
ens_couleur
= set of couleur;
var
x,y,z,t : ens_couleur;
begin
x := [ ]
; <--- ensemble vide (0 élément)
y := [noir];
<--- ensemble (1 élément)
z := [blanc];
<--- ensemble (1 élément)
t := [noir,blanc];
<--- ensemble (2 éléments : maximum
possible de l'exemple)
etc.....
On peut dire en fait que le type
ens_couleur est l'ensemble P(couleur) (ensemble des parties) et que toute variable
du type ens_couleur est un sous-ensemble de P(couleur).
Type structuré / Enregistrement :
Le type enregistrement est une
collection de composants appelés champs de l'enregistrement.
Ils peuvent être d'un type quelconque sauf le type fichier. C'est
une structure hétérogène.
| Tous les identificateurs de champs d'une même structure enregistrement doivent être différents à l'intérieur de l'enregistrement. Ils permettent d'accéder directement aux éléments de l'enregistrement. |
Type structuré / Enregistrement/partie fixe :
Exemple:
Type
enregis = record
jour : (lundi,mardi,dimanche);
x,y : integer;
mois : 1..12;
T_paie : array[boolean,1..30] of real;
end;
Enregistrement/accès aux champs :
| L'accès aux champs à l'intérieur d'un enregistrement s'effectue à l'aide de l'identificateur de l'enregistrement (identif de record), puis de celui du champs (identif de champs) auquel on désire accéder, dans cet ordre, comme en désignant un chemin accédant aux éléments en écrivant de gauche à droite. |
Exemple :
Type
Tenregis =
record
jour : (lundi,mardi,dimanche);
x,y : integer;
mois : 1..12;
T_paie : array[boolean,1..31] of real;
end;
var
A : Tenregis;
begin
A.jour:=;mardi;
A.mois:=8;
A.y:=125;
A.x:=0;
A.T_paie[false,A.mois]
:= -2.37
etc.....
Ce
sont les
traductions des instructions algorithmiques
de notre langage de description formelle d'algorithme que nous avons dénommé
LDFA.
LDFA Pascal W (instruction vide) pas de traduction debut i1 ; i2; i3; ...... ; ik fin begin i1 ; i2; i3; ...... ; ik end x ¬ a x := a ; (ordre d'exécution) ; Si P alors E1 sinon E2 Fsi if P then E1 else E2
( attention défaut, pas de fermeture !)Tantque P faire E Ftant while P do E
( attention, pas de fermeture)répeter E jusquà P repeat E until P lire (x1,x2,x3......,xn ) read(fichier,x1,x2,x3......,xn )
readln(x1,x2,x3......,xn )
Get(fichier)ecrire (x1,x2,x3......,xn ) write(fichier,x1,x2,x3......,xn )
writeln(x1,x2,x3......,xn )
Put(fichier)pour x<-a jusquà b faire E Fpour for x:=a to b do E (croissant) for x:=a downto b do E (décroissant)
( attention, pas de fermeture)SortirSi P if P then Break L'affectation est applicable à tous les genres de variables du pascal sauf au type file of.
![]()
Sémantique:
- Evaluation de la partie droite (l'expression)
- Transfert de la valeur calculée dans la partie gauche (la variable)
Exemple :
program Affectation ;
type
Temperature = -20 .. 40 ;
LettreMin = ' a ' .. ' z ' ;
Jour = ( lundi , mardi , mercredi , jeudi ) ;
var
a : integer ; b : char ;
c : string ;
Temp : Temperature ; Lmin : LettreMin ;
Day : Jour ;begin
Temp := 18 ;
a := (2+Temp)*4 ;
b := 'F' ;
c := 'bon'+'jour' ;
Lmin := 'f' ;
Day := mercredi ;
end.// Après affectations :
// Temp vaut 18
// a vaut 80
// b vaut 'F'
// c vaut 'bonjour'
// Lmin vaut 'f'
// Day vaut mercredi
![]()
Dans l'instruction if, l'expression est un prédicat ( expression contenant des variables, prenant la valeur vrai ou faux), les blocs <instruction> représentent soit une instruction simple, soit une instruction composée (begin ..... end).
Sémantique:
cas du if...then
- Si l'expression est vraie, le bloc d'instruction situé après le then est exécuté et le if...then s'arrête
- Si l'expression est fausse le if...then s'arrête.
cas du if...then...else
- Si l'expression est vraie, le bloc d'instruction situé après le then est exécuté et le if...then...else s'arrête.
- Si l'expression est fausse, le bloc d'instruction situé après le else est exécuté et le if...then...else s'arrête.
Exemple :
program Condition ;
var
x, y ,z : integer ;begin
x := 10 ;
y := x*4 ;
if y>100 then z := y
else z := 0;
if z = 0 then
y := 0
x := 0 ;
end.// Exécution pas à pas :
// x vaut 10
// y vaut 40
// y>100 est false
donc z vaut 0
// z=100 est true
donc y vaut 0
// x vaut 0
(à la fin : x=0, y=0, z=0)
4.3 Instruction d'itération while…do
![]()
Dans l'instruction while…do, l'expression est un prédicat ( expression contenant des variables, prenant la valeur vrai ou faux), le blocs <instruction> représente soit une instruction simple, soit une instruction composée (begin ..... end).
Sémantique:
C'est une instruction de boucle.
- Tant que l'expression reste vraie, le bloc d'instruction est réexécuté.
- Dès que l'expression est fausse le while…do s'arrête.
C'est une boucle non finie (c-à-dire que l'on ne peut pas connaître dans les cas de figure si une boucle quelconque de ce type s'arrêtera après un nombre fini d'exécution).
Exemple :
program WhileDo ;
var
x, y : integer ;begin
x := 1 ;
y := 0 ;
while x<4 do
begin
x := x+1 ;
y := y +x
end;
writeln ('x=', x , 'y=', y)
end.
Le programme écrit :
x=4 y=9Exécution pas à pas :
x vaut 1
y vaut 0
x<4 est true
donc x vaut x+1 soit 2
et y vaut y+x soit 2
x<4 est true
donc x vaut x+1 soit 3
et y vaut y+x soit 5
x<4 est true
donc x vaut x+1 soit 4
et y vaut y+x soit 9
x<4 est false donc arrêt
(à la fin : x=4, y=9)
4.4 Instruction d'itération repeat…until
![]()
Dans l'instruction repeat…until, l'expression est un prédicat ( expression contenant des variables, prenant la valeur vrai ou faux), le blocs <instruction> représente soit une suite d'instructions simples.
Sémantique:
C'est une instruction de boucle.
- Tant que l'expression reste fausse, le bloc d'instruction est réexécuté.
- Dès que l'expression est vraie le repeat…until s'arrête.
C'est une boucle non finie (c-à-dire que l'on ne peut pas connaître dans les cas de figure si une boucle quelconque de ce type s'arrêtera après un nombre fini d'exécution).
La différence avec le while .. do réside dans le fait que le repeat ... until exécute toujours au moins une fois le bloc d'instructions avant d'évaluer l'expression booléenne alors que le while ... do évalue immédiatement son expression booléenne avant d'exécuter le bloc d'instructions.
Exemple :
program RepeatUntil ;
var
x, y : integer ;begin
x := 1 ;
y := 0 ;
repeat
x := x+1 ;
y := y +x
until x>=4;
writeln ('x=', x , 'y=', y)
end.
Le programme écrit :
x=4 y=9// Exécution pas à pas :
// x vaut 1
// y vaut 0
// on entre dans le repeat
donc x vaut x+1 soit 2
// et y vaut y+x soit 2
// x>=4 est false
donc x vaut x+1 soit 3
// et y vaut y+x soit 5
// x>=4 est false
donc x vaut x+1 soit 4
et y vaut y+x soit 9
// x>=4 est true donc arrêt
(à la fin : x=4, y=9)Ce programme fournit le même résultat que celui de la boucle while…do, car il y a une correspondance sémantique entre ces deux boucles :
repeat <instruction> until <expr>
<instruction> ;
while not<expr> do <instruction>
4.5 Instruction d'itération for…doC'est une instruction de boucle, il y a deux genres d'instructions for (for...to et for...downto)
![]()
Version for <identificateur> := <Expr1>to <Expr2> do <Instruction> :
- identificateur est une variable qui se dénomme indice de boucle.
- <Expr1> et <Expr2> sont obligatoirement des expressions du même type que la variable d'indice de boucle identificateur.
- < Instruction > est un bloc d'instruction simple ou composée (begin ..... end).
Version for <identificateur> := <Expr1> downto <Expr2> do <Instruction> :
- même signification des constituants que pour la version précédente, seul le sens de parcours différe (par valeurs croissantes pour un for...to, par valeurs décroissantes pour un for...downto).
Sémantique:
L'indice de boucle prend toutes les valeurs (par ordre croissant ou décroissant selon le genre de for) comprises entre <Expr1> et <Expr2> bornes inclues.
Tant que la valeur de l'indice de boucle ne dépasse pas
- par valeur supérieure dans le cas du for...to,
- ou par valeur inférieure dans le cas du for...downto
la valeur de <Expr2>, le bloc d'instruction est réexécuté
C'est une boucle finie (c-à-dire que l'on connaît à l'avance le nombre de tours de boucle).
Exemple :
program ForDo ;
var x, y : integer ;
begin
y :=0 ;
for x := 1 to 3 do
y := y +x
end.Exécution de chaque tour de boucle :
y vaut 0
x vaut 1 => y vaut 0+1=1
x vaut 2 => y vaut 1+2=3
x vaut 3 => y vaut 3+3=6
x vaut 4 => arrêt
(à la fin : x=4, y=6)
C'est une instruction de choix :
![]()
<expression> doit être de l'un des types : integer, char, boolean, énuméré, intervalle .
<constante> doit obligatoirement être du même type que <expression>
<Instruction> est un bloc d'instruction simple ou composée (begin ..... end).Sémantique:
C'est une instruction structurée équivalente à une série de if...then...else imbriqués. Cette instruction lorsque cela est possible, doit être préférée à un emboîtement de if...then...else dont la lisibilité n'est en fait pas optimale.
if...then...else imbriqués
case ... of équivalent
if x = 3 then E1 else
if x = 4 then E2 else
if x = 5 then E2 else
if x = 6 then E2 else
if x = -5 then E3 else Efcase x of
3 : E1 ;
4..6 : E2 ;
-5 : E3 ;
else Ef
endExemple :
program CaseOf ;
var x, y : integer ;
begin
y :=1 ;
for x := 0 to 4 do
case x+1 of
0..3 : y :=y*2 ;
4 : y := y+100
else y:=0 ;
end
end.
y vaut 1
Exécution du case dans la boucle :
x vaut 0 => x+1 vaut 1 (dans 0..3) => y vaut 1*2=2
x vaut 1 => x+1 vaut 2 (dans 0..3) => y vaut 2*2=4
x vaut 2 => x+1 vaut 3 (dans 0..3) => y vaut 4*2=8
x vaut 3 => x+1 vaut 4 => y vaut 8+100=108
x vaut 4 => x+1 vaut 5 (else) => y vaut 0
x vaut 5 => arrêt
( à la fin : x=4, y=0 )
Le langage Pascal a été conçu à l'origine comme un langage pédagogique d'implantation de la programmation de type algorithmique; grâce à son extension objet Delphi il est utilisé comme outil de développement professionnel en entreprise.
La programmation algorithmique est une programmation hiérarchisée descendante
![]()
Cette décomposition descendante hiérarchique est construite à l'aide de blocs de programme notés aussi des sous-programmes.
Un bloc comporte donc des données locales, du code (instructions ou corps du bloc), des données d'entrée et/ou des données de sortie (permettant les échanges d'informations entre les différents blocs de la hiérarchie) :
![]()
L'exemple ci-après représente trois blocs B1, B2 et B3 échangeant des informations (en fait chacun calcule la somme des deux entiers qu'il reçoit en entrée et renvoie leur somme :
![]()
Le bloc B1 reçoit en entrée 12 et 15 et renvoie la somme 12+15 = 27 vers le bloc B2, la valeur 27 devient une donnée d'entrée pour le bloc B2 qui reçoit comme autre entrée la valeur 10. Le bloc B2 renvoie vers le bloc B3 le résultat 27+10 = 37 etc...
Nous remarquons que chaque bloc est indépendant des autres blocs. La seule liaison qui intervienne ici se situe dans le passage des données d'un bloc vers un autre bloc. Le code et les données locales d'un bloc fixé sont inaccessibles aux autres blocs.
En pascal les blocs sont implémentés soit par des fonctions :
![]()
En pascal les blocs sont implémentés aussi par des procédures :
![]()
Voici la syntaxe de déclaration des procédures en Pascal :
![]()
Voici la syntaxe de déclaration des fonctions en Pascal :
![]()
- <identificateur> est le nom de la procédure ou de la fonction (choisi par vous)
- <liste de paramètres> est soit vide, soit elles contient entre parenthèses et séparés par des point-virgules la liste des paramètres formels.
- <bloc> est une instruction composée (begin ..... end).
- <identificateur de type>, dans le cas d'une fonction représente le type du résultat renvoyé par la fonction.
Exemples de déclarations avec et sans paramètres formels :
procedure Somme (x,y :integer; var z :integer) ;
begin
z := x +y
end ;function Somme (x,y :integer): integer ;
begin
result := x +y
end ;procedure Somme ;
var x, y : integer ;
begin
y :=1 ; x := 2;
writeln( x+y)
end ;function Somme : integer ;
var x, y : integer ;
begin
y :=1 ; x := 2;
result := x +y
end ;6. Paramètres en Pascal
On s’intéresse dans ce paragraphe aux rapports qu’il y a entre un programme appelant et un sous-programme appelé uniquement en Pascal.Soit par exemple une procédure B ayant 3 paramètres formels et renvoyant dans le troisième paramètre la somme des deux premiers :
![]()
![]()
Les paramètres formels d'une procédure jouent le rôle de variables muettes et servent à décrire le fonctionnement d'une procédure. Ils ont la même utilisation qu'une variable dans un polynôme mathématique. Les deux écritures P(x) = 3x2 - 4x + 5 et P(t) = 3t2 - 4t + 5 représentent mathématiquement le même polynôme, il en est de même pour une procédure.
On peut changer tous les paramètres formels d'une procédure sans en changer son fonctionnement.
Les deux déclarations ci-dessous sont identiques :
procedure B (x , y :integer; var t :integer) ;
begin
t := x +y
end ;
procedure B (a , b integer; var c :integer) ;
begin
c := a +b
end ;L'intérêt pratique d'une procédure et en général d'un sous-programme est essentiellement de pouvoir exécuter toujours la même action mais avec des valeurs différentes.
Par exemple une procédure P qui utilise une autre procédure B qui effectue la somme de deux entiers. La procédure B fonctionne comme une sorte de boîte noire qui reçoit deux valeurs en entrée et qui retourne leur somme comme dans le pseudo-code ci-dessous :
Lignes fictives de code de la procédure P utilisant la boîte noire (procédure B)
![]()
La boîte "faire la somme" est utilisée une première fois pour sommer 5 et 8, puis plus loin elle est utilisée une deuxième fois pour sommer -2 et 105.
Le mécanisme qui permet d'utiliser la procédure B dans le code de la procédure P se dénomme l'appel de procédure. P se dénomme la procédure appelante.
Reprenons l'exemple du polynôme écritures P(x) = 3x2 - 4x + 5 , nous savons qu'en donnant une valeur effective à la variable x (par exemple x = 2) on obtient un résultat noté P(2) qui vaut: P(x) = 3.22 - 4.2 + 5 = 9.
L'appel de procédure est un procédé très semblable au calcul du polynôme sur une valeur. La procédure a besoin qu'on lui fournisse des variables contenant effectivement des valeurs. De telles variables se dénomment les paramètres effectifs de la procédure.
Précisons un peu plus l'utilisation d'une procédure S avec des variables. Supposons que S serve à calculer la somme de deux valeurs 5 et 8 contenues respectivement dans deux variables locales a et b d'une autre procédure nommée P dont le seul paramètre x renvoie le résultat 13 du calcul obtenu par appel de la procédure B dans le code de la procédure P :
![]()
L'appel S(a,b,x) s'effectue sur des paramètres effectifs qui sont nécessairement des variables existantes, soit déclarées dans un paragraphe var dans la zone des données locales, soit déclarées en tant que paramètres de la procédure appelante.
L'appel se fait avec un nombre de paramètres effectifs ègal à celui des paramètres formels en respectant l'ordre et la cohérence des types. On peut imaginer que lors d'un appel à la procédure S par le code de la procédure S, le code de la procédure S vient s'imbriquer fictivement dans le code de P à l'endroit de l'appel avec comme variables les paramètres effectifs :
![]()
Comment a lieu cet appel, cette inclusion fictive du code ?
On dénomme l'action qui consiste à appeler sur des paramètres effectifs, le passage des paramètres effectifs ou encore la transmission des paramètres effectifs.
Il faut savoir qu’un paramètre effectif transmis au sous-programme appelé est un moyen d’utiliser ou d’accéder à une information appartenant au bloc appelant (le bloc appelé peut être le même que le bloc appelant, il s’agit alors de récursivité).
Pascal ne dispose que de 2 modes de passage sur les 5 modes généraux :
- Le passage par valeur,
- le passage par référence ou adresse.
6.1 Lecture seulement : passage par valeur
Dans un passage par valeur, le paramètre formel est considéré comme une variable locale dans le corps du sous-programme. Sa valeur est initialisée au début de chaque exécution du sous-programme avec la valeur du paramètre effectif correspondant.
Il y a recopie de la valeur du paramètre effectif dans une zone spécifique locale à la procédure. Toutes les opérations qui sont effectuées sur le paramètre formel n’affectent que cette valeur locale.
Ecriture en Pascal procedure sp(... x: real ....)
![]()
passage par valeur
6.2 Accès direct : passage par adresse ou par référenceDans un passage par adresse le paramètre formel est traité comme une variable dont l’adresse qui est transmise au moment de chaque appel, est celle du paramètre effectif correspondant. L’adresse de la variable effective autorise toutes les modifications immédiatement sur cette variable quelle que soit sa localisation.
Ecriture en Pascal procedure sp (....var x : real .....)
![]()
passage par référence
Comparaison des avantages et des inconvénients des 2 modes
Passage par valeur :
- Avantage : sécurité et protection des informations.
- Inconvénient : lenteur due à la recopie des données et doublement de la place mémoire occupée (mais convient bien pour des variables simples !).
Passage par référence :
- Avantage : rapidité d’accès aux données, moindre occupation mémoire puisqu’il ne s’agit que d’une adresse.
- Inconvénient : ce mode est dangereux à cause de la non protection des données et de la nécessité qu’il y a de connaître la façon dont sont implantées physiquement les données sur la machine.
Ces deux modes de passage des paramètres sont présents dans des langages comme C++, java, Ada, Visual-Basic .net, Delphi et C#. Ils suffit donc pour le débutant, de bien comprendre le processus avec le pascal et par analogie il pourra l'utiliser avec les autres langages.
Exemple :
procedure B1 (x : integer; var y : integer) ;
begin
y := 10*x
end ;
Dans la procédure B1
x est passé par valeur