Пространства имён
Варианты
Действия

Цикл for

Материал из cppreference.com
< cpp‎ | language
 
 
 
Инструкции
Метки
метка : оператор
Операторы выражений
выражение ;
Составные операторы
{ оператор... }
Операторы выбора
if
switch
Операторы итерирования
while
do-while
for
диапазонный for(C++11)
Операторы переходов
break
continue
return
goto
Операторы объявления
объявление ;
Блоки try
try составной-оператор последовательность-обработчиков
Транзакционная память
synchronized, atomic_commit, и т.д. (ТС TM)
 

Выполняет оператор-инициализации, затем выполняет оператор и выражение-итерации повторно, пока значение условия не станет ложным. Проверка проводится перед каждой итерацией.

Содержание

[править] Синтаксис

    формальный синтаксис:
атрибуты (необязательно) for ( оператор-инициализации условие (необязательно) ; выражение-итерации (необязательно) ) оператор
    неформальный синтаксис:
атрибуты (необязательно) for ( объявление-или-выражение (необязательно) ; объявление-или-выражение (необязательно) ; выражение (необязательно) ) оператор
атрибуты (начиная с C++11) любое количество атрибутов
оператор-инициализации одно из следующего
(начиная с C++23)
Обратите внимание, что любой оператор-инициализации должен заканчиваться точкой с запятой ;, поэтому его часто неофициально описывают как выражение или объявление, за которым следует точка с запятой.
условие одно из
  • выражение которое контекстно преобразуется в bool. Это выражение вычисляется перед каждой итерацией, и если оно даёт false, цикл завершается.
  • объявление одной переменной с инициализатором в виде скобок или равенства. Инициализатор оценивается перед каждой итерацией, и если значение объявленной переменной преобразуется в false, цикл завершается.
выражение-итерации любое выражение, которое выполняется после каждой итерации цикла и перед переоценкой условия. Как правило, это выражение, которое увеличивает счётчик циклов
оператор любой оператор, обычно составной оператор, который является телом цикла

[править] Объяснение

Приведенный выше синтаксис создаёт код, эквивалентный следующему:

{
оператор-инициализации
while ( условие ) {
оператор
выражение-итерации ;
}

}

Кроме этого

1) Область действия ыражения-инициализации и область действия условия совпадают.
2) Область действия оператора и область действия выражения-итерации не пересекаются и вложены в область видимости оператора-инициализации и условия.
3) continue в операторе выполняет выражение-итерации
4) Пустое условие эквивалентно while(true)

Если выполнение цикла необходимо прервать в какой-то момент, в качестве завершающего оператора можно использовать оператор break.

Если выполнение цикла необходимо продолжить в конце тела цикла, как сокращение можно использовать оператор continue.

Как и в случае с циклом while, если оператор является одиночным оператором (а не составным оператором), область действия переменных, объявленных в нём, ограничена телом цикла, как если бы он был составным оператором.

for (;;)
    int n;
// n выходит из области видимости

[править] Ключевые слова

for

[править] Примечание

Как часть гарантии продвижения вперёд C++, поведение не определено, если цикл, который не имеет наблюдаемого поведения (не выполняет вызовы функций Ввода/Вывода, не обращается к volatile объектам или не выполняет атомарные операции или операции синхронизации), не завершается. Компиляторам разрешено удалять такие циклы.

В то время как в C имена, объявленные в области действия оператора-инициализации и условия, могут быть затенены в области действия оператора, в C++ это запрещено:

for (int i = 0; ; ) {
    long i = 1;   // допустимо в C, недопустимо в C++
    // ...
}

[править] Пример

#include <iostream>
#include <vector>
 
int main()
{
    std::cout << "1) типичный цикл с одним оператором в качестве тела:\n";
    for (int i = 0; i < 10; ++i)
        std::cout << i << ' ';
 
    std::cout << "\n\n" "2) оператор-инициализации может объявлять несколько имён,\n"
                 "если они могут использовать одну и ту же\n"
                 "последовательность-спецификаторов-объявления:\n";
    for (int i = 0, *p = &i; i < 9; i += 2)
        std::cout << i << ':' << *p << ' ';
 
    std::cout << "\n\n" "3) условие может быть объявлением:\n";
    char cstr[] = "Привет";
    for (int n = 0; char c = cstr[n]; ++n)
        std::cout << c;
 
    std::cout << "\n\n" "4) оператор-инициализации может использовать спецификатор\n"
                 "автоматического типа:\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) оператор-инициализации может быть выражением:\n";
    int n = 0;
    for (std::cout << "Начало цикла\n";
         std::cout << "Тест цикла\n";
         std::cout << "Итерация " << ++n << '\n')
    {
        if(n > 1)
            break;
    }
 
    std::cout << "\n" "6) конструкторы и деструкторы объектов, созданных\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};
}

Вывод:

1) типичный цикл с одним оператором в качестве тела:
0 1 2 3 4 5 6 7 8 9 
 
2) оператор-инициализации может объявлять несколько имён,
если они могут использовать одну и ту же
последовательность-спецификаторов-объявления:
0:0 2:2 4:4 6:6 8:8 
 
3) условие может быть объявлением:
Привет
 
4) оператор-инициализации может использовать спецификатор
автоматического типа:
3 1 4 1 5 9 
 
5) оператор-инициализации может быть выражением:
Начало цикла
Тест цикла
Итерация 1
Тест цикла
Итерация 2
Тест цикла
 
6) конструкторы и деструкторы объектов, созданных
в теле цикла, вызываются на каждой итерации:
S::S(0, 5); S::~S()
S::S(1, 4); S::~S()
S::S(2, 3); S::~S()

[править] Смотрите также

диапазонный цикл for(C++11) выполняет цикл по диапазону[править]