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

Ejecuta condicionalmente una sentencia repetidamente, donde la sentencia no necesita gestionar la condición del bucle.

Contenidos

Sintaxis

attr  (opcional) for ( init-statement condition  (opcional) ; expression  (opcional) ) statement
attr - (desde C++11) cualquier número de atributos
init-statement - uno de
(desde C++23)

Nótese que cualquier init-statement debe terminar con un punto y coma. Por esto se describe informalmente como una expresión o una declaración seguida de un punto y coma.

condition - una condición
expression - una expresión (típicamente una expresión que incrementa el contador del bucle)
statement - una sentencia (típicamente una sentencia compuesta)

Condición

Una condición puede ser una expresión o una declaración simple .

  • Si puede resolverse sintácticamente como una declaración de structured binding , se interpreta como una declaración de structured binding.
(since C++26)
  • Si puede resolverse sintácticamente como una expresión, se trata como una expresión. De lo contrario, se trata como una declaración que no es una declaración de enlace estructurado (since C++26) .

Cuando el control alcanza la condición, la condición producirá un valor, que se utiliza para determinar si statement será ejecutado.

Expresión

Si condition es una expresión, el valor que produce es el valor de la expresión convertido contextualmente a bool . Si esa conversión es incorrecta, el programa está mal formado.

Declaración

Si condition es una declaración simple, el valor que produce es el valor de la variable de decisión (ver abajo) convertido contextualmente a bool . Si esa conversión está mal formada, el programa está mal formado.

Declaración de enlace no estructurado

La declaración tiene las siguientes restricciones:

  • Se ajusta sintácticamente a la siguiente forma:
  • type-specifier-seq declarator = assignment-expression
(hasta C++11)
  • attribute-specifier-seq (opcional) decl-specifier-seq declarator brace-or-equal-initializer
(desde C++11)

La variable de decisión de la declaración es la variable declarada.

Declaración de enlace estructurado

La declaración tiene las siguientes restricciones:

La variable de decisión de la declaración es la variable inventada e introducida por la declaración .

(desde C++26)

Explicación

Una for declaración equivalente a:

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

}

Excepto que

  • El ámbito de init-statement y el ámbito de condition son el mismo.
  • El ámbito de statement y el ámbito de expression son disjuntos y están anidados dentro del ámbito de init-statement y condition .
  • Ejecutar una continue statement en statement evaluará expression .
  • Una condition vacía es equivalente a true .

Si el bucle necesita ser terminado dentro de statement , una break statement puede ser usada como sentencia de terminación.

Si la iteración actual necesita ser terminada dentro de statement , se puede usar una continue statement como atajo.

Notas

Como es el caso con el while loop, si la statement no es una compound statement, el alcance de las variables declaradas en ella está limitado al cuerpo del loop como si fuera una compound statement.

for (;;)
    int n;
// n sale del ámbito

Como parte de la garantía de progreso de C++, el comportamiento es undefined si un bucle que no es un trivial infinite loop (since C++26) sin observable behavior no termina. Los compiladores pueden eliminar dichos bucles.

Mientras que en C los nombres declarados en el ámbito de init-statement y condition pueden ser ocultados en el ámbito de statement , esto está prohibido en C++:

for (int i = 0;;)
{
    long i = 1;   // C válido, C++ inválido
    // ...
}

Palabras clave

for

Ejemplo

#include <iostream>
#include <vector>
int main()
{
    std::cout << "1) bucle típico con una sola sentencia como cuerpo:\n";
    for (int i = 0; i < 10; ++i)
        std::cout << i << ' ';
    std::cout << "\n\n" "2) la init-statement puede declarar múltiples nombres,\n"
                 "siempre que puedan usar la misma decl-specifier-seq:\n";
    for (int i = 0, *p = &i; i < 9; i += 2)
        std::cout << i << ':' << *p << ' ';
    std::cout << "\n\n" "3) la condición puede ser una declaración:\n";
    char cstr[] = "Hello";
    for (int n = 0; char c = cstr[n]; ++n)
        std::cout << c;
    std::cout << "\n\n" "4) init-statement puede usar el especificador de tipo 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) init-statement puede ser una expresión:\n";
    int n = 0;
    for (std::cout << "Inicio del bucle\n";
         std::cout << "Prueba del bucle\n";
         std::cout << "Iteración " << ++n << '\n')
    {
        if (n > 1)
            break;
    }
    std::cout << "\n" "6) los constructores y destructores de objetos creados\n"
                 "en el cuerpo del bucle se llaman por cada iteración:\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) init-statement puede usar structured bindings:\n";
    long arr[]{1, 3, 7};
    for (auto [i, j, k] = arr; i + j < k; ++i)
        std::cout << i + j << ' ';
    std::cout << '\n';
}

Salida:

1) bucle típico con una sola sentencia como cuerpo:
0 1 2 3 4 5 6 7 8 9
2) la init-statement puede declarar múltiples nombres,
siempre que puedan usar la misma decl-specifier-seq:
0:0 2:2 4:4 6:6 8:8
3) la condición puede ser una declaración:
Hello
4) init-statement puede usar el especificador de tipo auto:
3 1 4 1 5 9
5) init-statement puede ser una expresión:
Inicio del bucle
Prueba del bucle
Iteración 1
Prueba del bucle
Iteración 2
Prueba del bucle
6) los constructores y destructores de objetos creados
en el cuerpo del bucle se llaman por cada iteración:
S::S(0, 5); S::~S()
S::S(1, 4); S::~S()
S::S(2, 3); S::~S()
7) init-statement puede usar structured bindings:
4 5 6

Véase también

bucle for de rango (C++11) ejecuta bucle sobre rango