III. Les instructions en Pascal

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 (’je dois faire mes exercices pour réussir mon bac’)       { affichage }
– readln (x)                                                         { lecture }
– ma_procedure (paramètres)                                          { 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.

Regardons ensemble ces deux exemples qui ne sont pas identiques

exemple1:

if B then        
I1;
I2;

exemple2:

if B then
begin
I1;
I2;
end; 
Screen Shot 2016-01-07 at 3.33.32 PM

→ Dans le premier exemple, I2 ne fait pas partie du if, dans le deuxième oui.

2.Branchement

En Pascal il y a 2 types de branchements, le if et le case.

Le test booléen if

L’instruction ci-dessous prend 2 formes, elle signifie si . . . alors . . . sinon.

Syntaxe

if B then I1;
{ken fama khobz , het khanekel}
if B then I1 else I2; 
{ken jé leprof , a3malli appel sinon (famech flous fetelifoune) 9oulou rani mridh}

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}
if B1
then I1
else if B2
     then I2
     else if B3
          then I3
          else Iautre;
{ forme 2 }
if B1
then if B2
     then Ia
     else Ib
else if B3
     then Ic
     else Id;

Règles d’or
* Il n’y a jamais de ; avant le else.
* Le else se rapporte toujours au dernier then rencontré.

Problème Dans la deuxième 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.

 

 

{ forme 1 }                                       { forme 2}
if B1                                             if B1
then { B1 }                                       then if B2
I1                                                     then  { B1 et B2 }     
else if B2                                                     Ia
then { !B1 et B2 }                                     else  { B1 et !B2}   
 I2                                                          Ib
else if B3                                        else if B3
then { !B1 et !B2 et B3 }                              then { !B1 et B3 }
I3                                                           Ic
else { !B1 et !B2 et !B3 }                             else { !B1 et !B3}
                                                             Id;




Sélection de cas avec case

Syntaxe

case E of
     C1 : Ia;  
     C2 : Ib;
     C3, C4 : Ic;   { liste }
     c5, C6 : Id;   { intervalle }
     {...}
     else Iautre;   { Important:  } 
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 réel ni une chaîne de caractèeres). 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; { évalué une seule fois au début }
 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.

Exemple complet

Écrire un programme qui lit un caractère, puis classe ce caractère comme espace, lettre, digit ou autre.

PROGRAM caractere;
Uses Wincrt;
TYPE
   nat_t = (Espace, Lettre, Digit, Autre); 
VAR
   nat : nat_t; { nature }
   c   : char;
    
BEGIN
   writeln (’donner 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 
                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.

3.Les boucles

 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; 
{medem leprof mejech, no93ed nal3ab}

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 a` 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;

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;
{o93ed otlobni 7atta line nhez alik}

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 := false ;
until (k > 100) or arreter;

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;
{ mel esm lowel 7ata lel esm ellekher , a3mel l'appel} {on connait le nombre des élèves}

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;        {downto et non pas down to }
{mel esm lekher 7ata lel esm lowel , a3mel l'appel} {on connait le nombre des élèves}

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.

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;
    Uses Wincrt
    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;


Choix de la boucle

La règle est simple (l’apprendre par cœur): 😀

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).


                        
Facebook