for
loop
有条件地重复执行一条语句,其中该语句无需管理循环条件。
目录 |
语法
attr
(可选)
for (
init-statement
condition
(可选)
;
expression
(可选)
)
statement
|
|||||||||
| attr | - | (since C++11) 任意数量的 属性 | ||
| init-statement | - |
以下之一
注意:任何 init-statement 必须以分号结尾。因此常被非正式地描述为表达式或声明后接分号。 |
||
| condition | - | 一个 条件表达式 | ||
| expression | - | 一个 表达式 (通常为递增循环计数器的表达式) | ||
| statement | - | 一条 语句 (通常为复合语句) |
条件表达式
|
(since C++26) |
- 如果它能被语法解析为表达式,则被视为表达式。否则,它被视为声明 (非结构化绑定声明) (since C++26) 。
当控制流到达条件语句时,该条件将产生一个值,该值用于判断是否执行 statement 。
表达式
如果 condition 是一个表达式,其产生的值即为该表达式在上下文语境中转换为 bool 类型后的值。若该转换不合法,则程序亦为不合法。
声明
如果 condition 是一个简单声明,其产生的值是由决策变量(见下文)经上下文转换到 bool 类型的值。若该转换格式错误,则程序格式错误。
非结构化绑定声明
该声明具有以下限制:
- 语法上符合以下形式:
|
(C++11 前) |
|
(C++11 起) |
声明的决策变量即为所声明的变量。
结构化绑定声明该声明具有以下限制: 该声明的决策变量是由 声明引入的 虚构变量 e 。 |
(自 C++26 起) |
说明
一个 for 语句等价于:
{
|
|||||||||
除此之外
- init-statement 的作用域与 condition 的作用域相同。
- statement 的作用域与 expression 的作用域互不相交,且嵌套在 init-statement 和 condition 的作用域内。
- 在 statement 中执行 continue 语句 将会对 expression 进行求值。
- 空的 condition 等价于 true 。
如果循环需要在 statement 内部终止,可以使用 break statement 作为终止语句。
若需要在 statement 中终止当前迭代,可使用 continue 语句 作为快捷方式。
注释
与
while
循环的情况相同,如果
语句
不是复合语句,则其中声明的变量作用域将限定于循环体,如同它是复合语句一般。
for (;;) int n; // n 超出作用域
作为 C++ 向前进度保证 的一部分,如果循环 (非 平凡无限循环 (C++26 起) )没有 可观察行为 且不会终止,则其行为是 未定义 的。编译器有权移除此类循环。
虽然在 C 语言中,声明在 init-statement 和 condition 作用域内的名称可以在 statement 作用域内被遮蔽,但在 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"; for (int i = 0, *p = &i; i < 9; i += 2) std::cout << i << ':' << *p << ' '; std::cout << "\n\n" "3) 条件可以是声明:\n"; char cstr[] = "Hello"; for (int n = 0; char c = cstr[n]; ++n) std::cout << c; std::cout << "\n\n" "4) 初始化语句可使用 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) 初始化语句可以是表达式:\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}; std::cout << "\n" "7) 初始化语句可使用结构化绑定:\n"; long arr[]{1, 3, 7}; for (auto [i, j, k] = arr; i + j < k; ++i) std::cout << i + j << ' '; std::cout << '\n'; }
输出:
1) 以单条语句作为循环体的典型循环: 0 1 2 3 4 5 6 7 8 9 2) 初始化语句可声明多个名称, 只要它们能使用相同的声明说明符序列: 0:0 2:2 4:4 6:6 8:8 3) 条件可以是声明: Hello 4) 初始化语句可使用 auto 类型说明符: 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() 7) 初始化语句可使用结构化绑定: 4 5 6
参见
范围
for
循环
(C++11)
|
在范围上执行循环 |
|
C 文档
关于
for
|
|