for 迴圈
出自 cppreference.com
重複地有條件執行語句,其中該語句不需要自行管理迴圈條件。
目錄 |
[編輯] 語法
attr (可選) for ( init-statement condition (可選) ; expression (可選) ) statement |
|||||||||
| 屬性 | - | (C++11 起) 任意數量的 屬性 (attributes) | ||
| 初始化陳述式 (init-statement) | - | 其中之一為
請注意,任何 init-statement 都必須以分號結尾。這就是為什麼它通常被非正式地描述為一個表達式或宣告,後面跟著一個分號。 | ||
| 條件 (condition) | - | 一個 條件 | ||
| expression | - | 表達式(通常是用於遞增迴圈計數器的表達式) | ||
| statement | - | 一個 語句 (statement)(通常為複合語句) |
[編輯] 條件
|
(C++26 起) |
- 如果它在語法上可以被解析為表達式,則將其視為表達式。否則,將其視為宣告(非結構化綁定宣告)(C++26 起)。
當控制流程到達 condition 時,該條件會產生一個值,該值用於決定是否執行 statement。
[編輯] 表達式
如果 condition 是表達式,其產生的值是該表達式在上下文中轉換為 bool 的值。如果該轉換格式錯誤,則程式格式錯誤。
[編輯] 宣告
如果 condition 是簡單宣告,其產生的值是決策變數(見下文)在上下文中轉換為 bool 的值。如果該轉換格式錯誤,則程式格式錯誤。
[編輯] 非結構化綁定宣告
該宣告具有以下限制
- 語法上符合以下形式
|
(直到 C++11) |
|
(C++11 起) |
- 宣告子 (declarator) 不能指定 函式 或 陣列。
- 型別說明符序列(C++11 前)宣告說明符序列 只能包含型別說明符和 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++ 進度保證 (forward progress guarantee) 的一部分,若一個迴圈(非 平凡無限迴圈)(自 C++26)不具備 可觀察行為 (observable behavior) 且無法終止,則其行為是 未定義的 (undefined)。編譯器被允許移除此類迴圈。
雖然在 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
[編輯] 參閱
範圍 for 迴圈(C++11) |
在範圍上執行迴圈 |
| C 文件 關於 for
| |