Bonjour ! Dans la leçon précédente, nous avons exploré les boucles imbriquées, un outil puissant pour traiter des données à deux dimensions comme des grilles ou des tables de multiplication. Vous avez appris que pour chaque tour de la boucle externe, la boucle interne s'exécute dans son intégralité.
Introduction
Aujourd'hui, nous allons nous pencher sur un problème fondamental et très courant en programmation : la boucle infinie. C'est un bug qui se produit lorsqu'une boucle ne respecte pas sa condition de sortie et, par conséquent, ne s'arrête jamais. Un programme bloqué dans une boucle infinie devient inutilisable.
L'objectif de cette leçon est d'apprendre à identifier la cause d'une boucle infinie et à la corriger. Comprendre ce phénomène est une étape cruciale dans votre parcours pour écrire du "code clean", car cela vous apprend à maîtriser le flux d'exécution de vos algorithmes et à anticiper les erreurs logiques. Nous verrons les erreurs classiques qui mènent à ce problème et les stratégies pour les détecter et les prévenir.
1. Qu'est-ce qu'une Boucle Infinie ?
Une boucle infinie est une boucle dont la condition de continuation reste toujours vraie. Comme la condition de sortie n'est jamais atteinte, le programme répète les mêmes instructions à l'infini, sans jamais passer à la suite.
Il est important de distinguer deux types de boucles infinies :
- Les boucles infinies inattendues : Ce sont des bugs. Elles sont le résultat d'une erreur de logique dans votre algorithme. Le programme semble "gelé" ou "planté". C'est le principal sujet de cette leçon.
- Les boucles infinies intentionnelles : Ce ne sont pas des erreurs. Parfois, on a besoin qu'un programme tourne en continu jusqu'à une action externe (par exemple, l'utilisateur qui clique sur "Quitter"). Dans ce cas, on utilise souvent une structure
Tant que VRAIavec une instructionInterrompre(oubreaken programmation) à l'intérieur pour contrôler la sortie.
Le document suivant explique très bien cette distinction et comment une boucle Tant que peut dériver en boucle infinie inattendue.
[PDF] Corrigé Cours Python Niveau 2 Boucles Tests
Pour commencer, lisons une section qui explique comment une boucle peut devenir infinie et pourquoi ces boucles inattendues sont une source de bugs.
Lisez la partie intitulée "Comment une boucle While devient-elle une boucle infinie ?" jusqu'à la fin de la section (avant "Application"). Concentrez-vous sur la raison fondamentale (la condition reste toujours vraie) et sur la différence entre les boucles infinies inattendues (bugs) et attendues (utiles en programmation).
2. Les Causes Courantes des Boucles Infinies
Pour corriger une boucle infinie, il faut d'abord en comprendre la cause. Voici les erreurs les plus fréquentes.
Cause n°1 : Oubli de modification de la variable de condition
C'est l'erreur la plus classique. La boucle Tant que continue tant qu'une condition est vraie. Si la variable utilisée dans cette condition n'est jamais modifiée à l'intérieur de la boucle, la condition restera toujours vraie.
Exemple d'erreur :
Algorithme CompteInfini
Variables
compteur : Entier
Début
compteur ← 1
Tant que compteur <= 5 Faire
Afficher "Le compteur est à " + compteur
// Erreur : on a oublié de faire avancer le compteur !
FinTantQue
Afficher "Terminé." // Cette ligne ne sera jamais atteinte
Fin
Dans cet exemple, compteur vaudra toujours 1. La condition 1 <= 5 sera donc toujours vraie, et le programme affichera "Le compteur est à 1" indéfiniment.
Correction :
Il faut s'assurer qu'une instruction dans la boucle fait évoluer la variable vers la condition de sortie.
Algorithme CompteCorrect
Variables
compteur : Entier
Début
compteur ← 1
Tant que compteur <= 5 Faire
Afficher "Le compteur est à " + compteur
compteur ← compteur + 1 // Correction ! Le compteur avance.
FinTantQue
Afficher "Terminé."
Fin
Le document suivant vous montre des exemples concrets de cette erreur et comment l'éviter.
Structures de Contrôle en Python
Ce document illustre parfaitement la cause numéro 1 et propose des stratégies pour l'éviter. Il est très orienté vers la pratique.
Lisez la section "4.2. Éviter la boucle infinie". Regardez attentivement l'exemple "BOUCLE INFINIE CLASSIQUE" et sa correction. Portez aussi attention au point "1. Toujours modifier la variable de condition".
Cause n°2 : Logique de la condition défaillante
Parfois, la variable est bien modifiée, mais la condition est écrite de telle manière qu'elle ne peut jamais devenir fausse.
Exemple d'erreur :
Algorithme LogiqueErronée
Variables
k : Entier
Début
k ← 10
// La condition `k > 5 OU k < 20` est toujours vraie si k diminue depuis 10
Tant que k > 5 OU k < 20 Faire
Afficher "k = " + k
k ← k - 1
FinTantQue
Fin
Ici, tant que k est supérieur à 5, la première partie (k > 5) est vraie. Lorsque k devient 5, 4, etc., la seconde partie (k < 20) reste vraie. La condition globale est donc impossible à rendre fausse.
Cause n°3 : Réinitialisation accidentelle dans la boucle
Une autre erreur subtile consiste à réinitialiser la variable de contrôle à sa valeur de départ à l'intérieur de la boucle.
Exemple d'erreur :
Algorithme ReinitialisationFatale
Variables
total : Entier
Début
total ← 0
Tant que total < 10 Faire
total ← 0 // Erreur : le total est remis à zéro à chaque tour !
total ← total + 1
Afficher "Total = " + total
FinTantQue
Fin
À chaque tour, total est remis à 0, puis passe à 1. La condition total < 10 reste donc toujours vraie. Cet exemple est bien illustré dans la section "Conseils pour les boucles While" du premier PDF que nous avons consulté ([PDF] Corrigé Cours Python..., ressource LINK).
3. Comment Détecter et Corriger une Boucle Infinie ?
Puisque vous êtes novice et que vous travaillez en pseudo-code, votre principal outil de détection est le traçage manuel. Cependant, il est bon de connaître les signes et les techniques utilisées en pratique.
Signes d'une boucle infinie :
- Le programme ne se termine pas.
- La même sortie s'affiche en boucle, ou bien il n'y a plus aucune sortie du tout.
- Dans un environnement réel, l'ordinateur peut ralentir ou son ventilateur s'accélérer (signe d'une utilisation intensive du processeur).
Stratégies de correction et de prévention :
-
Traçage manuel : C'est votre meilleur allié. Prenez une feuille et un crayon, et suivez l'exécution de votre boucle pas à pas, en notant la valeur des variables à chaque tour. Vous repérerez très vite si la variable de condition n'évolue pas comme prévu.
-
Affichages de débogage : Ajoutez des instructions
Affichertemporaires à l'intérieur de votre boucle pour "voir" l'évolution des variables clés.Tant que compteur < 10 Faire // Affichage de débogage pour surveiller la variable Afficher "[DEBUG] Valeur du compteur avant traitement : " + compteur // ... instructions de la boucle ... compteur ← compteur + 1 FinTantQue -
Analyse critique de la boucle : Avant même de tester, posez-vous systématiquement la question : "Quelle instruction dans ma boucle garantit qu'elle va s'arrêter un jour ?". Si vous n'avez pas de réponse claire, il y a probablement un problème.
-
Prévention : utiliser un compteur de sécurité : C'est une excellente pratique de "programmation défensive". Si une boucle ne devrait logiquement jamais dépasser, disons, 1000 tours, vous pouvez ajouter une seconde condition pour forcer sa sortie et éviter qu'elle ne bloque tout le programme.
securite ← 0 Tant que (condition_principale) ET (securite < 1000) Faire // ... instructions ... securite ← securite + 1 FinTantQue Si securite >= 1000 Alors Afficher "Erreur : La boucle a été arrêtée par sécurité." FinSi
4. Mise en Pratique
Votre tour ! Analysons l'algorithme suivant. Il est censé compter le nombre de divisions par 2 qu'on peut faire sur un nombre avant qu'il ne devienne inférieur ou égal à 1. Cependant, il contient une boucle infinie.
Exercice : Identifiez la cause de la boucle infinie et proposez une correction.
Algorithme DiviseurInfini
Variables
nombre : Réel
nb_divisions : Entier
Début
nombre ← 100
nb_divisions ← 0
Tant que nombre > 1 Faire
Afficher "Nombre actuel : " + nombre
nombre / 2 // Erreur subtile ici !
nb_divisions ← nb_divisions + 1
FinTantQue
Afficher "Nombre de divisions effectuées : " + nb_divisions
Fin
Prenez un moment pour tracer l'exécution. Que se passe-t-il avec la variable nombre ?
Cliquez ici pour voir l'analyse et la solution
Analyse de l'erreur :
L'instruction nombre / 2 calcule bien la division de nombre par 2, mais le résultat de cette opération n'est assigné à aucune variable. La valeur de la variable nombre elle-même ne change donc jamais. Elle reste à 100 à chaque tour de boucle. La condition nombre > 1 (c'est-à-dire 100 > 1) est donc toujours vraie.
Correction :
Il faut assigner le résultat du calcul à la variable nombre pour la mettre à jour.
Algorithme DiviseurCorrigé
Variables
nombre : Réel
nb_divisions : Entier
Début
nombre ← 100
nb_divisions ← 0
Tant que nombre > 1 Faire
Afficher "Nombre actuel : " + nombre
nombre ← nombre / 2 // Correction : on met à jour la variable
nb_divisions ← nb_divisions + 1
FinTantQue
Afficher "Le résultat final est " + nombre
Afficher "Nombre de divisions effectuées : " + nb_divisions
Fin
Conclusion
Félicitations ! Vous savez maintenant reconnaître l'un des bugs les plus courants et les plus déroutants pour les débutants. Cette compétence est essentielle pour construire des algorithmes fiables.
Points clés à retenir :
- Une boucle infinie inattendue est un bug où la condition de sortie d'une boucle n'est jamais atteinte.
- La cause principale est que la variable de condition n'est pas modifiée ou est modifiée d'une manière qui ne mène jamais à la sortie.
- Les erreurs courantes incluent l'oubli d'incrémentation, une logique de condition erronée ou la réinitialisation d'une variable dans la boucle.
- Votre meilleur outil pour détecter ces erreurs est le traçage manuel, complété par des affichages de débogage.
- Adoptez une approche préventive en vous demandant toujours : "Qu'est-ce qui fera arrêter ma boucle ?"
Et après ?
Nous avons maintenant terminé notre exploration approfondie des structures de contrôle (conditions et boucles). Vous avez les outils logiques pour dicter le flux d'exécution de vos algorithmes.
Dans la prochaine leçon, nous allons aborder un nouveau pilier de l'algorithmique : les structures de données. Nous commencerons par la plus fondamentale : le tableau. Vous apprendrez à déclarer une variable capable de stocker non pas une, mais toute une collection de valeurs, et à y accéder. C'est la porte d'entrée vers la résolution de problèmes beaucoup plus complexes.