Les bases de la programmation


précédentsommairesuivant

Structures de contrôle

But de ce chapitre

Avec ce que nous avons vu dans les deux premiers cours (Premières notions et Sous-programmes), un programme se présente comme un ensemble de sous-programmes qui ne contiennent que deux types d'instructions : des affectations ou des appels de procédures.

Les programmes de ce type ont deux limitations importantes, qui disparaîtront avec les nouvelles notions introduites dans ce cours.

Premièrement, ils ne peuvent pas s'adapter aux données qu'ils traitent. Ils ne pourront donc jamais traiter différents cas de figure ni se protéger contre l'introduction de données erronées. Cette limitation disparaîtra avec l'introduction des conditionnelles.

La deuxième limitation concerne les traitements itératifs dont nous avons déjà eu un aperçu dans le premier cours. Mais il s'agissait alors de traitements itératifs réalisés manuellement par l'utilisateur. Pour répéter un traitement, il reclique sur le bouton concerné. En fait, de nombreux problèmes informatiques nécessitent de pouvoir répéter automatiquement des instructions. Or nous n'avons pour l'instant qu'un seul moyen de le faire : dupliquer ces instructions dans le code autant de fois que nécessaire. Cette solution n'est évidemment pas très pratique. Et comment faire alors si le nombre de répétitions dépend des données ?

Cette deuxième limitation disparaîtra avec l'introduction des boucles.

Les conditionnelles et les boucles utilisent toutes les deux un type d'expression que nous n'avons pas encore étudié : les expressions logiques.

Nous allons donc commencer par là.

Les expressions logiques

Variable booléenne

Le type booléen est un type de variable, tout comme les types entier ou chaîne de caractères.

Une variable de ce type sert à représenter une information qui peut être vraie ou fausse.

Par exemple, dans un programme de gestion de marchandises, on pourrait avoir une variable RuptureDeStock qui nous permettrait de savoir si le stock de marchandises est épuisé.

De manière générale :

Une variable booléenne est une variable qui peut prendre deux valeurs : true (vrai) et false (faux).

Il n'y a donc que deux littéraux de type booléen.

En Pascal, le type booléen se note Boolean et une variable booléenne se déclare de la manière suivante :

 
Sélectionnez
Var nom de la variable : Boolean;

On pourrait par exemple écrire :

 
Sélectionnez
  Var RuptureDeStock : Boolean;
  RuptureDeStock := True;

La première instruction déclare une variable booléenne nommée RuptureDeStock. La deuxième lui affecte la valeur True.

Opérateurs logiques

Nous avons déjà vu quelques opérateurs : les opérateurs arithmétiques, qui agissent sur des nombres, ainsi que l'opérateur de concaténation, qui agit sur des chaînes de caractères.

De la même manière, il existe des opérateurs logiques. Ceux-ci permettent de calculer une valeur logique (donc vrai ou faux) à partir d'autres valeurs logiques.

Il existe principalement trois opérateurs logiques : la négation , la conjonction et la disjonction.

La négation

En logique, la négation permet de représenter le contraire d'une proposition.

Si quelque chose est vrai, alors son contraire est faux et réciproquement.

En Pascal, l'opérateur de négation se note Not.

La table suivante (que l'on appelle table de vérité) résume l'effet de l'opérateur de négation :

X Not X
True False
False True

Par exemple, avec deux variables booléennes ArticleDisponible et RuptureDeStock, on pourrait écrire :

 
Sélectionnez
ArticleDisponible := Not RuptureDeStock;

Si RuptureDeStock vaut true avant cette affectation, alors ArticleDisponible vaudra false après cette affectation.

Réciproquement, si RuptureDeStock vaut False avant cette affectation, alors ArticleDisponible vaudra true après cette affectation.

La conjonction

La conjonction, représentée en Pascal par l'opérateur And, permet d'exprimer le fait que deux choses sont vraies simultanément.

Voilà la table de vérité de l'opérateur And :

X Y X And Y
False False False
False True False
True False False
True True True

Prenons un exemple.

La variable booléenne AmpouleFonctionne représente le fait qu'une ampoule électrique fonctionne.

Une autre variable booléenne InterrupteurOn est vraie si et seulement si l'interrupteur est en position On.

La variable booléenne LumiereAllumee représente le fait que la lumière est allumée.

Après l'affectation suivante :

 
Sélectionnez
LumiereAllumee := AmpouleFonctionne And InterrupteurOn;

la variable LumiereAllumee ne vaudra True que si les variables AmpouleFonctionne et InterrupteurOn valaient également True juste avant l'affectation.

La disjonction

La disjonction de deux propositions est vraie si et seulement si au moins une de ces deux propositions est vraie.

Autrement dit, la disjonction de deux propositions n'est fausse que lorsque ces deux propositions sont fausses.

Par exemple, la proposition « Il est bête ou il ne comprend pas » ne sera fausse que si l'individu en question n'est pas bête et a très bien compris.

Attention ! Le « ou logique » n'est pas un « ou exclusif ». La disjonction de deux propositions est vraie lorsque les deux propositions sont vraies. Par exemple, l'affirmation « Il pleut ou il y a du soleil » est vraie lorsqu'il pleut et qu'il y a du soleil en même temps.

L'opérateur de disjonction est représenté en Pascal par le mot-clé Or. Voici sa table de vérité :

X Y X Or Y
False False False
False True True
True False True
True True True

Prenons un exemple.

La variable booléenne AmpouleFoutue représente le fait qu'une ampoule électrique ne fonctionne pas.

Une autre variable booléenne InterrupteurOff est vraie si et seulement si l'interrupteur est en position Off.

La variable booléenne LumiereEteinte représente le fait que la lumière est éteinte.

Après l'affectation suivante :

 
Sélectionnez
LumiereEteinte := AmpouleFoutue Or InterrupteurOff;

la variable LumiereEteinte ne vaudra True que si la variable AmpouleFoutue et/ou la variable InterrupteurOff avaient la valeur True juste avant l'affectation.

Expressions logiques

Une expression logique est une expression de type booléen, c'est-à-dire une expression pouvant prendre la valeur vrai ou faux.

Les variables booléennes

Vous connaissez déjà un cas particulièrement simple d'expression logique : ce sont les noms de variables booléennes.

Par exemple, si la variable LumiereEteinte est déclarée comme une variable booléenne, le simple nom de variable LumiereEteinte peut être considéré comme une expression logique.

Utilisation des opérateurs logiques

On peut également construire des expressions logiques en combinant d'autres expressions logiques avec les opérateurs Not, And, Or.

Supposons, par exemple, que x, y et z soient des variables booléennes. Alors Not x, x And y, x Or y sont des expressions logiques. Tout comme z Or (x And y), (Not z And x) et (x Or y)

De manière générale :

  • Si E est une expression logique, alors Not E est une expression logique.
  • Si E et F sont des expressions logiques, alors E And F est une expression logique.
  • Si E et F sont des expressions logiques, alors E Or F est une expression logique.
  • Si E est une expression logique, alors (E) est une expression logique.

Utilisation des opérateurs de comparaison

Il existe encore un autre moyen de construire une expression logique : en utilisant des opérateurs de comparaison.

Un opérateur de comparaison est un opérateur qui permet de comparer deux expressions de même type.

Les six opérateurs

Il existe six opérateurs de comparaison :

Symboles mathématiques Signification
= Égal à
Différent de
< Strictement inférieur à
> Strictement supérieur à
Inférieur ou égal à
Supérieur ou égal à

La notation des opérateurs de comparaison varie selon les langages :

Symboles mathématiques Pascal Langage C
= = ==
<> !=
< < <
> > >
<= <=
>= >=
Comparaison d'expressions numériques

L'utilisation la plus fréquente des opérateurs de comparaison est la comparaison d'expressions numériques.

La plus simple est la comparaison directe de deux variables numériques. Exemple :

x y x = y x <> y x < y x >= y x > y x <= y
1 1 True False False True False True
1 2 False True True False False True
2 1 False True False True True False

Mais on peut bien sûr comparer des expressions numériques quelconques. Par exemple, pour x = 1 et y = 2, on aurait :

Expression logique Valeur
(x+1) = y True
(x+1)*(y+1) = 6 True
x+1 <= 2 True
x-1 < -y False
Comparaison de chaînes de caractères

En Pascal, les six opérateurs de comparaison peuvent être utilisés avec des chaînes de caractères, en se basant sur l'ordre alphabétique. Exemple :

x y x = y x <> y x < y x >= y x > y x <= y
'Trac' 'Trac' True False False True False True
'Trac' 'Truc' False True True False False True
'Truc' 'Trac' False True False True True False

Exercices

  • Énoncés ;
  • Pour obtenir les corrigés, rendez-vous au bas de la page.

La conditionnelle

La programmation n'aurait que très peu d'intérêt si elle ne permettait pas aux ordinateurs de réagir différemment selon différentes conditions.

Une machine programmable doit pouvoir effectuer des traitements différents selon les données qu'elle doit traiter.

Cela est possible grâce à l'existence des structures de contrôle dans les langages de programmation : la conditionnelle et les boucles.

L'objet de ce chapitre est d'expliquer le fonctionnement d'une conditionnelle.

Le If

La conditionnelle If existe en deux variantes : le If ... Then et le IfThenElse.

Le If … Then

La structure de contrôle If … Then s'écrit de la manière suivante :

 
Sélectionnez
If condition Then
Begin
    Instructions à exécuter
    si la condition est vraie
End;

La condition n'est rien d'autre qu'une expression logique.

Les instructions entre begin et end ne seront exécutées que si la condition est vraie.

S'il n'y a qu'une seule instruction à exécuter, on peut omettre les mots-clés begin et end :

 
Sélectionnez
If condition Then Instruction à exécuter;

Prenons un exemple :

 
Sélectionnez
If n > 0 Then n := n - 1;

Si, par exemple, n vaut 5 juste avant l'exécution du If … Then, la condition n > 0 est vérifiée. L'ordinateur va donc exécuter l'affectation n := n - 1. n vaudra donc 4 à la sortie de la conditionnelle.

Si n vaut -1, par contre, la condition n > 0 n'est pas vérifiée. L'affectation ne sera pas exécutée et n vaudra toujours -1 à la sortie de la conditionnelle.

Le If … Then … Else

Le If … Then … Else est une autre forme de conditionnelle.

Elle permet d'exécuter certaines instructions si une condition est vraie, et d'autres si elle est fausse.

Voilà sa syntaxe :

 
Sélectionnez
If condition Then
begin
    Instructions à exécuter
    si la condition est vraie
End
Else
begin
&#160;&#160; Instructions à exécuter 
&#160;&#160; si la condition est fausse 
End;

De même, les begin et end ne sont pas nécessaires s'il n'y a qu'une seule instruction.

Prenons un exemple :

 
Sélectionnez
If n > 0 Then
   n := n - 1
Else
   n := n + 1;

Remarquez que nous n'avons pas mis de point-virgule après la première affectation. Si nous l'avions fait, le compilateur aurait généré une erreur de syntaxe, car il aurait interprété ceci comme un if … then simple suivi du mot-clé else, qui n'aurait rien à voir ici dans ce cas.

Par contre, le point-virgule est nécessaire après la deuxième affectation pour marquer la fin de la conditionnelle.

Que se passe-t-il lors de l'exécution de cette conditionnelle ?

Supposons, par exemple, que n vaut 5 juste avant l'exécution du If … Then … Else. La condition n > 0 est vérifiée. L'ordinateur va donc exécuter l'affectation n := n - 1. Par contre, l'affectation n := n + 1 ne sera pas exécutée. n vaudra donc 4 à la sortie de la conditionnelle.

Si n vaut -1, par contre, la condition n > 0 n'est pas vérifiée. L'affectation n := n - 1 n'est donc pas exécutée. Mais comme la condition est fausse, l'affectation n := n + 1 sera exécutée. n vaudra donc 0 à la sortie de la conditionnelle.

If imbriqués

Les instructions à l'intérieur d'un If ne sont pas forcément des affectations comme dans les exemples précédents.

On peut également y mettre d'autres structures de contrôle et, en particulier, d'autres If.

Exemple :

 
Sélectionnez
If n > 0 Then
    n := n - 1
Else
    If n >= -3 Then
         n := n + 1
    Else
         n := 2 * n;

Pour n = 5, l'instruction exécutée est n := n - 1. n vaudra donc 4 à la sortie de la conditionnelle.

Pour n = -1, l'instruction exécutée est n := n + 1. n vaudra donc 0 à la sortie de la conditionnelle.

Pour n = -4, l'instruction exécutée est n := 2 * n. n vaudra donc -8 à la sortie de la conditionnelle.

Dans l'exemple précédent, on a deux niveaux d'imbrication. Mais on peut avoir autant de niveaux d'imbrication qu'on le souhaite.

L'instruction Exit

L'imbrication de If peut conduire à des programmes plus rapides (voir l'exercice Min-Max-Med), mais elle peut également compliquer l'écriture du code, notamment dans la protection d'un programme contre les erreurs.

