Académique Documents
Professionnel Documents
Culture Documents
Thierry Lacoste
27 octobre 2007
Nous abordons deux questions :
1. Comment est introduit un nom pour un objet ?
2. Dans quelle partie du programme existe-t-il ?
1
Chapitre 1
Déclarations d’objets et
affectation
I : Integer;
P : Integer := 13;
2
I, J, K : Integer;
P, Q, R : Integer := 13;
I : Integer;
J : Integer;
K : Integer;
P : Integer := 13;
Q : Integer := 13;
R : Integer := 13;
⋆
Cette remarque est importante surtout lorsqu’une initialisation fait inter-
venir un appel de fonction.
Exemple :
Nous aurons donc trois appels à la fonction Sqrt. Si l’appel est coûteux, on
préfèrera écrire :
⋆
Notre remarque est importante surtout lorsque la fonction appelée lors
de l’initialisation comporte des effets de bord, c’est à dire si elle modifie
l’état de variables globales ou des périphériques.
Exemples :
3
1. Si la fonction Sqrt1 imprime un message, voire l’exécution bord1.log2
du programme bord1.adb3 comparée à l’exécution bord1bis.log4 du
programme bord1bis.adb5 .
2. Si on veut compter le nombre d’appels à une fonction, il faut procéder
par effet de bord. Voire l’exécution bord2.log6 du programme bord2.adb7
comparée à l’exécution bord2bis.log8 du programme bord2bis.adb9 .
1.2 Affectation
L’instruction d’affectation permet de donner une (nouvelle) valeur à une
variable.
Exemple :
I := 36;
P := P + Q;
Remarque. Le symbole := peut être suivi de toute expression produisant
une valeur du type de la variable à laquelle elle doit être affectée.
⋆
Une variable de type Integer peut être vue comme une boı̂te qui contient
à tout moment une valeur de type Integer.
Cette valeur peut être changée et c’est d’ailleurs le rôle de l’affectation.
Exemple :
P := I;
I := I+1;
Les variables n’ont pas le même sens selon qu’elles se trouvent à gauche
ou à droite du symbole :=.
1. une variable à gauche de l’affectation est la cible de l’affectation.
2. lorsqu’une variable apparaı̂t dans une expression à droite d’une affec-
tation, sa signification est la valeur qu’elle contient au moment où l’ex-
pression est évaluée.
Dans le langage Caml, les références sont l’équivalent des variables de
Ada. Caml interdit la confusion entre la variable I et sa valeur qui s’écrit !I.
Ainsi, les deux affectations ci-dessus s’écrive :
P := !I;
I := !I+1;
4
1.3 Les constantes
Une constante se déclare comme une variable ; il faut insérer le mot réservé
constant après le deux-points.
Exemple :
Toute tentative d’affectation d’un tel objet sera rejetée par le compilateur.
5
Chapitre 2
Blocs et portées
Les déclarations, qui introduisent des objets, doivent précéder les instruc-
tions qui manipulent ces objets.
Rappel : Les déclarations et les instructions apparaissent dans des endroits
différents du programme. Nous parlerons de
– partie déclarative pour toute zone où il est possible de déclarer des
objets et de
– partie instructions pour une zone où il est possible d’écrire des ins-
tructions.
Exemple : Le bloc declare est une instruction qui introduit les deux types
de zones.
declare
I : Integer := 0; -- Declarations
begin
I := I + 1; -- Instructions
end;
6
2.1 Portée et visibilité
Comme d’autres langages à structure de bloc, Ada possède la notion
d’occultation : la définition d’un identificateur dans une portion de pro-
gramme y cache toute éventuelle définition précédente de ce même identifi-
cateur.
Exemple : Voire bloc1.adb10 et son exécution bloc1.log11 .
Définitions :
1. La portée d’une entité est la région de texte dans laquelle l’entité est
potentiellement visible ;
2. l’entité est visible en un point si l’on peut se servir de son nom pour
s’y référer.
⋆
Il est possible de nommer un bloc. Si la déclaration d’un objet en masque
une autre, on peut se référer à l’objet masqué en utilisant (avec la notation
pointée) le nom du bloc où il est déclaré.
Voire bloc2.adb12 et son exécution bloc2.log13 .
Attention ! Dans le cas où un bloc est nommé, il est impératif de répeter
son nom après son end final.
⋆
Style : Il est conseillé de choisir un identificateur d’autant plus grand que
sa portée est grande. En effet,
– Il est dangeureux d’avoir une variable globale comme I ou X. Le risque
d’une fausse manipulation d’une telle variable est grand.
– Il est inutile de choisir un identificateur long si sa portée n’est que de
quelques lignes.
7
Notes
1
fichier : Ada/Bord/sqrt.adb
with Io;
function Sqrt (X : Natural) return Integer is
R : Natural;
begin
Io.Put ("Entrée dans Sqrt : X = "); Io.Put (X); Io.Put (". ");
R := 0;
while (R + 1) ** 2 <= X loop
R := R + 1;
end loop;
Io.Put ("Sortie de Sqrt"); Io.New_Line;
return R;
end Sqrt;
2
fichier : Ada/Bord/bord1.log
$ ./bord1
Entrée dans Sqrt : X = 2000. Sortie de Sqrt
Entrée dans Sqrt : X = 2000. Sortie de Sqrt
Entrée dans Sqrt : X = 2000. Sortie de Sqrt
A = 44
B = 44
C = 44
3
fichier : Ada/Bord/bord1.adb
with Io;
with Sqrt;
procedure Bord1 is
A, B, C : Integer := Sqrt (2000);
begin
Io.Put ("A = "); Io.Put (A); Io.New_Line;
Io.Put ("B = "); Io.Put (B); Io.New_Line;
Io.Put ("C = "); Io.Put (C); Io.New_Line;
end Bord1;
4
fichier : Ada/Bord/bord1bis.log
8
$ ./bord1bis
Entrée dans Sqrt : X = 2000. Sortie de Sqrt
A = 44
B = 44
C = 44
5
fichier : Ada/Bord/bord1bis.adb
with Io;
with Sqrt;
procedure Bord1bis is
A : Integer := Sqrt (2000);
B, C : Integer := A;
begin
Io.Put ("A = "); Io.Put (A); Io.New_Line;
Io.Put ("B = "); Io.Put (B); Io.New_Line;
Io.Put ("C = "); Io.Put (C); Io.New_Line;
end Bord1bis;
6
fichier : Ada/Bord/bord2.log
$ ./bord2
Compteur = 3
A = 44
B = 44
C = 44
7
fichier : Ada/Bord/bord2.adb
with Io;
procedure Bord2 is
Compteur : Integer := 0;
9
while (R + 1) ** 2 <= X loop
R := R + 1;
end loop;
return R;
end Sqrt;
begin
Io.Put ("Compteur = "); Io.Put (Compteur); Io.New_Line;
Io.Put ("A = "); Io.Put (A); Io.New_Line;
Io.Put ("B = "); Io.Put (B); Io.New_Line;
Io.Put ("C = "); Io.Put (C); Io.New_Line;
end Bord2;
8
fichier : Ada/Bord/bord2bis.log
$ ./bord2bis
Compteur = 1
A = 44
B = 44
C = 44
9
fichier : Ada/Bord/bord2bis.adb
with Io;
procedure Bord2bis is
Compteur : Integer := 0;
10
A : Integer := Sqrt (2000);
B, C : Integer := A;
begin
Io.Put ("Compteur = "); Io.Put (Compteur); Io.New_Line;
Io.Put ("A = "); Io.Put (A); Io.New_Line;
Io.Put ("B = "); Io.Put (B); Io.New_Line;
Io.Put ("C = "); Io.Put (C); Io.New_Line;
end Bord2bis;
10
fichier : Ada/Declare/bloc1.adb
with Io;
procedure Bloc1 is
begin
declare
I, J : Integer;
begin
I := 0;
J := 1_000_000;
Io.Put (" I = "); Io.Put (I); Io.New_Line;
declare
I : Integer;
begin
I := J - 1;
Io.Put (" I = "); Io.Put (I); Io.New_Line;
I := I - 1;
Io.Put (" I = "); Io.Put (I); Io.New_Line;
end;
Io.Put (" I = "); Io.Put (I); Io.New_Line;
end;
end Bloc1;
11
fichier : Ada/Declare/bloc1.log
$ ./bloc1
I = 0
I = 999999
I = 999998
I = 0
11
12
fichier : Ada/Declare/bloc2.adb
with Io;
procedure Bloc2 is
begin
Bloc :
declare
I, J : Integer;
begin
I := 100;
J := 2 * I;
Io.Put (" I = "); Io.Put (I); Io.New_Line;
Io.Put (" J = "); Io.Put (J); Io.New_Line;
declare
I, K, L : Integer;
begin
I := 0;
K := 10 * I;
L := 10 * Bloc.I;
Io.Put (" I = "); Io.Put (I); Io.New_Line;
Io.Put (" J = "); Io.Put (J); Io.New_Line;
Io.Put (" K = "); Io.Put (K); Io.New_Line;
Io.Put (" L = "); Io.Put (L); Io.New_Line;
end;
Io.Put (" I = "); Io.Put (I); Io.New_Line;
Io.Put (" J = "); Io.Put (J); Io.New_Line;
end Bloc;
end Bloc2;
13
fichier : Ada/Declare/bloc2.log
$ ./bloc2
I = 100
J = 200
I = 0
J = 200
K = 0
L = 1000
I = 100
J = 200
12