for ループ
文がループ条件を管理する必要がない場合に、文を繰り返し条件付きで実行します。
目次 |
[編集] 構文
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 に変換したものです。その変換が不適格である場合、プログラムは不適格となります。
[編集] 非構造化束縛宣言
この宣言には以下の制限があります
- 構文的に以下の形式に準拠する
|
(C++11まで) |
|
(C++11以降) |
- 宣言子は関数や配列を指定することはできません。
- 型指定子シーケンスは(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++ の前方進行保証の一環として、観測可能な振る舞いを持たないループ(自明な無限ループではない)(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
[編集] 関連項目
範囲forループ(C++11) |
範囲に対するループを実行する |
| for のC言語ドキュメント
| |