for
迴圈
來自 cppreference.com
有條件地重複執行語句,該語句無需管理迴圈條件。
目錄 |
[編輯] 語法
attr (可選) for ( init-statement condition (可選) ; expression (可選) ) statement |
|||||||||
屬性 | - | (自 C++11 起) 任意數量的屬性 | ||
init-statement | - | 以下之一
注意,任何 init-statement 都必須以分號結尾。這就是為什麼它通常被非正式地描述為表示式或聲明後跟分號的原因。 | ||
條件 | - | 一個條件 | ||
表示式 | - | 一個表示式(通常是遞增迴圈計數器的表示式) | ||
語句 | - | 一個語句(通常是複合語句) |
[編輯] 條件
|
(C++26 起) |
- 如果它可以被語法解析為表示式,則將其視為表示式。否則,將其視為宣告,而不是結構化繫結宣告(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內終止當前迭代,可以使用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
|