Première · Langages et programmation

Boucles non bornées : raisonner avec while

Combien de fois faut-il répéter une action pour atteindre un objectif ? Lorsque le nombre de répétitions dépend de l’évolution des données, une boucle while exprime directement la condition de poursuite. Encore faut-il comprendre ce qui permettra de sortir.

SofienAvec SofienIngénieur et enseignant en informatique
Dans ce chapitre

Un cap pour ce chapitre

Ce que vous saurez faire

  • Suivre une boucle while et expliquer son arrêt
  • Choisir une initialisation et une mise à jour cohérentes
  • Détecter une boucle infinie ou un décalage de borne
Les bases utiles pour commencer

Tester avant chaque passage

while signifie « tant que ». Python évalue la condition avant d’entrer dans le corps, puis la réévalue après chaque exécution complète du bloc. Le corps peut donc ne jamais s’exécuter. Avec reserve = 3 et while reserve >= 5, aucune action n’est entreprise. Cette règle distingue une boucle while d’une répétition qui imposerait un premier essai. Lors d’une trace, notez la valeur de la condition au départ, les modifications du corps et le test suivant. La dernière vérification fausse explique la sortie même si elle ne produit aucun passage supplémentaire.

Il y a un test réussi par passage, puis un dernier test faux si la boucle se termine normalement. Une exécution comportant quatre passages évalue donc cinq fois la condition. Cette distinction est utile lorsque l’on demande un nombre d’opérations : il faut préciser si l’on compte les transformations ou les évaluations du test.

Faire évoluer ce que l’on teste

Supposons qu’une réserve commence à 2 unités et double jusqu’à atteindre au moins 20. La condition est reserve < 20 et la mise à jour reserve = reserve * 2. Les réserves successives sont 2, 4, 8, 16 puis 32. On sort à 32, pas à 20 : franchir un seuil ne signifie pas l’atteindre exactement. Une condition reserve != 20 ne fonctionnerait pas ici, puisque les doublements ne produisent jamais 20. Le choix du comparateur doit donc correspondre au mécanisme qui fait évoluer les valeurs.

Une variable peut évoluer sans rapprocher l’exécution de la sortie. Ajouter deux à un entier qui doit devenir pair ne change pas sa parité. Pour analyser une boucle, cherchez donc aussi une propriété conservée par la mise à jour. Elle peut montrer que la sortie est inaccessible.

Distinguer l’état et le nombre d’étapes

Un compteur d’étapes répond à une question différente de la valeur transformée. On initialise etapes à zéro avant la boucle, puis on l’incrémente une fois par transformation. Pour la réserve précédente, quatre doublements sont nécessaires. Si l’on initialise le compteur à un sans justification, le résultat sera décalé. Une bonne explication associe chaque variable à une phrase : reserve est la quantité disponible maintenant ; etapes est le nombre de doublements déjà effectués. Ces phrases permettent de vérifier l’initialisation aussi bien que le corps.

reserve = 2
etapes = 0
while reserve < 20:
    reserve = reserve * 2
    etapes = etapes + 1
print(reserve, etapes)

Le compteur augmente après la transformation qu’il mesure. Si l’on veut mémoriser les valeurs avant chaque transformation, il faut le préciser dans la trace. Une colonne « avant », une colonne « après » et une colonne « transformations effectuées » suppriment les ambiguïtés entre premier état et première étape.

Justifier que la boucle finira

Observer quelques sorties ne prouve pas que toutes les entrées valides terminent. Pour une quantité entière restante qui diminue de un à chaque passage et reste positive tant que le corps s’exécute, on dispose d’un argument simple : elle ne peut pas diminuer indéfiniment parmi les entiers positifs. C’est l’idée d’un variant. Pour d’autres évolutions, on adapte le raisonnement : doubler une quantité strictement positive finit par dépasser tout seuil fixe. Commencer à zéro invaliderait cet argument, puisque doubler zéro laisse zéro. Les préconditions font donc partie de la preuve.

Un variant doit être entier, rester positif ou nul dans les états considérés et diminuer strictement à chaque tour. Dire seulement « la valeur diminue » est insuffisant : des nombres positifs divisés par deux peuvent rester strictement positifs indéfiniment dans un modèle mathématique exact.

Calculer un quotient par retraits successifs

Pour répartir vingt-trois jetons par groupes de cinq, on initialise reste = 23 et groupes = 0. Tant que reste >= 5, on enlève cinq au reste et on augmente le nombre de groupes. Les restes deviennent dix-huit, treize, huit puis trois ; quatre groupes ont été constitués. À chaque étape, 23 == 5 * groupes + reste. Cette égalité est conservée, car ajouter un groupe retire exactement cinq au reste.

À la sortie, le reste est positif ou nul et strictement inférieur à cinq. On obtient donc quotient quatre, reste trois. La quantité restante constitue un variant naturel : elle diminue strictement sans devenir négative. Le cas de zéro jeton termine immédiatement avec zéro groupe.

Rechercher un premier événement dans un tableau

On cherche la première valeur négative de [4, 0, -3, 8]. Avec un indice initialisé à zéro, la poursuite doit vérifier à la fois que l’indice est valide et que la valeur courante n’est pas négative : indice < len(valeurs) and valeurs[indice] >= 0. L’ordre protège l’accès au tableau. À chaque tour, l’indice augmente. On sort ici à l’indice deux.

Si aucune valeur négative n’existe, l’indice atteint la longueur du tableau. On interprète alors la sortie comme une absence, sans tenter de lire cet indice. Un tableau vide suit immédiatement ce même cas. La condition de sortie peut donc recouvrir deux causes différentes, qu’un test après la boucle permet de distinguer.

À vous de faire varier les choses

Le seuil sera-t-il atteint ?

Choisissez départ, pas et condition. Le simulateur s’arrête après 24 passages pour vous permettre d’examiner une progression qui ne termine pas.

Lire le résultat de l’expérience initiale

Sortie après 5 passages

Le test final est faux pour n = 11. La dernière transformation est déjà comptée.

PassageAvantTestAprès
01Vrai3
13Vrai5
25Vrai7
37Vrai9
49Vrai11

Un seuil se raisonne avec les valeurs réellement produites. La limite de sécurité du simulateur ne prouve pas à elle seule une boucle infinie.

De la compréhension à l’autonomie

À vous de résoudre

Cherchez d’abord par vous-même. Vérifiez les résultats demandés, utilisez les indices si nécessaire, puis comparez votre méthode à la correction.

Exercice 1 · S’entraîner#

Le premier test suffit

On initialise n = 10 et compteur = 0, puis on répète n = n + 3 et compteur = compteur + 1 tant que n < 10. Donnez l’état final.

Indice 1

Le test a lieu avant le corps.

Indice 2

10 < 10 est faux.

Comprendre la correction

Le corps n’est jamais exécuté. n reste 10 et compteur reste 0. Affirmer qu’il y a un passage reviendrait à placer mentalement le test après le corps. La trace contient simplement l’état initial et la condition fausse : cela suffit à justifier la sortie.

Exercice 2 · S’entraîner#

Atteindre ou dépasser

Une valeur commence à 3 et double tant qu’elle est inférieure à 25. Donnez les valeurs obtenues et le nombre de doublements.

Indice 1

Écrivez les puissances successives obtenues à partir de 3.

Indice 2

Il faut inclure le dernier doublement qui rend la condition fausse.

Comprendre la correction

La suite des états est 3, 6, 12, 24, 48. Quatre doublements ont lieu. Après 24, le test 24 < 25 reste vrai ; il faut donc encore doubler. Le résultat 48 dépasse le seuil, ce qui est compatible avec une règle demandant d’atteindre au moins 25.

Exercice 3 · S’entraîner#

Une égalité inaccessible

Un compteur commence à 1 et augmente de 2 tant qu’il est différent de 10. Pourquoi la boucle ne termine-t-elle pas ? Proposez une condition pour s’arrêter dès que 10 est atteint ou dépassé.

Indice 1

Quel point commun ont toutes les valeurs successives ?

Indice 2

La condition de poursuite doit exprimer que le seuil n’est pas encore franchi.

Comprendre la correction

Les valeurs restent impaires : 1, 3, 5, 7, 9, 11, etc. Le compteur ne vaut donc jamais 10. La condition compteur < 10 convient : la boucle sort à 11. Remplacer != par < traduit ici correctement la notion de seuil, sans prétendre atteindre exactement 10.

Exercice 4 · S’entraîner#

Prouver une soustraction répétée

Un entier n positif est diminué de 3 tant que n >= 3. Expliquez pourquoi la boucle termine et quelles sont les valeurs finales possibles.

Indice 1

La valeur reste entière et diminue strictement.

Indice 2

À la sortie, la condition n >= 3 est fausse, et aucune soustraction n’a rendu n négatif.

Comprendre la correction

Chaque passage réduit n de 3, tout en le laissant positif ou nul puisque l’on soustrait seulement lorsque n >= 3. Une suite d’entiers naturels strictement décroissante ne peut être infinie. À la sortie, 0 <= n < 3 ; les seules valeurs possibles sont donc 0, 1 et 2.

Exercice 5 · Approfondir et relier#

Une division expliquée par un invariant

On retire 6 à un reste initial de 29 tant que ce reste est au moins 6 ; un compteur commence à zéro et augmente à chaque retrait. Donnez la trace des restes, le compteur final et une égalité conservée. Justifiez l’arrêt.

Indice 1

À chaque retrait, un groupe supplémentaire est compté.

Indice 2

Le reste reste naturel et diminue de six.

Comprendre la correction

Les restes après retrait sont 23, 17, 11 et 5. Le compteur final vaut quatre. L’égalité 29 == 6 * compteur + reste est vraie au départ et conservée par le corps. Le reste diminue parmi les entiers naturels ; la boucle termine. À la sortie, cinq est inférieur à six et la décomposition est correcte.

Exercice 6 · Approfondir et relier#

Deux conditions, deux comportements

Un entier commence à 2 et augmente de 4. Comparez les conditions de poursuite n < 15 et n != 15. Donnez les cinq premiers états en incluant le départ. Pour la première version, comptez les passages et les évaluations du test.

Indice 1

Toutes les valeurs produites ont le même reste dans la division par quatre.

Indice 2

La sortie normale comporte un dernier test faux.

Comprendre la correction

Les états sont 2, 6, 10, 14 et 18. Avec le test strict, quatre passages ont lieu et cinq tests sont évalués : le dernier constate que 18 n’est pas inférieur à 15. Avec la différence, aucune valeur ne vaut 15, car toutes ont un reste deux modulo quatre. Cette seconde boucle ne termine pas.

Exercice 7 · Approfondir et relier#

Trouver sans sortir du tableau

On cherche la première valeur strictement supérieure à 10 dans [4, 10, 7, 12, 15]. Proposez une condition protégée avec un indice, donnez l’indice trouvé puis adaptez l’interprétation à [4, 10, 7] et au tableau vide.

Indice 1

Tant qu’une valeur est inférieure ou égale à dix, il faut continuer.

Indice 2

Vérifiez la validité de l’indice avant d’accéder au tableau.

Comprendre la correction

On part de i = 0 et on répète i = i + 1 tant que i < len(t) and t[i] <= 10. Le premier tableau donne l’indice trois. Le deuxième termine à trois, égal à sa longueur : aucune valeur ne convient. Le tableau vide termine à zéro pour la même raison. L’accès ne s’effectue jamais après la dernière case.

Les erreurs qui méritent un détour

Modifier une autre variable que celle testée
Vérifiez que le corps peut réellement changer la valeur de vérité de la condition.
Tester une égalité que la suite saute
Une progression par pas peut dépasser une cible sans la rencontrer : choisissez alors une inégalité.

La fiche à garder

L’essentiel à retenir

  • while teste avant chaque passage.
  • Le compteur mesure les transformations déjà effectuées.
  • La terminaison dépend du corps, de la condition et des entrées autorisées.

Cette notion au bac

Retrouvez ces idées dans un sujet complet, avec des indices, une correction expliquée et des ateliers.

Le prochain pas

Retrouver le catalogue de Première

Ce chapitre s’appuie sur le programme officiel de Première (PDF, nouvel onglet). Les explications et exercices sont proposés pour l’apprentissage.