Keyboard shortcuts

Touchez ← ou → pour naviguer les chapitres

Touchez S ou / pour chercher dans le livre

Touchez ? pour afficher ce message

Touchez Esc pour masquer ce message

Accueil > Programmer avec Java > Structures de contrĂŽle >

📚 Boucles

Survol et attentes

Définitions

La rĂ©pĂ©tition conditionnelle d’un bloc de code est un autre concept fondamental de la programmation. Elle permet aux programmes de devenir puissants en profitant de la vitesse d’exĂ©cution de l’ordinateur et prĂ©vient la rĂ©pĂ©tition de code.

La boucle while est la plus polyvalente et peut servir à tous les contextes. La boucle for est plus spécialisée et est utilisée pour traiter une suite de nombres.

boucle
une structure de contrĂŽle qui rĂ©pĂšte un bloc de code tant qu’une condition est vraie.

itération une seule exécution du bloc de code dans une boucle.

mécanisme de mise à jour
combinaison de variables et d’instructions qui ont l’objectif d’amener la condition de la boucle Ă  false et prĂ©venir les boucles infinies.
variable de contrĂŽle
une variable qui est utilisée pour contrÎler la condition de la boucle.
variable accumulateur
variable qu’on dĂ©clare avant une boucle qui collecte des valeurs pendant les itĂ©rations de la boucle, comme une somme ou une liste de noms.
drapeau booléen
une variable boolĂ©enne utilisĂ© pour reprĂ©senter l’état de quelque chose. Dans ce contexte, un drapeau boolĂ©en peut remplacer la condition de la boucle et sa valeur peut ĂȘtre modifiĂ©e Ă  l’intĂ©rieur du bloc de code.
break
mot-clĂ© Java qui force la sortie d’une boucle, peu importe la condition ou la position dans le bloc de code.
continue
mot-clĂ© Java qui force la boucle Ă  passer Ă  l’itĂ©ration suivante, ignorant toutes les instructions restantes dans le bloc de code.

Objectifs d’apprentissage

À la fin de cette leçon vous devrez ĂȘtre en mesure de :

  • DĂ©crire le rĂŽle des trois Ă©lĂ©ments d’une boucle : condition, bloc de code, mise Ă  jour.
  • DĂ©crire trois façons de formuler la condition d’une boucle : avec une variable de contrĂŽle, avec une variable boolĂ©enne, avec la constante true
  • Expliquer comment utiliser le mot-clĂ© break pour sortir d’une boucle.

CritĂšres de succĂšs

  • Je peux Ă©crire diffĂ©rentes structures de boucles selon le contexte du problĂšme.
  • Je peux utiliser des variables boolĂ©ennes pour Ă©viter la rĂ©pĂ©tition du code nĂ©cessaire pour valider une condition.

Boucle while

Voici la syntaxe de base pour une boucle while :

while (condition) {
    // bloc de code
    // mécanisme de mise à jour
}

boucle

C’est important de noter que l’exĂ©cution des instructions ne continue pas aprĂšs le bloc de code mais revient Ă  la condition. C’est ça qui forme la boucle. Si la condition est true, le bloc de code est rĂ©pĂ©tĂ©. Si la condition est false, l’exĂ©cution continue aprĂšs la boucle. Ici, le diagramme de flux donne une meilleure reprĂ©sentation de l’exĂ©cution rĂ©elle de Ă©tapes.

Exemple : Traiter une suite de nombres

Pour traiter une suite de nombres, on dĂ©finit d’abord une variable de contrĂŽle qui reprĂ©sente la valeur initiale de la suite. Ensuite, on dĂ©finit la condition de la boucle en fonction de cette variable de contrĂŽle. Finalement, on met Ă  jour la variable de contrĂŽle Ă  l’intĂ©rieur du bloc de code.

Placez le code suivant dans un fichier qui s’appelle LoopExamples1.java et exĂ©cutez-le pour voir les rĂ©sultats.

Par exemple, pour afficher les nombres de 1 Ă  10 :

Avec while

void whileLoop() {
    int i = 1;          // initialiser la variable de contrĂŽle
    while (i <= 10) {   // condition utilisant la variable de contrĂŽle
        System.out.println(i);
        i++; // mise à jour de la variable de contrÎle (incrémenter)
    }
}

void main() {
    whileLoop();
}

boucle while 1

L'exécution du code précédent commence à quelle ligne?

La ligne 9, Ă  la signature de main. La ligne 10 envoie ensuite l’exĂ©cution Ă  la ligne 1 en appelant whileLoop().

Combien de fois est-ce que la ligne 2 sera-t-elle exécutée?

Une seule fois. Elle vient juste avant le début de la déclaration while.

Combien de fois est-ce que la ligne 4 sera-t-elle exécutée?

Dix fois : une pour chaque valeur de i qui donne un résultat true à i <= 10

Combien de fois est-ce que la ligne 3 sera-t-elle exécutée?

11 fois! Oui, on doit aussi visiter la condition pour la fois que la condition est fausse, quand i est Ă©gale Ă  11, brisant la boucle. La condition est donc Ă©valuĂ©e une fois de plus que le nombre d’itĂ©ration.

Quelle sera la sortie du code précédant?

La sortie est :

1
2
3
4
5
6
7
8
9
10

Avec for

La boucle for est spécialisée pour ce type de tùche. Elle inclut les trois éléments clés de la boucle directement dans sa déclaration. Sa syntaxe est la suivante :

for (initialisation; condition; mise Ă  jour) {
    // bloc de code
}

Par exemple, pour afficher les nombres de 1 Ă  10 avec une boucle for :

void forLoop() {
    for (int i = 1; i <= 10; i++) { // les trois éléments séparés par des ;
        System.out.println(i);
    }
}

Si on appelle aussi cette mĂ©thode dans main, on aura exactement la mĂȘme sortie qu’avec la version while. Ajoutez-le Ă  votre fichier LoopExamples1.java pour le vĂ©rifier.

Défi

Pouvez vous trouver et afficher la somme de toutes les valeurs de 1 Ă  10 en modifiant une des boucles ci-dessus?

Indice : vous aurez besoin d’une variable accumulateur en plus de la variable de contrîle.

Exemple : Valider des donnĂ©es d’entrĂ©e

Un autre contexte pour une boucle est demander une rĂ©ponse Ă  l’utilisateur tant que la rĂ©ponse n’est pas valide.

Une situation typique est lorsqu’on demande une confirmation oui/non Ă  l’utilisateur. On peut utiliser une boucle while pour s’assurer que la rĂ©ponse est valide.

Voici deux façons de le faire. Il en existe d’autres! Vous pouvez tester ces mĂ©thodes dans un nouveau fichier LoopExamples2.java.

Avec une variable de contrĂŽle pour la condition de la boucle

import java.util.*;

final Scanner INPUT = new Scanner(System.in);

String again() {
    String answer = ""; // variable : contrĂŽle ET accumulateur

    while (!(answer.equals("oui") || answer.equals("non"))) { 
        System.out.print("Voulez-vous continuer? (oui/non) > ");
        answer = INPUT.next().toLowerCase();
            // mise à jour avec une réponse en minuscules
    }
    return answer;
}

void main() {
    while (again().equals("oui")) {
        // code à répéter
    }
    System.out.println("Au revoir");
}

boucle while 2

Il y a deux conditions dans ce code.

Le plus complexe est dans again() : !(answer.equals("oui") || answer.equals("non")) :

  • Le ! au dĂ©but indique qu’on veut inverser le rĂ©sultat entre les parenthĂšses - c’est parce que ce qu’on dĂ©crit entre parenthĂšses correspond Ă  ce que nous voulons, mais la boucle devrait se rĂ©pĂ©ter dans le cas contraire
  • Le || est l’opĂ©rateur “ou” qui sera vrai si l’une ou l’autre des conditions est vraie.
  • On utilise .equals() pour comparer l’égalitĂ© parce qu’on compare deux String.

Plaçant tout ça ensemble avec le mot-clé while, on devrait lire :

si la réponse EST "oui" OU "non", NE PAS répéter le bloc de code

La deuxiĂšme condition est dans main : again().equals("oui") :

  • again retourne un String au programme qui est directement utilisĂ© dans la comparaison

Voici un exemple d’interaction avec l’utilisateur pour ce programme :

Voulez-vous continuer? (oui/non) > peut-ĂȘtre
Voulez-vous continuer? (oui/non) > n
Voulez-vous continuer? (oui/non) > Non
Au revoir
Combien des fois est-que la condition de la boucle dans la méthode again() est-elle évaluée durant l'intéraction ci-dessus?

4 fois : une au dĂ©but avec la valeur initiale de "" et une pour chaque rĂ©ponse de l’utilisateur

Pourquoi est-ce que la réponse "Non" a-t-elle été acceptée?

INPUT.next() nous donne "Non" ce qui ne serait pas equals Ă  "non". Mais ce n’est pas ce qui se rend Ă  la condition : on passe la rĂ©ponse brute Ă  la mĂ©thode toLowerCase() qui convertit tout en minuscules. Ainsi, answer contient la valeur "non" ce qui permet Ă  la condition d’ĂȘtre vraie.

Défi

La condition pour évaluer si la réponse était invalide (alors répéter la boucle) est la suivante :

!(answer.equals("oui") || answer.equals("non")) = si la réponse EST "oui" OU "non", NE PAS répéter le bloc de code

On peut Ă©crire cette mĂȘme condition d’une autre façon.

Quelle condition serait équivalente à "répéter la boucle si la réponse n'EST PAS "oui" ET la réponse n'EST PAS "non"?

!answer.equals("oui") && !answer.equals("non")

Exemple : RĂ©pĂ©ter un programme jusqu’à ce que l’utilisateur dĂ©cide de le quitter

Un autre contexte commun est une boucle de programme intentionellement infinie. Pour ces cas, la dĂ©claration de la boucle est while (true). C’est ce qui se passe avec les fenĂȘtres de vos applications : l’affichage est rafraĂźchi en permanence jusqu’à ce que vous fermiez la fenĂȘtre.

Mais comment quitter une boucle oĂč la condition de boucle est une constante? RĂ©ponse : on utilise une instruction break Ă  l’intĂ©rieur du bloc de code. L’instruction break est insĂ©rĂ©e dans une sĂ©lection qui Ă©value si la condition de sortie est atteinte.

while (true) { // passe tout droit
    // bloc de code
    if (condition) {
        break; // sortie de la boucle
    }
}

infinite_loop

Notez que dans le diagramme pour une boucle while (true) la condition de boucle se trouve Ă  l’intĂ©rieur et parfois Ă  la fin des instructions de la boucle. Le “while (true)” n’est pas reprĂ©sentĂ© directement parce que ça n’affecte pas le flux des Ă©tapes.

Notez que le mot-clĂ© while n’apparaĂźt jamais dans ces diagrammes, ni les autres mot-clĂ©s (p. ex.: if, else, true, break). Il s’agit simplement de conditions et d’embranchements dans les diagrammes. Dans les divers cas d’itĂ©ration, une des branches forme une boucle. Sinon on parle de sĂ©lection / d’embranchement tout court.

Retour sur la validation de données

On pourrait remplacer la version de main dans LoopExamples2.java avec la version suivante :

void main() {
    while (true) {
        // code de la tĂąche

        // code pour demander Ă  l'utilisateur s'il veut continuer

        if (again().equals("non")) {
            break; // sortie de la boucle
        } else {
            // code pour réinitialiser les variables de la tùche
        }
    }
}

Pour d’autres tñches

Un autre exemple est pour faire la somme d’une sĂ©rie de nombres. On demande Ă  l’utilisateur d’entrer un nombre Ă  la fois. Si le nombre est -999, on quitte la boucle. Sinon, on ajoute le nombre Ă  la somme.

Reprendre cet exemple dans un nouveau fichier LoopExamples3.java.

import java.util.*;

void main() {
    Scanner input = new Scanner(System.in);

    int sum = 0; // variable accumulateur

    while (true) {
        System.out.print(
            "Entrez un nombre entier (-999 pour quitter) : "
        );
        
        int num = input.nextInt(); // variable de contrĂŽle
        if (num == -999) {
            break; // mot-clé pour quitter la boucle
        } else {
            sum += num;
        }
    }
    System.out.println("La somme est " + sum);
}

while avec break

Et voici deux exemples d’interaction avec l’utilisateur :

Entrez un nombre entier (-999 pour quitter) : 5
Entrez un nombre entier (-999 pour quitter) : 10
Entrez un nombre entier (-999 pour quitter) : 15
Entrez un nombre entier (-999 pour quitter) : -999
La somme est 30
Entrez un nombre entier (-999 pour quitter) : -3
Entrez un nombre entier (-999 pour quitter) : 0
Entrez un nombre entier (-999 pour quitter) : 3
Entrez un nombre entier (-999 pour quitter) : 6
Entrez un nombre entier (-999 pour quitter) : -999
La somme est 6

Exercices

Pratique

Travaillez dans le répertoire GitHub partagé par votre enseignant pour la pratique et les exercices.

Contexte

Voici un autre exemple qui nous donne la partie entiĂšre du logarithme d’une valeur x en base 2. On divise x jusqu’à ce que sa valeur soit infĂ©rieure Ă  1. Le nombre de divisions est le logarithme de x en base 2.

int x = 1024; // valeur Ă  traiter; aussi la variable de contrĂŽle
System.out.print("Le log2 de " + x + " est ");

int divCounter = 0;
while (x > 1) { // condition
    divCounter++;
    x = x/2; // mise Ă  jour (divise par 2)
}
System.out.println(divCounter);

et sa sortie:

Le log2 de 1024 est 10

ProblÚme à résoudre

Écrire une boucle while (ou for) qui utilise une mise Ă  jour autre que l’incrĂ©mentation. Par exemple, on peut utiliser une dĂ©crĂ©mentation, une multiplication ou une division, ou n’importe quel calcul que vous souhaitez en autant que la variable de contrĂŽle se rapproche de la condition false Ă  chaque itĂ©ration. L’exemple prĂ©cĂ©dant pour le logarithme utilise une division.

© 2022-2025 David Crowley