命名空间
变体
操作

for 循环

来自 cppreference.cn
< cpp‎ | 语言
 
 
C++ 语言
 
 

有条件地重复执行语句,该语句无需管理循环条件。

目录

[编辑] 语法

attr (可选) for ( init-statement condition (可选) ; expression (可选) ) statement
属性 - (自 C++11 起) 任意数量的属性
init-statement - 以下之一
(C++23 起)

注意,任何 init-statement 都必须以分号结尾。这就是为什么它通常被非正式地描述为表达式或声明后跟分号的原因。

条件 - 一个条件
表达式 - 一个表达式(通常是递增循环计数器的表达式)
语句 - 一个语句(通常是复合语句)

[编辑] 条件

condition 可以是一个表达式或一个简单声明

  • 如果它在语法上可以解析为结构化绑定声明,则将其解释为结构化绑定声明。
(C++26 起)
  • 如果它可以被语法解析为表达式,则将其视为表达式。否则,将其视为声明,而不是结构化绑定声明(C++26 起)

当控制到达条件时,条件将产生一个值,该值用于确定是否执行statement

[编辑] 表达式

如果condition是一个表达式,它产生的值是表达式的值,并按上下文转换为bool。如果该转换格式错误,则程序格式错误。

[编辑] 声明

如果condition是一个简单声明,它产生的值是决策变量(见下文)的值,并按上下文转换为bool。如果该转换格式错误,则程序格式错误。

[编辑] 非结构化绑定声明

该声明有以下限制:

  • 语法上符合以下形式:
  • type-specifier-seq declarator = assignment-expression
(C++11 前)
  • attribute-specifier-seq(可选) decl-specifier-seq declarator brace-or-equal-initializer
(C++11 起)

声明的决策变量是被声明的变量。

结构化绑定声明

该声明有以下限制:

声明的决策变量是声明引入的虚构变量e

(C++26 起)

[编辑] 解释

一个for语句等同于

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

}

除了

  • init-statement 的作用域和condition 的作用域相同。
  • statement 的作用域和expression 的作用域是分离的,并嵌套在init-statementcondition 的作用域内。
  • statement 中执行continue 语句将评估expression
  • 空的condition等同于true

如果需要在statement内终止循环,可以使用break 语句作为终止语句。

如果需要在statement内终止当前迭代,可以使用continue 语句作为快捷方式。

[编辑] 注意

while循环一样,如果statement不是复合语句,则其中声明的变量的作用域仅限于循环体,如同它是复合语句一样。

for (;;)
    int n;
// n goes out of scope

作为 C++ 前向进度保证的一部分,如果一个循环不是平凡无限循环(C++26 起)没有可观察行为但未终止,则行为是未定义的。编译器被允许移除此类循环。

虽然在 C 语言中,在init-statementcondition的作用域中声明的名称可以在statement的作用域中被隐藏,但在 C++ 中这是禁止的。

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

[编辑] 关键字

for

[编辑] 示例

#include <iostream>
#include <vector>
 
int main()
{
    std::cout << "1) typical loop with a single statement as the body:\n";
    for (int i = 0; i < 10; ++i)
        std::cout << i << ' ';
 
    std::cout << "\n\n" "2) init-statement can declare multiple names, as\n"
                 "long as they can use the same decl-specifier-seq:\n";
    for (int i = 0, *p = &i; i < 9; i += 2)
        std::cout << i << ':' << *p << ' ';
 
    std::cout << "\n\n" "3) condition may be a declaration:\n";
    char cstr[] = "Hello";
    for (int n = 0; char c = cstr[n]; ++n)
        std::cout << c;
 
    std::cout << "\n\n" "4) init-statement can use the auto type specifier:\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 can be an expression:\n";
    int n = 0;
    for (std::cout << "Loop start\n";
         std::cout << "Loop test\n";
         std::cout << "Iteration " << ++n << '\n')
    {
        if (n > 1)
            break;
    }
 
    std::cout << "\n" "6) constructors and destructors of objects created\n"
                 "in the loop's body are called per each iteration:\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 can use 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';
}

输出

1) typical loop with a single statement as the body:
0 1 2 3 4 5 6 7 8 9
 
2) init-statement can declare multiple names, as
long as they can use the same decl-specifier-seq:
0:0 2:2 4:4 6:6 8:8
 
3) condition may be a declaration:
Hello
 
4) init-statement can use the auto type specifier:
3 1 4 1 5 9
 
5) init-statement can be an expression:
Loop start
Loop test
Iteration 1
Loop test
Iteration 2
Loop test
 
6) constructors and destructors of objects created
in the loop's body are called per each iteration:
S::S(0, 5); S::~S()
S::S(1, 4); S::~S()
S::S(2, 3); S::~S()
 
7) init-statement can use structured bindings:
4 5 6

[编辑] 另请参阅

range-for 循环(C++11) 对范围执行循环[编辑]
C 文档 for for