III. Les instructions en Pascal▲
III-1. Instruction composée▲
Une instruction spécifie une opération ou un enchaînement d'opérations à exécuter
sur des objets.
Les instructions sont séparées par des ; et sont exécutées séquentiellement, c'est-à -dire
l'une après l'autre, depuis le BEGIN jusqu'au END. final.
Instruction déjà vues
- a := 5 affectation
- writeln ('Bonjour') affichage
- readln (x) lecture
- ma_procedure (parametres) appel procédure
Plus généralement Soient I1, I2, etc, des instructions.
- On fabrique dans la suite de nouvelles instructions :
- if expr then I1 - while test do I1 - etc - Il est possible de regrouper l'enchaînement I1; I2; I3; en une instruction
unique en l'encadrant entre un begin et un end
begin I1; I2; I3; end
Intérêt On veut faire I1 puis I2 dans un if.
(on met des accolades sur les instructions).
--> Dans la 1ère forme, I2 ne fait pas partie du if, dans la 2nde oui.
III-2. Les branchements▲
Etant donné une expression et plusieurs instructions, la valeur de l'expression va
déterminer laquelle de ces instructions exécuter.
En Pascal il y a 2 types de branchements, le if et le case.
III-2-1. Le test booléen if▲
L'instruction ci-dessous prend 2 formes, elle signifie si . . . alors . . . sinon.
Syntaxe
if
B then
I1;
if
B then
I1 else
I2;
B est une expression booléenne, I1 et I2 sont des instructions.
L'expression B est évaluée ; si elle est vraie, alors I1 est exécutée, sinon I2 est
exécutée.
Remarque On peut se passer de else en n'employant que des if then, mais c'est
moins efficace, et on peut facilement se tromper : l'exemple suivant ne donne pas les
mêmes résultats !
a := 1
;
{ sans else }
{ avec else }
if
a = 1
then
a := 2
; if
a = 1
then
a := 2
if
a <> 1
then
a := 3
; else
a := 3
;
On peut imbriquer des if then else de différentes manières :
{ forme 1 }
{ forme 2 }
if
B1 if
B1
then
I1 then
if
B2
else
if
B2 then
Ia
then
I2 else
Ib
else
if
B3 else
if
B3
then
I3 then
Ic
else
Iautre; else
Id;
Règles
- Il n'y a jamais de ; avant le else .
- Le else se rapporte toujours au dernier then rencontré.
Problème Dans la deuxieme forme, comment supprimer l'instruction Ib ?
On ne peut pas simplement supprimer la ligne else Ib, car alors le else if B3
se rapporterait à then Ia.
On ne peut pas non plus rajouter un ; car il y a un else après.
La solution consiste à < protéger > if B2 then Ia; dans un begin end :
if
B1
then
begin
if
B2
then
Ia;
end
else
if
B3
then
Ic
else
Id;
Remarque Il faut faire très attention aux tests multiples, imbriqués ou non, et être très rigoureux dans l'écriture. La règle est d'indiquer entre {} le cas précis dans lequel on se trouve.
III-2-2. Sélection de cas avec case▲
Syntaxe
case
E of
C1 : Ia;
C2 : Ib;
C3, C4 : Ic; { liste }
C5..C6 : Id; { intervalle }
{ ... }
else
Iautre; { en option }
end
;
Cette instruction signifiant choix selon permet d'exécuter l'une des instructions
Ix selon le cas E.
E est une expression ordinale (dont le type est un entier, un caractère, un booléen,
ou un énuméré, mais pas un reel ni une chaîne de caractères). Les Cx sont des
constantes ordinales du même type que E.
Comment ça marche E est évalué. Ensuite, est recherchée parmi les valeurs possibles
Cx, laquelle est égale à E. L'instruction correspondante Ix est alors exécutée. Sinon,
l'instruction après le else (s'il y en a un) est exécutée.
- On peut donner une liste de constantes, ou des intervalles de constantes.
Attention, chaque valeur possible ne doit être représentée qu'une fois au plus (sinon il y a erreur à la compilation). Par exemple, on ne peut pas faire des intervalles se chevauchant, comme 3..6 et 5..10, les cas 5 et 6 étant représentés 2 fois. - L'exemple donné ci-dessus est équivalent à une forme en if then else imbriqués.
V := E; { evalue' une seule fois au debut }
if
V = C1 then
Ia
else
if
V = C2 then
Ib
else
if
(V = C3) or
(V = C4) then
Ic
else
if
(V >= C5) and
(V <= C6) then
Id
else
Iautre;
On préfère la forme avec le case, qui est plus lisible et plus efficace.
Exercice
Réécrire l'exemple sur les feux du §I.6.2, (Type énuméré) avec un case.
Exemple complet
Écrire un programme qui lit un caractère, puis classe ce caractère comme espace,
lettre, digit ou autre.
PROGRAM
caractere;
TYPE
nat_t = (Espace, Lettre, Digit, Autre);
VAR
nat : nat_t; { nature }
c : char
;
BEGIN
write
('Rentrez un caractere :'
);
readln(c);
{ analyse de c }
case
c of
'a'
..'z'
, 'A'
..'Z'
, '_'
: nat := Lettre;
'0'
..'9'
: nat := Digit;
' '
: nat := Espace;
else
nat := Autre;
end
; { case c }
{ affichage de nat }
case
nat of
Espace : writeln ('Espace'
);
Lettre : writeln ('Lettre'
);
Digit : writeln ('Digit'
);
Autre : writeln ('Autre'
);
else
{ case nat }
writeln ('Erreur case nat : '
, ord(nat), ' non prevu'
);
end
; { case nat }
END
.
Bonnes habitudes
- Après le else et le end, marquer en commentaire qu'ils se rapportent au case.
- Faire afficher un message d'erreur après le else : aide à la mise au point du programme.
III-3. Les boucles▲
III-3-1. La boucle while▲
Cette instruction signifie tant que. Elle permet de répéter l'exécution d'une
instruction de boucle I :
Syntaxe
while
B do
I;
B est une expression booléenne.
(*) B est évaluée. Si B est vraie, alors I est exécutée, et on recommence depuis
(*).
Remarques
- Les variables de l'expression B doivent être initialisées avant le while, pour que au premier passage B puisse être évalué.
- Le while continue de boucler tant que B n'est pas faux. Pour éviter une boucle infinie, qui < plante > le programme, il faut obligatoirement que dans I il y aie une sous-instruction rendant B faux à un moment donné.
Exemple Programme calculant la somme des nombres de 1 Ã 100.
PROGRAM
Somme;
VAR
s, k : integer
;
BEGIN
s := 0
; k := 1
;
while
k <= 100
do
begin
s := s + k;
k := k + 1
;
end
;
writeln (s);
END
.
- On se sert souvent d'un booléen dans une boucle while :
continuer := true
;
while
(k <= 100
) and
continuer do
begin
{ ... }
if
( ... ) then
continuer := false
;
end
;
III-3-2. La boucle repeat▲
Cette instruction signifie répéter . . . jusqu'à . Elle permet comme le while de
répéter l'exécution d'une instruction de boucle I :
Syntaxe
repeat I; until B;
B est une expression booléenne.
(*) I est exécutée, puis B est évaluée. Si B est vraie, alors on s'arrête, sinon on
recommence depuis (*).
Différences avec
while
- L'instruction I est exécutée au moins une fois.
- Le test B étant évalué après I, B peut être affecté dans I. Pour le while il faut avoir initialisé B avant.
- Pas besoin d'encadrer un groupe d'instructions par un begin end, le repeat until joue déjà ce rôle.
Exemple Le while de Somme s'écrit avec un repeat :
s := 0
; k := 1
;
repeat
s := s + k; k := k + 1
; until
k > 100
;
- Traduction d'une boucle while B do I; avec un repeat :
if
B then
repeat
I;
until
not
B;
- On se sert souvent d'un booléen dans une boucle repeat :
repeat
{ ... }
arreter := ... ;
until
(k > 100
) or
arreter;
III-3-3. La boucle for▲
Cette instruction signifie pour. Elle permet de répéter l'exécution d'une
instruction de boucle I :
Syntaxe
for
k := E1 to
E2 do
I;
k est le compteur de boucle, E1 et E2 sont les bornes inférieures et supérieures.
E1 et E2 sont des expressions ordinales, du même type que la variable k.
E1 et E2 sont d'abord évaluées, puis k prend la valeur E1. (*) Si k <= E2, alors I
est exécutée, puis k est incrémenté de 1, et on recommence depuis (*).
- Pour avoir une boucle décroissante, on écrit
for
k := E2 downto
E1 do
I;
- On peut écrire une boucle for k := E1 to E2 do I; avec un while :
k := E1; { init de k }
m := E2; { on evalue E2 une fois pour toutes }
while
k <= m do
begin
I;
k := k+1
;
end
;
- On en déduit l'écriture d'une boucle for k := E1 to E2 do I; avec un repeat :
k := E1; { init de k }
m := E2; { on evalue E2 une fois pour toutes }
if
k <= m then
repeat
I;
k := k+1
;
until
k > m;
Remarques
- L'instruction de boucle I n'est pas exécutée du tout si E1 > E2.
- Modifier pendant la boucle la valeur de E1 ou E2 n'a pas d'effet.
- Il est totalement interdit de modifier la valeur du compteur k dans le corps de la boucle.
- L'incrément de 1 n'est pas modifiable (contrairement au Basic avec step).
- A la fin de l'exécution de la boucle, la variable k redevient indéterminée : elle a une valeur qui dépend du compilateur. Par exemple sous Delphi, elle vaut E2+1, et sous Turbo Pascal 7.0, elle vaut E2.
Exemple d'application des règles : dire la valeur affichée [ c'est 10240 ]
a := 5
;
for
i := a to
a+10
do
a := a*2
;
writeln(a);
Exemple Le while de Somme s'écrit avec un for :
s := 0
;
for
k := 1
to
100
do
s := s + k;
- On peut bien entendu imbriquer des boucles.
PROGRAM
table_multiplication;
VAR
i, j : integer
;
BEGIN
for
i := 1
to
10
do
begin
for
j := 1
to
10
do
write
(i*j : 3
);
writeln;
end
;
END
.
Variante
for
i := 1
to
10
do
for
j := 1
to
10
do
begin
write
(i*j : 3
);
if
j = 10
then
writeln;
end
;
III-3-4. Choix de la boucle▲
La règle est simple (l'apprendre par coeur) :
Si le nombre d'itérations est connu a priori, alors on utilise un for.
Sinon : on utilise le repeat (quand il y a toujours au moins une itération), ou le
while (quand le nombre d'itérations peut être nul).