Menu

Boucle for en C++ : syntaxe, exemples et erreurs courantes

Comment répéter du code avec la boucle for de C++ : l'en-tête en trois parties, compter vers le haut et vers le bas, parcourir des tableaux, imbriquer, break et continue, ainsi que les bugs de décalage d'un et de types non signés qui piègent tout le monde.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Pourquoi une boucle for

Un switch choisit une branche à exécuter une seule fois. Mais les vrais programmes ont besoin de faire quelque chose de façon répétée : afficher chaque score, additionner une liste de nombres, dessiner 10 lignes d'une grille. La boucle for est le cheval de bataille de C++ pour répéter du code un nombre de fois connu, avec un compteur intégré que vous contrôlez.

Tout ce dont une boucle for a besoin tient dans un en-tête compact, de sorte que toute l'histoire du « combien de fois et comment » est visible d'un coup d'œil.

L'en-tête en trois parties

L'en-tête d'une boucle for comporte trois parties séparées par des points-virgules : un initialiseur, une condition et une mise à jour.

for (initializer; condition; update) {
    // corps - s'exécute tant que la condition est vraie
}

Elles s'exécutent dans un ordre précis : l'initialiseur s'exécute une fois au début ; puis la condition est vérifiée avant chaque itération ; le corps ne s'exécute que si la condition est true ; et la mise à jour s'exécute à la fin de chaque itération, juste avant que la condition ne soit revérifiée.

Ici int i = 0 s'exécute une fois. Ensuite i < 5 est vérifié : tant que c'est vrai, le corps affiche et i++ incrémente le compteur. Quand i atteint 5, la condition est false, donc la boucle se termine et done s'affiche. Le corps s'exécute exactement 5 fois, avec i prenant les valeurs 0 à 4.

Déclarer le compteur dans l'en-tête (int i = 0) limite la portée de i à la boucle - il n'existe plus après l'accolade fermante, ce qui est exactement ce que vous voulez.

Compter vers le haut, vers le bas et par pas

La partie mise à jour ne se limite pas à i++. Vous pouvez compter à rebours, avancer de n'importe quel pas ou parcourir l'indice d'un tableau.

La première boucle s'exécute tant que i > 0, en décrémentant à chaque fois, donc elle affiche 5 4 3 2 1. La seconde ajoute 2 à chaque passage et utilise <= 10 car 10 est une valeur que nous voulons inclure. Accordez votre condition à votre mise à jour : compter à rebours va avec > ou >=, compter vers le haut avec < ou <=.

Parcourir un tableau

L'usage le plus courant d'une boucle de comptage est de parcourir un tableau par indice. Le compteur sert aussi de position que vous lisez.

Notez que la condition est i < n, et non i <= n. Un tableau de 5 éléments a des indices valides de 0 à 4 ; l'indice 5 est au-delà de la fin. Lire scores[5] est un comportement indéfini - cela peut afficher n'importe quoi, planter, ou sembler fonctionner tout en corrompant silencieusement la mémoire. Le modèle i < n est la valeur par défaut sûre pour tout tableau indexé à partir de zéro.

Si vous n'avez besoin que des valeurs et pas de l'indice, un for basé sur un intervalle est plus propre. Recourez à la boucle indexée classique lorsque vous avez réellement besoin de la position.

break et continue

Deux mots-clés vous permettent de modifier le flux en plein milieu de la boucle. break quitte la boucle immédiatement ; continue saute le reste de l'itération courante et passe à la mise à jour.

La première boucle s'arrête au moment où elle trouve 7 et ne vérifie jamais le reste. La seconde utilise continue pour sauter l'affichage du corps chaque fois que i est pair - la mise à jour i++ s'exécute quand même, donc la boucle continue d'avancer. Un piège subtil : continue passe à la mise à jour, donc si vous comptez un jour sur continue dans une boucle dont le compteur est mis à jour dans le corps plutôt que dans l'en-tête, vous pouvez accidentellement sauter cette mise à jour et tourner indéfiniment.

Boucles imbriquées

Placez un for à l'intérieur d'un autre pour travailler avec des grilles, des tableaux ou des paires. La boucle interne s'exécute entièrement à chaque pas unique de la boucle externe.

Ceci affiche une grille de multiplication 3x3. La boucle externe fixe une row, la boucle interne balaie chaque col de cette ligne, puis un saut de ligne termine la ligne. Donnez des noms distincts aux compteurs (row/col, pas i/i) - réutiliser un nom masque celui de l'extérieur et produit des bugs déroutants. Surveillez aussi le coût : imbriquer une boucle de n dans une boucle de n exécute le corps n * n fois, ce qui s'accumule vite.

Pièges courants

Quelques pièges expliquent la plupart des bugs de boucles for en C++ :

  • Décalage d'un : i <= n avec une taille indexée à partir de zéro lit un élément au-delà de la fin. Utilisez i < n.
  • Sous-dépassement non signé : compter à rebours avec un type non signé ne devient jamais négatif. for (size_t i = n - 1; i >= 0; i--) boucle indéfiniment, car i >= 0 est toujours vrai pour une valeur non signée - quand i vaut 0, i-- retombe à un nombre positif énorme. Utilisez un int signé pour les comptages descendants, ou réécrivez la condition.
  • Modifier le compteur dans le corps : changer i dans le corps en plus de l'en-tête rend le nombre d'itérations imprévisible. Choisissez un seul endroit.
// BUG: infinite loop - unsigned i is never < 0
for (size_t i = n - 1; i >= 0; i--) {
    process(arr[i]);
}

Les compteurs en virgule flottante sont un autre danger silencieux : for (double x = 0.0; x != 1.0; x += 0.1) peut ne jamais atteindre exactement 1.0 car 0.1 ne peut pas être stocké avec précision. Bouclez avec un comptage entier et calculez la valeur à l'intérieur, ou utilisez < au lieu de !=.

Suite : les boucles while

La boucle for brille lorsque vous connaissez le nombre d'itérations à l'avance. Mais parfois, vous devez répéter jusqu'à ce qu'une condition change - lire une entrée jusqu'à la fin de fichier, réessayer jusqu'à réussir - sans nombre fixe d'étapes. C'est le rôle de la boucle while, qui réduit l'en-tête à une simple condition. C'est la page suivante.

Questions fréquentes

Comment écrit-on une boucle for en C++ ?

Placez trois parties dans l'en-tête, séparées par des points-virgules : un initialiseur, une condition et une mise à jour. for (int i = 0; i < 5; i++) { cout << i; } exécute le corps avec i prenant les valeurs 0, 1, 2, 3, 4. La boucle s'arrête dès que la condition devient false.

Quelle est la différence entre une boucle for et une boucle for basée sur un intervalle en C++ ?

Un for classique vous donne un compteur d'indice que vous contrôlez (for (int i = 0; i < n; i++)), dont vous avez besoin lorsque vous voulez la position ou avancer d'une manière personnalisée. Un for basé sur un intervalle (for (int x : v)) masque l'indice et vous remet simplement chaque élément - plus propre lorsque vous n'avez besoin que des valeurs.

Pourquoi ma boucle for en C++ s'exécute-t-elle une fois de trop ou une fois de moins ?

C'est le classique bug de décalage d'un (off-by-one). Utiliser <= au lieu de < avec une taille indexée à partir de zéro exécute une itération de trop et lit au-delà de la fin du tableau ; utiliser < alors que vous vouliez inclure la dernière valeur en exécute une de moins. Pour un tableau de taille n, le modèle sûr est for (int i = 0; i < n; i++).

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER