Espacios de nombres
Variantes
Acciones

Bucle for

De cppreference.com
< cpp‎ | language

Ejecuta una vez instrucción-de-iniciación, luego ejecuta repetidamente instrucción y expresión-de-iteración, hasta que el valor de la condición se hace falso. La comprobación se hace antes de cada iteración.

Contenido

[editar] Sintaxis

    sintaxis formal:
atrib(opcional) for ( instrucción-de-inicialización condición(opcional) ; expresión-de-iteración(opcional) ) instrucción
    sintaxis informal:
atrib(opcional) for ( declaración-o-expresión(opcional) ; declaración-o-expresión(opcional) ; expresión(opcional) ) instrucción
atrib - (desde C++11) cualquier número de atributos
instrucción-de-inicialización - uno de los siguientes
(desde C++23)
Tenga en cuenta que cualquier instrucción-de-inicialización debe terminar con un punto y coma ;, que es por lo que a veces se describe informalmente como una expresión o declaración seguida de un punto y coma.
condición - cualquiera de
  • una expresión que es contextualmente convertible a bool. Esta expresión se evalúa antes de cada iteración, y si da valor false, se sale del bucle.
  • una declaración de una sola variable con un inicializador de llaves o igual. El inicializador se evalúa antes de cada iteración, y si el valor de la variable declarada se convierte en false, se sale del bucle.
expresión-de-iteración - cualquier expresión, que se ejecuta después de cada iteración del bucle y antes de volver a evaluar la condición. Normalmente, esta es la expresión que incrementa el contador del bucle
instrucción - cualquier instrucción, una instrucción compuesta normalmente, que es el cuerpo del bucle

[editar] Explicación

La sintaxis anterior produce un código equivalente a:

{
instrucción-de-inicialización
while ( condición ) {
instrucción
expresión-de-iteración ;
}

}

Excepto que

1) Los nombres declarados por la instrucción-de-inicialización (si instrucción-de-inicialización es una declaración) y los nombres declarados por la condición (si la condición es una declaración) están en el mismo ámbito (que también es el ámbito de instrucción).
2) continue en la instrucción ejecutará expresión-de-iteración
3) Una condición vacía es equivalente a while(true)

Si se necesita terminar la ejecución del bucle en un punto, se puede usar la instrucción break como instrucción de terminación.

Si se necesita continuar la ejecución del bucle al final del cuerpo del bucle, se puede usar la instrucción continue como cortocircuito.

Como en el caso del bucle while, si instrucción es una sola instrucción (no es compuesta), el ámbito de la variables declaradas en ella está limitado por el cuerpo del bucle como si fuera una instrucción compuesta.

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

[editar] Palabras clave

for

[editar] Notas

Como parte de la garantía de progreso de avance de C++, el comportamiento no está definido si un bucle que no tiene comportamiento observable (no realiza llamadas a funciones de E/S, no accede a objetos volátiles ni realiza operaciones atómicas o de sincronización) no termina. Los compiladores pueden eliminar dichos bucles.

Mientras que en C++, el ámbito de la instrucción-de-inicialización y de la instrucción son el mismo, en C el ámbito de instrucción esta anidado dentro del ámbito de instrucción-de-incialización:

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

[editar] Ejemplo

#include <iostream>
#include <vector>
 
int main()
{
    std::cout << "1) bucle típico con una sola instrucción en el cuerpo:\n";
    for (int i = 0; i < 10; ++i)
        std::cout << i << ' ';
 
    std::cout << "\n\n" "2) instrucción-de-inicialización puede declarar varios nombres, "
                 "siempre que puedan usar la misma secuencia-especificadores-de-declaración:\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[] = "Hola";
    for (int n = 0; char c = cstr[n]; ++n)
        std::cout << c;
 
    std::cout << "\n\n" "4) instrucción-de-inicialización 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) instrucción-de-inicialización puede ser una expresión:\n";
    int n = 0;
    for (std::cout << "Comienza bucle\n";
         std::cout << "Comprobación de bucle\n";
         std::cout << "Iteración " << ++n << '\n')
        if(n > 1)
            break;
 
    std::cout << "\n" "6) los constructores y destructores de los objetos creados "
                 "en el cuerpo del bucle se llaman en 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};
}

Salida:

1) bucle típico con una sola instrucción en el cuerpo::
0 1 2 3 4 5 6 7 8 9 
 
2) instrucción-de-inicialización puede declarar varios nombres, siempre que puedan usar la misma secuencia-especificadores-de-declaración:
0:0 2:2 4:4 6:6 8:8 
 
3) la condición puede ser una declaración::
Hola
 
4) instrucción-de-inicialización puede usar el especificador de tipo auto:
3 1 4 1 5 9 
 
5) instrucción-de-inicialización puede ser una expresión::
Comienza bucle
Comprobación de bucle
Iteración 1
Comprobación de bucle
Iteración 2
Comprobación de bucle
 
6) los constructores y destructores de los objetos creados en el cuerpo del bucle se llaman en cada iteración:
S::S(0, 5); S::~S()
S::S(1, 4); S::~S()
S::S(2, 3); S::~S()

[editar] Véase también

Bucle for basado en rango Ejecuta un bucle sobre un rango (desde C++11) [editar]