Boucle

Quatre types de boucles : for / while / repeat / for-in

Commencez par examiner les exemples ci-dessous. Modifiez le fichier de code de la leçon précédente, mydemo.dpr, et changez son extension en pas pour obtenir mydemo.pas. C’est l’extension standard des fichiers source Pascal. Téléchargez ensuite un éditeur de code comme Notepad++ avec coloration syntaxique, cela rendra votre code beaucoup plus lisible.

Voici un exemple complet avec des commentaires sur chaque ligne de code. Après l’exemple, nous détaillerons chaque instruction une par une.

// 2.8 Instructions de boucle : for, while, repeat, for..in
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
// Directives du compilateur FPC : activer le mode orienté objet, chaînes longues, désactiver le comptage de références automatique des chaînes
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
// Plateforme Windows : définir le programme comme application console (sans fenêtre graphique)
{$R+} // Activer la vérification des limites de tableau, très utile pour déboguer les erreurs d’indice
var
  MyArray: array [0..9] of Integer; // Tableau d’entiers avec 10 éléments, indices de 0 à 9
  I: Integer; // Variable compteur de boucle
begin
// 1. Boucle for croissante : initialiser le tableau avec les carrés des nombres 0 à 9
for I := 0 to 9 do
    MyArray[I] := I * I;

// 2. Boucle for basique pour parcourir les indices et afficher les carrés
for I := 0 to 9 do
    WriteLn('Le carré est ', MyArray[I]);

// 3. Low/High récupèrent automatiquement les bornes du tableau, pas besoin d’écrire manuellement 0 et 9, meilleure évolutivité
for I := Low(MyArray) to High(MyArray) do
    WriteLn('Le carré est ', MyArray[I]);

// 4. Boucle while : tester la condition d’abord, exécuter le corps seulement si elle est vraie
  I := 0;
while I < 10 do
begin
    WriteLn('Le carré est ', MyArray[I]);
    I := I + 1; // Trois écritures équivalentes : I+=1 / Inc(I)
end;

// 5. Boucle repeat-until : exécuter le corps une première fois, vérifier la condition de sortie à la fin
  I := 0;
repeat
    WriteLn('Le carré est ', MyArray[I]);
    Inc(I); // Incrémenter le compteur
until I = 10;

// 6. Parcours for-in : récupérer directement les valeurs des éléments sans manipuler les indices
for I in MyArray do
    WriteLn('Le carré est ', I);
end.Langage du code : PHP (php)

Voici le code sans aucun commentaire

