for
loop
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
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 .
|
(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:
|
(hasta C++11) |
|
(desde C++11) |
- El declarador no puede especificar una function o un array .
- La type specifier sequence (until C++11) declaration specifier sequence solo puede contener especificadores de tipo y constexpr , y (since C++11) no puede definir una class o una enumeration .
La variable de decisión de la declaración es la variable declarada.
Declaración de enlace estructuradoLa 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:
{
|
|||||||||
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
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 |
|
Documentación de C
para
for
|
|