for
循环
来自 cppreference.com
重复执行语句,其中语句不需要管理循环条件。
内容 |
[编辑] 语法
attr (可选) for ( init-statement condition (可选) ; expression (可选) ) statement |
|||||||||
attr | - | (自 C++11 起) 任意数量的 属性 | ||
init-statement | - | 以下之一
请注意,任何 init-statement 都必须以分号结尾。这就是为什么它通常被非正式地描述为表达式或声明后跟一个分号的原因。 | ||
condition | - | 条件 | ||
表达式 | - | 表达式(通常是递增循环计数器的表达式) | ||
statement | - | 语句(通常是复合语句) |
[编辑] 条件
|
(自 C++26 起) |
- 如果它可以在语法上解析为表达式或声明 而不是结构化绑定声明(自 C++26 起),则它将被解释为后者。
当控制到达 condition 时,condition 将产生一个值,该值用于确定是否执行 statement。
[编辑] 表达式
如果 condition 是一个表达式,则它产生的值是表达式上下文转换为 bool 后的值。如果该转换是非法的,则程序是非法的。
[编辑] 声明
如果 condition 是一个简单的声明,它产生的值就是决策变量的值(见下文),在上下文中转换为 bool。如果该转换是非法的,程序就是非法的。
[编辑] 非结构化绑定声明
该声明有以下限制
- 它只有一个 声明符。
- 声明符不能指定 函数 或 数组。
- 声明符必须有一个 初始化器,它不能是 (3) 语法。
- 该 声明说明符序列 只能包含类型说明符 和 constexpr(自 C++11 起),并且不能定义 类 或 枚举。
该声明的决策变量是声明的变量。
结构化绑定声明该声明有以下限制 该声明的决策变量是声明引入的 虚构变量 e。 |
(自 C++26 起) |
[编辑] 说明
等效于以下 for 语句
{
|
|||||||||
除了
- init-statement 的作用域和 condition 的作用域相同。
- statement 的作用域和 expression 的作用域是不相交的,并且嵌套在 init-statement 和 condition 的作用域内。
- 在 statement 中执行 continue 语句 将会计算 expression。
- 空的 condition 等同于 true。
如果需要在 statement 中终止循环,可以使用 break 语句 作为终止语句。
如果需要在 statement 中终止当前迭代,可以使用 continue 语句 作为快捷方式。
[编辑] 注释
与 while
循环一样,如果 statement 不是复合语句,则在其中声明的变量的作用域仅限于循环体,就像它是一个复合语句一样。
for (;;) int n; // n goes out of scope
作为 C++ 前进保证 的一部分,如果一个循环 不是一个 平凡无限循环(自 C++26 起) 且没有 可观察到的行为 ,则其行为是 未定义的。编译器可以移除此类循环。
在 C 中,在 init-statement 和 condition 的作用域中声明的名称可以在 statement 的作用域中被遮蔽,但在 C++ 中这是禁止的。
for (int i = 0;;) { long i = 1; // valid C, invalid C++ // ... }
[编辑] 关键字
[编辑] 示例
运行这段代码
#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
|