{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

var
  MyArray: array [0..9] of Integer;
  I: Integer;

begin

for I := 0 to 9 do
    MyArray[I] := I * I;

for I := 0 to 9 do
    WriteLn('Le carré est ', MyArray[I]);

for I := Low(MyArray) to High(MyArray) do
    WriteLn('Le carré est ', MyArray[I]);

  I := 0;
while I < 10 do
begin
    WriteLn('Le carré est ', MyArray[I]);
    I := I + 1;
end;

  I := 0;
repeat
    WriteLn('Le carré est ', MyArray[I]);
    Inc(I);
until I = 10;

for I in MyArray do
    WriteLn('Le carré est ', I);

end.Langage du code : PHP (php)

Nous analysons ci-dessous pas à pas le code de chaque boucle

Boucle for

Affecter des valeurs à un tableau avec une boucle for

{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

var
  MyArray: array [0..9] of Integer;
  I: Integer;

begin

for I := 0 to 9 do
    MyArray[I] := I * I;

end.Langage du code : PHP (php)

Ce code se divise en trois parties : en haut les directives de précompilation, la section var déclare les variables (un tableau et un entier), puis le bloc d’exécution principal entre begin et end. contient une boucle for qui attribue successivement les valeurs de 0 à 9 à I pour remplir les éléments du tableau par indice.

On remplit les dix éléments MyArray[0] à MyArray[9]. L’étoile * représente l’opérateur de multiplication.

MyArray[0] := 0 * 0;

MyArray[1] := 1 * 1;

MyArray[9] := 9 * 9;

Ensuite, ajoutez une seconde boucle for sous la première pour lire chaque élément stocké dans le tableau.

Après compilation et exécution, toutes les valeurs s’affichent en sortie

Tous les résultats correspondent aux carrés des nombres de 0 à 9, conformément à nos attentes précédentes.

Si vous ignorez l’étendue des indices du tableau, utilisez les fonctions natives pour récupérer les bornes inférieure et supérieure.

La fonction Low(NomTableau) ci-dessus récupère l’indice minimal du tableau

  • Low(Type/Variable) : récupérer la valeur minimale / borne inférieure des types ordinaux, tableaux, ensembles
  • High(Type/Variable) : récupérer la valeur maximale / borne supérieure des types ordinaux, tableaux, ensembles

Boucles while et repeat

À l’intérieur du corps de la boucle while délimité par begin end;, la variable I augmente de 1 à la fin du bloc. Après incrémentation, le flux retourne sur la ligne while I < 10 do pour un nouveau test. Si la condition est vraie, le corps s’exécute une seconde fois, I augmente à nouveau et le test se répète. Le cycle s’arrête quand I < 10 devient faux, c’est-à-dire quand I vaut 10.

Différences essentielles entre while et repeat-until

  1. Logique de condition inverse
  • while Condition do : condition vraie → continuer la boucle ; condition fausse → sortir
  • repeat ... until Condition : condition vraie → sortir ; condition fausse → continuer la boucle
  1. Nombre minimal d’exécution différent
  • while : si la condition initiale est fausse, le corps de boucle ne s’exécute jamais
  • repeat-until : quelle que soit la condition, le corps s’exécute au moins une fois

Si vous avez appris des langages comme C, C++ ou Java, c’est simple à comprendre : repeat-until correspond exactement au do-while. On exécute d’abord le corps une fois, puis on vérifie la condition derrière until ; si elle est fausse, on répète la boucle.

repeat-until n’a pas besoin de begin et end : repeat et until forment naturellement un bloc unique. Vous pouvez ajouter begin end manuellement mais ce n’est pas recommandé.

Littéralement, repeat-until signifie « répéter … jusqu’à ce que », son fonctionnement est clair d’après sa dénomination.


Pendant le parcours, chaque valeur de MyArray est affectée successivement à I, que vous pouvez manipuler directement dans la boucle. Pas besoin d’incrémenter manuellement l’indice, voire même pas besoin d’indice du tout, jusqu’à ce que tout le tableau soit parcouru.

Présentation de la boucle for classique (for I := ... to/downto)

  1. Similaire à la boucle for du langage C mais plus restrictive : ne parcourt que des valeurs ordinales contiguës (entiers, énumérations) ;
  2. Prend en charge le parcours inverse avec downto : for I := 9 downto 0 do ;
  3. Les bornes Low(xx) / High(xx) ne sont calculées qu’une seule fois au lancement de la boucle, offrant une bonne efficacité ;
  4. Après fin normale de boucle, la valeur de I est indéfinie et le compilateur affichera un avertissement. Si vous interrompez prématurément avec Break ou Exit, I conserve sa valeur actuelle.

Parcours for-in (style foreach moderne)

Permet de parcourir quatre types de données sans manipuler manuellement les indices :

  1. Tableaux : lire directement chaque valeur d’élément (démontré dans les exemples précédents)
  2. Types énumérés
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

type TAnimalKind = (Duck,Cat,Dog);

var AK:TAnimalKind;
begin
  for AK in TAnimalKind do 
    WriteLn(AK);
end.Langage du code : PHP (php)
  1. Types ensemble
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}

type
  // Définition du type énuméré
  TAnimalKind = (Duck, Cat, Dog);
  // Définition d’un type ensemble basé sur l’énumération
  TAnimals = set of TAnimalKind;

var
  Animals: TAnimals;
  AK: TAnimalKind;
begin
  // Affecter deux valeurs énumérées à l’ensemble : Duck et Cat
  Animals := [Duck, Cat];

  // Parcourir tous les membres présents dans l’ensemble avec for-in
  for AK in Animals do
  begin
    WriteLn('Animal trouvé : ', AK);
  end;
end.Langage du code : PHP (php)
  1. Listes génériques (étudié dans les chapitres suivants)
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
uses
  SysUtils, Generics.Collections; // Importer l’unité des conteneurs génériques

type
  TMyClass = class  // Classe personnalisée stockant un nombre et son carré
    I, Square: Integer;
  end;
  // Instancier une liste générique d’objets avec gestion automatique du cycle de vie
  TMyClassList = {$ifdef FPC}specialize{$endif} TObjectList&lt;TMyClass&gt;;
var
  List: TMyClassList;
  C: TMyClass;
  I: Integer;
begin
  List := TMyClassList.Create(true); // true : libérer automatiquement les objets internes à la destruction de la liste
try
  // Créer des objets en boucle et les ajouter à la liste
for I := 0 to 9 do
begin
      C := TMyClass.Create;
      C.I := I;
      C.Square := I * I;
      List.Add(C);
end;
  // Parcourir directement chaque objet personnalisé de la liste avec for-in
for C in List do
      WriteLn('Le carré de ', C.I, ' est ', C.Square);
finally
    FreeAndNil(List); // Libérer la liste en toute sécurité pour éviter les fuites mémoire
end;
end.
Langage du code : HTML, XML (xml)

Note : cet exemple utilise des classes et des génériques. Les débutants peuvent le passer temporairement, nous le détaillerons dans le chapitre sur la programmation orientée objet.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *