Contactez-nous

Boucles `while` (quand utiliser)

Découvrez les boucles `while` et `do-while` en Kotlin. Apprenez leur syntaxe et comprenez quand les préférer à la boucle `for` pour des répétitions conditionnelles.

Introduction : quand la condition prime sur la séquence

Nous avons exploré la boucle `for`, idéale pour parcourir des séquences bien définies comme des plages de nombres ou des collections. Cependant, tous les scénarios de répétition ne s'inscrivent pas dans ce moule. Parfois, nous devons répéter un bloc de code non pas un nombre fixe de fois ou pour chaque élément d'un ensemble connu, mais tant qu'une certaine condition reste vraie. Le nombre d'itérations peut être inconnu à l'avance et dépendre de ce qui se passe à l'intérieur de la boucle elle-même.

C'est là qu'interviennent les boucles `while` et sa variante `do-while`. Elles offrent un mécanisme de répétition basé sur l'évaluation continue d'une condition booléenne. Comprendre quand et comment les utiliser est essentiel pour gérer des situations où la fin de la boucle n'est pas déterminée par la fin d'une séquence, mais par un état spécifique à atteindre.

La boucle `while` : vérifier avant d'agir

La boucle `while` est la forme la plus directe de boucle conditionnelle. Elle évalue une condition avant chaque itération potentielle. Si la condition est `true`, le corps de la boucle est exécuté. Ensuite, la condition est réévaluée, et le processus continue tant que la condition reste `true`. Si la condition est `false` dès la première vérification, le corps de la boucle n'est jamais exécuté.

Syntaxe :

while (condition) {
    // Bloc de code à exécuter tant que la condition est true
    // Important : le corps doit pouvoir influencer la condition pour éviter une boucle infinie
}

Exemple : Simuler un compte à rebours simple.

fun main() {
    var countdown = 5
    println("Début du compte à rebours :")

    while (countdown > 0) { // Condition: countdown est-il supérieur à 0 ?
        println(countdown)
        countdown-- // Décrémentation: influence la condition pour la prochaine itération
    }

    println("Décollage !")
}

Dans cet exemple, la boucle continue tant que `countdown` est strictement positif. A chaque itération, la valeur est affichée, puis décrémentée. Lorsque `countdown` atteint 0, la condition `0 > 0` devient `false`, et la boucle se termine.

Un autre exemple : traiter des éléments d'une liste mutable jusqu'à ce qu'elle soit vide.

fun main() {
    val tasks = mutableListOf("Tâche A", "Tâche B", "Tâche C")
    println("\nTraitement des tâches :")

    while (tasks.isNotEmpty()) { // Condition: la liste n'est-elle pas vide ?
        val currentTask = tasks.removeAt(0) // Retire et récupère le premier élément (influence la condition)
        println("- Traitement de: $currentTask")
    }

    println("Toutes les tâches sont terminées.")
}

La boucle `do-while` : agir puis vérifier

La boucle `do-while` est une variante de `while`. Sa différence fondamentale réside dans le moment où la condition est vérifiée : elle est évaluée après l'exécution du corps de la boucle. Cela garantit que le corps de la boucle sera exécuté au moins une fois, même si la condition est initialement `false`.

Syntaxe :

do {
    // Bloc de code à exécuter (au moins une fois)
    // Doit aussi pouvoir influencer la condition
} while (condition) // Vérification de la condition après l'exécution du bloc

Exemple typique : demander une entrée utilisateur jusqu'à ce qu'elle soit valide. Il faut demander au moins une fois.

fun main() {
    var input: String
    val secretNumber = "kotlin"

    do {
        print("Devinez le mot secret : ")
        // readlnOrNull() lit une ligne depuis la console, ou retourne null si fin de flux
        input = readlnOrNull() ?: "" // Utilise ?: "" pour éviter null, donne une chaîne vide si readlnOrNull est null
        if (input != secretNumber) {
            println("Incorrect, essayez encore !")
        }
    } while (input != secretNumber) // Condition: l'entrée est-elle différente du secret ?

    println("Bravo ! Vous avez trouvé le mot secret '$secretNumber'.")
}

Ici, l'utilisateur est invité à entrer une valeur au moins une fois. La boucle ne se répète que si l'entrée fournie n'est pas égale à `secretNumber`.

Quand choisir `while` ou `do-while` plutôt que `for` ?

La question clé est de savoir quand opter pour une boucle `while` ou `do-while` au lieu de la boucle `for`, généralement plus simple pour les séquences.

Utilisez `while` ou `do-while` lorsque :
  • Le nombre d'itérations est inconnu à l'avance : La boucle doit continuer non pas pour un nombre fixe d'éléments, mais jusqu'à ce qu'un certain état soit atteint (ex: fichier lu jusqu'à la fin, utilisateur entre une commande 'quitter', algorithme converge vers une solution).
  • La condition de fin dépend de calculs ou d'événements internes à la boucle : La décision de continuer ou d'arrêter la boucle est prise en fonction de résultats obtenus ou d'états modifiés à l'intérieur même du corps de la boucle (ex: vider une file d'attente, attendre une connexion réseau).
  • Vous devez garantir au moins une exécution : Si le bloc de code doit impérativement s'exécuter une première fois avant même de vérifier si une répétition est nécessaire, la boucle `do-while` est le choix naturel (ex: afficher un menu et demander une option au moins une fois).
  • La logique ressemble plus à "Répète tant que..." qu'à "Pour chaque élément..." : Si votre pensée naturelle pour décrire la répétition implique une condition de maintien plutôt qu'un parcours d'éléments, `while` est souvent plus expressif.
Préférez `for` lorsque :
  • Vous parcourez tous les éléments d'une collection (`List`, `Set`, `Map`).
  • Vous itérez sur une plage de nombres (`1..10`, `0 until size`).
  • Vous avez besoin de l'indice et de la valeur d'une collection (`collection.withIndex()`).

En résumé, `for` est idéal pour l'itération sur des séquences finies et connues, tandis que `while` et `do-while` sont conçues pour les répétitions dont la durée est déterminée par une condition dynamique.

Attention aux boucles infinies

Un risque inhérent aux boucles `while` et `do-while` est la création accidentelle d'une boucle infinie. Cela se produit si la condition de la boucle reste toujours `true`, empêchant ainsi le programme de sortir de la boucle et de continuer son exécution (il "gèle" ou consomme toutes les ressources).

Pour éviter cela, il est crucial de s'assurer que le corps de la boucle contient une logique qui, à un moment donné, modifiera l'état du programme de manière à rendre la condition `false`. Dans notre exemple `while (countdown > 0)`, c'est l'instruction `countdown--` qui garantit que la condition finira par devenir fausse. Si on oubliait cette ligne, la boucle tournerait indéfiniment en affichant '5'.

Soyez donc particulièrement vigilant à la logique de modification de la condition à l'intérieur de vos boucles `while` et `do-while`.

Récapitulatif : `while` et `do-while` pour les boucles conditionnelles

Les boucles `while` et `do-while` sont vos outils pour les répétitions basées sur une condition :

  • `while (condition) { ... }` : Vérifie la condition avant chaque itération. Le corps peut ne jamais s'exécuter.
  • `do { ... } while (condition)` : Exécute le corps une fois, puis vérifie la condition après chaque itération. Le corps s'exécute toujours au moins une fois.
  • Choisissez-les lorsque le nombre d'itérations n'est pas connu à l'avance ou dépend d'un état dynamique.
  • Préférez `for` pour itérer sur des séquences (collections, plages).
  • Assurez-vous que la condition peut devenir `false` pour éviter les boucles infinies.

En choisissant judicieusement entre `for`, `while`, et `do-while`, vous pouvez exprimer clairement l'intention de vos boucles et écrire une logique de répétition adaptée à chaque situation.