Prenons par exemple un programme utilisant une date définie par un jour (nombre entier entre 1 et 31), un mois (nombre entier entre 1 et 12) et une année de ce siècle (nombre entier supérieur à 2000). Ces trois données sont lues depuis trois zones de texte (respectivement ZT_Jour, ZT_Mois et ZT_Annee) dans des variables entières, respectivement Jour, Mois, Annee. Ce traitement est effectué par la procédure évènementielle associée au bouton BT_GererDate.

Pour tester la validité de ces données avec des If imbriqués, on écrirait le code suivant :

 
Sélectionnez
procedure TForm1.BT_GererDateClick(Sender: TObject)
var Jour,Mois,Annee: integer;
begin
 LireEntier (Jour, ZT_Jour);
 If ( Jour < 1) or (Jour > 31) Then
   ShowMessage ('Numéro du jour non valide!')
 Else
 begin
   LireEntier (Mois, ZT_Mois);
   If (Mois < 1) or (Mois > 12) Then
     ShowMessage('Numéro du mois non valide!')
   Else
   Begin
     LireEntier(Annee,ZT_Annee);
     If Annee < 2000 Then
       ShowMessage ('Année non valide!')
     Else
     Begin  
       Traitement de la date
     End
   End 
 End
End;

Pour raccourcir ce genre d'écriture, on peut utiliser l'instruction Exit, qui permet de forcer la fin de l'exécution du sous-programme qui la contient. Avec cette instruction, l'exemple précédent peut être écrit sans aucune imbrication de If :

 
Sélectionnez
procedure TForm1.BT_GererDateClick(Sender: TObject)
var Jour,Mois,Annee: integer;
begin
 LireEntier (Jour, ZT_Jour);
 If ( Jour < 1) or (Jour > 31) Then
 Begin ShowMessage ('Numéro du jour non valide!'); Exit End;
 
 LireEntier (Mois, ZT_Mois);
 If (Mois < 1) or (Mois > 12) Then
 Begin ShowMessage('Numéro du mois non valide!'); Exit End;
      
 LireEntier(Annee,ZT_Annee);
 If Annee < 2000 Then
 Begin ShowMessage ('Année non valide!'); Exit End;

  Traitement de la date

End;

Case

La conditionnelle Case est utilisée lorsque l'on veut effectuer différents traitements selon la valeur d'une expression quelconque.

Voici sa syntaxe :

 
Sélectionnez
Case Expression Of 
       V1 :
         Instructions à exécuter lorsque 
         l'expression vaut V1 ;
       V2 :
         Instructions à exécuter lorsque 
         l'expression vaut V2 ;
       .
       .
       VN :
         Instructions à exécuter lorsque 
         l'expression vaut VN ;
Else
    Instructions à exécuter dans les autres cas ;  
End;

La partie Else est optionnelle.

Voici, par exemple, comment déterminer le nom d'un mois en fonction de son numéro avec une instruction Case :

 
Sélectionnez
Case NumeroMois  Of
     1 : NomMois :='janvier';
     2 : NomMois :='février';  
     .
     .
     12 : NomMois :='décembre';       
Else
 ShowMessage ('Numéro de mois inexistant!')
End;

Exercices

Les boucles

Tout comme les conditionnelles, les boucles sont des structures de contrôle fondamentales de la programmation.

Par l'intermédiaire d'une boucle, on peut demander à un ordinateur de répéter une partie du code.

Nous allons présenter trois types de boucles : les boucles While, les boucles Repeat et les boucles For.

En fait, la boucle While suffirait à écrire n'importe quel programme. Mais dans certains cas, l'écriture d'une boucle avec Repeat ou avec For est plus pratique.

Les boucles While

Une boucle While permet de répéter du code tant qu'une certaine condition est vraie.

Elle s'écrit de la manière suivante :

 
Sélectionnez
While condition do
begin
 Instructions à répéter
 tant que la condition est vraie
End;

La condition est une expression logique quelconque.

Voilà un exemple précis de boucle While :

 
Sélectionnez
S := 0;
i := 1;
While i <= n Do
begin 
     S := S + i;
     i := i + 1;
End;

Cette boucle permet de calculer la somme S des n premiers entiers : 1 + 2 + 3 + … + n. Pour n = 4, on aura par exemple S = 1 + 2 + 3 + 4 = 10 à la fin de l'exécution de ce code.

Vocabulaire associé aux boucles

Un peu de vocabulaire :

Chaque exécution du code à l'intérieur d'une boucle s'appelle une itération.

Dans notre exemple, une itération est une exécution des instructions S := S + i; et i := i + 1;.

Généralement, une boucle est précédée d'un certain nombre d'affectations que l'on appelle des initialisations. Elles servent à donner des valeurs initiales aux variables de la boucle (c'est-à-dire toutes celles qui vont varier dans la boucle).

Dans notre exemple, ce sont les instructions S := 0 et i := 1.

Dans une boucle, on trouve fréquemment une variable qui joue le rôle de compteur (car elle compte en quelque sorte le nombre d'itérations). La valeur de cette variable est augmentée de 1 à chaque itération par une instruction de la forme variable := variable + 1, que l'on appelle une incrémentation.

Dans notre exemple, le compteur est représenté par la variable i. À chaque itération, la valeur de i est incrémentée par l'affectation i := i + 1.

Déroulement de la boucle

Nous allons à présent dérouler la boucle donnée en exemple, c'est-à-dire détailler toutes les instructions qui seront exécutées jusqu'à ce que la boucle s'arrête.

Supposons que n vaut 3 avant d'entrer dans la boucle. Voilà exactement ce qui se passe lorsque cette boucle est exécutée :

Instruction exécutée Valeur de i Valeur de S  
S := 0 0 0 Initialisation
i := 1 1 0
S := S + i 1 1 1re itération
i := i + 1 2 1
S := S + i 2 3 2e itération
i := i + 1 3 3
S := S + i 3 6 3e itération
i := i + 1 4 6

Dans une boucle While, la condition d'arrêt est testée avant l'exécution d'une itération.

Donc avant d'entrer la première fois dans la boucle, l'ordinateur va tester la condition i ≤ n. Comme i vaut 1 et n vaut 3, il va rentrer dans la boucle et faire une première itération.

À la fin de la première itération, i vaut 2. La condition i ≤ n est toujours vérifiée. L'ordinateur va donc faire une deuxième itération.

À la fin de la deuxième itération, i vaut 3. La condition i ≤ n est toujours vérifiée. L'ordinateur va donc faire une troisième itération.

À la fin de la troisième itération, i vaut 4. Ce sera donc la dernière itération, car à présent la condition i ≤ n est fausse.

Les boucles Repeat

La boucle Repeat s'écrit de la manière suivante :

 
Sélectionnez
Repeat
   Instructions à répéter
   jusqu'à ce que la condition soit vraie
Until condition

Remarques :

  • avec une boucle Repeat, le code à répéter est toujours exécuté au moins une fois ;
  • il n'y a pas de BeginEnd englobant les instructions à répéter, car Repeat et Until jouent déjà ce rôle.

Voici par exemple comment calculer la somme des n premiers nombres entiers avec une boucle Repeat :

 
Sélectionnez
S := 0;
i := 0;
Repeat
  i := i + 1;
  S := S+ i 
Until i = n;

Comme précédemment, supposons que n vaut 3 et voyons ce qui se passe exactement lorsque la boucle Repeat est exécutée :

Instruction exécutée Valeur de i Valeur de S  
S := 0 0 0 Avant d'entrer
dans la boucle
i := 0 0 0
i := i + 1 1 0 1re itération
S := S + i 1 1
i := i + 1 2 1 2e itération
S := S + i 2 3
i := i + 1 3 3 3e itération
S := S + i 3 6

Avant d'entrer dans la boucle, S et i sont initialisés à 0.

À la fin de chaque itération, l'ordinateur va tester si i est égal à n (donc à 3 dans notre exemple).

Cette condition n'est réalisée qu'à la fin de la troisième itération.

Les boucles For

Fondamentalement, une boucle For n'est rien d'autre qu'un raccourci d'écriture pour un certain type de boucle While que l'on rencontre très fréquemment :

 
Sélectionnez
compteur := valeur initiale;
While compteur <= valeur finale Do
Begin
   Instructions à répéter 
   compteur := compteur + 1;
End;

Avant la boucle, on affecte une valeur initiale au compteur.

À chaque itération, le compteur est incrémenté.

La boucle s'arrête dès que le compteur dépasse la valeur finale.

La boucle For permet d'écrire ce type de boucle de manière plus concise, comme suit :

 
Sélectionnez
For compteur :=  valeur initiale To valeur finale Do
Begin
&#160;&#160; Instructions à répéter
End;

On économise ainsi l'écriture de l'incrémentation du compteur à l'intérieur de la boucle.

Attention : l'incrémentation du compteur n'est pas écrite, mais elle est bien exécutée.

Voici, par exemple, la somme des n premiers nombres entiers avec une boucle For et avec une boucle While :

En boucle For En boucle While

S := 0;
For i := 1 To n Do
Begin
S := S+i
End

S := 0;
i := 1;
While i <= n Do
Begin
S := S+i;
i := i+1
End

Exercices

  • Énoncés ;
  • Pour obtenir les corrigés, voyez ci-dessous.

Corrigés des exercices

Pour obtenir les corrigés, le téléchargement n'est possible que via un login et un mot de passe, que vous pouvez obtenir en envoyant un mail à l'adresse suivante :

Image non disponible

en précisant un peu qui vous êtes et les raisons pour lesquelles ce cours vous intéresse.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2014 Eric Thirion. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.