⌂ Programmation
Fiche 10 sur 13

Répéter tant que

Faire tourner le programme en rond, jusqu'à ce qu'une condition change.

Après cette fiche, vous saurez :

1Le problème des lignes répétées

Souvenez-vous de la fiche 5. Pour compter trois évènements, vous avez écrit :

nbEvents = nbEvents + 1;
nbEvents = nbEvents + 1;
nbEvents = nbEvents + 1;

Trois fois la même ligne. Et pour le bon d'achat, trois fois totalAchats = totalAchats + ….

Imaginez maintenant qu'il faille compter cent évènements. Ou mille. Ou un nombre qu'on ne connaît pas d'avance.

À retenir

Dès que vous écrivez deux fois la même ligne, pensez « boucle ».

Une boucle fait répéter un bloc de code à l'ordinateur, autant de fois que nécessaire. Vous ne l'écrivez qu'une seule fois.

2while : tant que

int compteur = 1;

while (compteur <= 5)
{
    Console.WriteLine($"Tour numéro {compteur}");
    compteur = compteur + 1;
}

Console.WriteLine("Terminé !");
Ce que l'ordinateur affiche
Tour numéro 1
Tour numéro 2
Tour numéro 3
Tour numéro 4
Tour numéro 5
Terminé !

Cinq lignes affichées, alors qu'on n'a écrit qu'un seul Console.WriteLine.

MorceauRôle
while« tant que » en anglais
(compteur <= 5)La condition à vérifier avant chaque tour
{ … }Ce qu'on répète

Comment l'ordinateur exécute une boucle

  1. Il teste la condition compteur <= 5 ? Au premier passage, compteur vaut 1. C'est vrai.
  2. Il exécute le bloc Il affiche, puis augmente le compteur.
  3. Il remonte Et recommence à l'étape 1.
  4. Quand la condition devient fausse Il saute le bloc et continue en dessous.
Tourcompteur au débutConditionCe qui s'affiche
111 ≤ 5 → vraiTour numéro 1
222 ≤ 5 → vraiTour numéro 2
333 ≤ 5 → vraiTour numéro 3
444 ≤ 5 → vraiTour numéro 4
555 ≤ 5 → vraiTour numéro 5
—66 ≤ 5 → fauxon sort

À retenir

Tracez toujours ce tableau quand une boucle ne fait pas ce que vous attendez.

C'est la méthode des professionnels, et c'est la seule qui marche à coup sûr. Trois colonnes suffisent : le numéro du tour, la valeur des variables, et le résultat du test.

3Le piège : la boucle infinie

Attention

Si rien ne change dans la boucle, elle ne s'arrête jamais.

int compteur = 1;

while (compteur <= 5)
{
    Console.WriteLine($"Tour numéro {compteur}");
    // on a oublié d'augmenter le compteur !
}

compteur vaut toujours 1. La condition est toujours vraie. Le programme affiche « Tour numéro 1 » indéfiniment, jusqu'à ce que vous le tuiez.

Pour l'arrêter : cliquez dans la fenêtre noire et appuyez sur Ctrl + C. Ou fermez la fenêtre.

À retenir

Toute boucle while a besoin de trois choses.

  1. Une variable initialisée avant la boucle.
  2. Une condition qui la teste.
  3. Une modification de cette variable à l'intérieur du bloc.

Il manque l'une des trois ? Votre boucle est cassée. Vérifiez-les dans cet ordre à chaque fois.

Une boucle qui ne compte pas

La condition n'est pas forcément un compteur. Elle peut dépendre de l'utilisateur.

string reponse = "";

while (reponse != "stop")
{
    Console.Write("Tapez quelque chose (ou 'stop' pour quitter) : ");
    reponse = Console.ReadLine().ToLower();

    Console.WriteLine($"Vous avez tapé : {reponse}");
}

Console.WriteLine("Au revoir !");

Ici, c'est l'utilisateur qui décide quand la boucle s'arrête. Le nombre de tours n'est pas connu d'avance.

4do…while : passer au moins une fois

Avec while, la condition est testée avant le premier tour. Si elle est fausse dès le départ, le bloc n'est jamais exécuté.

Parfois, on veut le contraire.

string reponse;

do
{
    Console.Write("Voulez-vous continuer ? (oui/non) ");
    reponse = Console.ReadLine().ToLower();
}
while (reponse == "oui");

Console.WriteLine("Fin du programme.");

La question est forcément posée une première fois. Ce n'est qu'après qu'on teste s'il faut recommencer.

whiledo…while
La condition est testéeavant le blocaprès le bloc
Nombre minimum de tours01
Quand l'utiliseron peut ne rien faire du toutil faut faire au moins une fois

À retenir

La question à se poser : le bloc doit-il s'exécuter au moins une fois, quoi qu'il arrive ?

Attention au point-virgule après le while final du do…while. Il est obligatoire là, alors qu'il est interdit sur un while normal.

5L'ordinogramme : la flèche qui remonte

Une boucle n'a pas de forme à elle. Elle se dessine avec le losange de la fiche 8, et une flèche qui remonte.

Début compteur = 1 compteur <= 5 ? oui "Tour " + compteur compteur = compteur + 1 non Fin

À retenir

Ce qui fait une boucle sur un ordinogramme : une flèche qui remonte vers un point déjà parcouru.

C'est exactement ce que nous annoncions à la fiche 1 : le chemin ne descend pas toujours tout droit. Le voilà, ce chemin qui remonte.

Notez que le losange de la boucle ressemble à celui d'une condition, mais qu'une de ses sorties revient en arrière au lieu de continuer.

→Exercices

1Compter jusqu'à dixRecopier

Recopiez ce programme et lancez-le.

int compteur = 1;

while (compteur <= 10)
{
    Console.WriteLine($"Compteur : {compteur}");
    compteur = compteur + 1;
}

Console.WriteLine("Fini !");

Console.ReadKey();
  1. Combien de lignes s'affichent ?
  2. Que vaut compteur à la fin ?
  3. Supprimez la ligne compteur = compteur + 1; et relancez. Que se passe-t-il, et comment arrêtez-vous le programme ?

Solution

1. Dix lignes, de 1 à 10.

2. compteur vaut 11. C'est ce qui a fait échouer le test 11 <= 10 et permis de sortir.

C'est normal, et c'est important à comprendre : après une boucle, la variable dépasse toujours d'un cran la dernière valeur utilisée.

3. Boucle infinie. « Compteur : 1 » défile sans fin.

Pour l'arrêter : cliquez dans la fenêtre noire et faites Ctrl + C. Ou fermez simplement la fenêtre.

Rassurez-vous, il n'y a aucun danger pour votre ordinateur. C'est une erreur que tout le monde fait, y compris les professionnels.

2Le compteur de RadakassModifier

Reprenez le compteur d'évènements de la fiche 5, où vous aviez écrit trois fois nbEvents = nbEvents + 1;.

  1. Écrivez un programme qui demande combien d'évènements Radakass va vivre.
  2. Utilisez une boucle pour afficher « Évènement numéro X » autant de fois.
  3. À chaque évènement, Radakass perd 5 HP. Il commence à 100.
  4. Affichez ses HP après chaque évènement, et son état final.

Solution

int hp = 100;

Console.Write("Combien d'évènements ? ");
int nbEvents = int.Parse(Console.ReadLine());

int compteur = 1;

Console.WriteLine();
Console.WriteLine($"Radakass démarre avec {hp} HP");
Console.WriteLine();

while (compteur <= nbEvents)
{
    hp = hp - 5;
    Console.WriteLine($"Évènement numéro {compteur} : Radakass a {hp} HP");
    compteur = compteur + 1;
}

Console.WriteLine();

if (hp <= 0)
{
    Console.WriteLine("Radakass n'a pas survécu à l'aventure.");
}
else
{
    Console.WriteLine($"Radakass s'en sort avec {hp} HP !");
}

Console.ReadKey();
Ce que l'ordinateur affiche
Combien d'évènements ? 4

Radakass démarre avec 100 HP

Évènement numéro 1 : Radakass a 95 HP
Évènement numéro 2 : Radakass a 90 HP
Évènement numéro 3 : Radakass a 85 HP
Évènement numéro 4 : Radakass a 80 HP

Radakass s'en sort avec 80 HP !

Comparez avec la fiche 5. Là-bas, trois évènements demandaient neuf lignes de code, et il fallait tout réécrire pour en ajouter un quatrième.

Ici, le nombre d'évènements est demandé à l'utilisateur. Le programme fonctionne avec 3, avec 25 ou avec 1000, sans qu'on change une seule ligne.

Testez avec 25 : Radakass meurt. Le if de la fin le détecte correctement.

Les trois éléments de la boucle sont bien là : compteur = 1 avant, la condition compteur <= nbEvents, et compteur = compteur + 1 dedans.

3Le jeu du nombre mystèreCréer

Écrivez un petit jeu.

  1. Choisissez un nombre secret, écrit en dur dans le programme (par exemple 42).
  2. Demandez à l'utilisateur de deviner, encore et encore, tant qu'il n'a pas trouvé.
  3. À chaque essai, dites-lui « c'est plus grand » ou « c'est plus petit ».
  4. Comptez le nombre d'essais.
  5. Quand il trouve, félicitez-le et affichez le nombre d'essais.

Réfléchissez : faut-il un while ou un do…while ?

Solution

int secret = 42;
int proposition;
int essais = 0;

Console.WriteLine("=== LE NOMBRE MYSTÈRE ===");
Console.WriteLine("J'ai choisi un nombre entre 1 et 100.");
Console.WriteLine();

do
{
    Console.Write("Votre proposition : ");
    proposition = int.Parse(Console.ReadLine());

    essais = essais + 1;

    if (proposition < secret)
    {
        Console.WriteLine("C'est plus grand !");
    }
    else if (proposition > secret)
    {
        Console.WriteLine("C'est plus petit !");
    }
}
while (proposition != secret);

Console.WriteLine();
Console.WriteLine($"Bravo ! Trouvé en {essais} essai(s).");

Console.ReadKey();
Ce que l'ordinateur affiche
=== LE NOMBRE MYSTÈRE ===
J'ai choisi un nombre entre 1 et 100.

Votre proposition : 50
C'est plus petit !
Votre proposition : 25
C'est plus grand !
Votre proposition : 42

Bravo ! Trouvé en 3 essai(s).

Pourquoi do…while ?

Parce qu'il faut forcément demander au moins une proposition avant de pouvoir tester quoi que ce soit. Avec un while classique, il faudrait initialiser proposition à une valeur bidon avant la boucle — ça marche, mais c'est moins élégant.

Le compteur d'essais est incrémenté juste après la saisie, avant les tests. S'il était placé à la fin, le dernier essai gagnant ne serait pas compté.

Remarquez : quand l'utilisateur trouve, aucun des deux messages ne s'affiche. Ni « plus grand », ni « plus petit ». C'est voulu : le else if ne se déclenche que si la proposition est différente.

Pour aller plus loin : remplacez int secret = 42; par Random de = new Random(); suivi de int secret = de.Next(1, 101);, avant la boucle (voir la fiche 9). Le nombre change à chaque partie.

Je sais faire

Une case qui coince ? Relisez la partie concernée avant de passer à la fiche suivante.

← Fiche 9 Fiche 11 : Répéter un nombre connu de fois →