Namespaces
Variants

for loop

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
for
range- for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Exécute conditionnellement une instruction de manière répétée, où l'instruction n'a pas besoin de gérer la condition de boucle.

Table des matières

Syntaxe

attr  (optionnel) for ( init-statement condition  (optionnel) ; expression  (optionnel) ) statement
attr - (depuis C++11) n'importe quel nombre d' attributs
init-statement - l'un des éléments suivants
(depuis C++23)

Notez que toute init-statement doit se terminer par un point-virgule. C'est pourquoi elle est souvent décrite informellement comme une expression ou une déclaration suivie d'un point-virgule.

condition - une condition
expression - une expression (généralement une expression qui incrémente le compteur de boucle)
statement - une instruction (généralement une instruction composée)

Condition

Une condition peut être soit une expression soit une déclaration simple .

(depuis C++26)
  • S'il peut être syntaxiquement résolu comme une expression, il est traité comme une expression. Sinon, il est traité comme une déclaration qui n'est pas une déclaration de décomposition structurée (depuis C++26) .

Lorsque le contrôle atteint la condition, celle-ci produira une valeur, qui est utilisée pour déterminer si statement sera exécuté.

Expression

Si condition est une expression, la valeur qu'elle produit est la valeur de l'expression convertie contextuellement en bool . Si cette conversion est mal formée, le programme est mal formé.

Déclaration

Si condition est une déclaration simple, la valeur qu'elle produit est la valeur de la variable de décision (voir ci-dessous) convertie contextuellement en bool . Si cette conversion est mal formée, le programme est mal formé.

Déclaration non structurée de liaison

La déclaration comporte les restrictions suivantes :

  • Conforme syntaxiquement à la forme suivante :
  • type-specifier-seq declarator = assignment-expression
(jusqu'en C++11)
  • attribute-specifier-seq (optionnel) decl-specifier-seq declarator brace-or-equal-initializer
(depuis C++11)

La variable de décision de la déclaration est la variable déclarée.

Déclaration de liaison structurée

La déclaration présente les restrictions suivantes :

  • L' expression dans son initialiseur ne peut pas être de type tableau.
  • La séquence de spécificateurs de déclaration ne peut contenir que des spécificateurs de type et constexpr .

La variable de décision de la déclaration est la variable inventée e introduite par la déclaration .

(depuis C++26)

Explication

Une for instruction équivalente à :

{
instruction-init
while ( condition )
{
instruction
expression ;
}

}

Sauf que

  • La portée de init-statement et la portée de condition sont identiques.
  • La portée de statement et la portée de expression sont disjointes et imbriquées dans la portée de init-statement et condition .
  • L'exécution d'une continue statement dans statement évaluera expression .
  • Une condition vide est équivalente à true .

Si la boucle doit être interrompue au sein de statement , une break statement peut être utilisée comme instruction de terminaison.

Si l'itération actuelle doit être terminée au sein de statement , une continue statement peut être utilisée comme raccourci.

Notes

Comme c'est le cas avec la boucle while , si la instruction n'est pas une instruction composée, la portée des variables déclarées dans celle-ci est limitée au corps de la boucle comme s'il s'agissait d'une instruction composée.

for (;;)
    int n;
// n sort du scope

Dans le cadre de la garantie de progression du C++, le comportement est indéfini si une boucle qui n'est pas une boucle infinie triviale (depuis C++26) sans comportement observable ne se termine pas. Les compilateurs sont autorisés à supprimer de telles boucles.

Alors qu'en C, les noms déclarés dans la portée de init-statement et condition peuvent être masqués dans la portée de statement , cela est interdit en C++ :

for (int i = 0;;)
{
    long i = 1;   // C valide, C++ invalide
    // ...
}

Mots-clés

for

Exemple

#include <iostream>
#include <vector>
int main()
{
    std::cout << "1) Boucle typique avec une seule instruction comme corps :\n";
    for (int i = 0; i < 10; ++i)
        std::cout << i << ' ';
    std::cout << "\n\n" "2) L'instruction d'initialisation peut déclarer plusieurs noms,\n"
                 "tant qu'ils peuvent utiliser la même séquence de spécificateurs de déclaration :\n";
    for (int i = 0, *p = &i; i < 9; i += 2)
        std::cout << i << ':' << *p << ' ';
    std::cout << "\n\n" "3) La condition peut être une déclaration :\n";
    char cstr[] = "Hello";
    for (int n = 0; char c = cstr[n]; ++n)
        std::cout << c;
    std::cout << "\n\n" "4) L'instruction d'initialisation peut utiliser le spécificateur de type auto :\n";
    std::vector<int> v = {3, 1, 4, 1, 5, 9};
    for (auto iter = v.begin(); iter != v.end(); ++iter)
        std::cout << *iter << ' ';
    std::cout << "\n\n" "5) L'instruction d'initialisation peut être une expression :\n";
    int n = 0;
    for (std::cout << "Début de la boucle\n";
         std::cout << "Test de boucle\n";
         std::cout << "Itération " << ++n << '\n')
    {
        if (n > 1)
            break;
    }
    std::cout << "\n" "6) Les constructeurs et destructeurs des objets créés\n"
                 "dans le corps de la boucle sont appelés à chaque itération :\n";
    struct S
    {
        S(int x, int y) { std::cout << "S::S(" << x << ", " << y << "); "; }
        ~S() { std::cout << "S::~S()\n"; }
    };
    for (int i{0}, j{5}; i < j; ++i, --j)
        S s{i, j};
    std::cout << "\n" "7) L'instruction d'initialisation peut utiliser des liaisons structurées :\n";
    long arr[]{1, 3, 7};
    for (auto [i, j, k] = arr; i + j < k; ++i)
        std::cout << i + j << ' ';
    std::cout << '\n';
}

Sortie :

1) Boucle typique avec une seule instruction comme corps :
0 1 2 3 4 5 6 7 8 9
2) L'instruction d'initialisation peut déclarer plusieurs noms,
tant qu'ils peuvent utiliser la même séquence de spécificateurs de déclaration :
0:0 2:2 4:4 6:6 8:8
3) La condition peut être une déclaration :
Hello
4) L'instruction d'initialisation peut utiliser le spécificateur de type auto :
3 1 4 1 5 9
5) L'instruction d'initialisation peut être une expression :
Début de la boucle
Test de boucle
Itération 1
Test de boucle
Itération 2
Test de boucle
6) Les constructeurs et destructeurs des objets créés
dans le corps de la boucle sont appelés à chaque itération :
S::S(0, 5); S::~S()
S::S(1, 4); S::~S()
S::S(2, 3); S::~S()
7) L'instruction d'initialisation peut utiliser des liaisons structurées :
4 5 6

Voir aussi

boucle for sur plage (C++11) exécute une boucle sur une plage