for
loop
条件付きで文を繰り返し実行します。ここで、文はループ条件を管理する必要がありません。
目次 |
構文
attr
(オプション)
for (
init-statement
condition
(オプション)
;
expression
(オプション)
)
statement
|
|||||||||
| attr | - | (C++11以降) 任意の数の 属性 | ||
| init-statement | - |
以下のいずれか
任意の init-statement はセミコロンで終了しなければならないことに注意。これが、しばしば非公式に「式または宣言の後にセミコロンが続くもの」と説明される理由である。 |
||
| condition | - | 条件 | ||
| expression | - | 式 (通常はループカウンタをインクリメントする式) | ||
| statement | - | 文 (通常は複文) |
条件
condition は、 expression または simple declaration のいずれかです。
|
(C++26 以降) |
- 構文的に式として解決できる場合は、式として扱われます。それ以外の場合は、構造化束縛宣言ではない宣言として扱われます (since C++26) (C++26以降) 。
`, `
`, `
制御が条件式に到達すると、条件式は値を返し、その値に基づいて statement が実行されるかどうかが決定されます。
式
condition が式である場合、その評価結果は式が文脈的に bool に変換された値となります。この変換が不適格な場合、プログラムは不適格となります。
宣言
condition が単純な宣言である場合、その結果の値は決定変数(下記参照)の値を文脈的に bool に変換したものである。その変換が不適格な場合、プログラムは不適格となる。
非構造化バインディング宣言
この宣言には以下の制限があります:
- 構文的には以下の形式に従います:
|
(C++11まで) |
|
(C++11以降) |
- 宣言子は 関数 または 配列 を指定できません。
- 型指定子シーケンス (C++11まで) 宣言指定子シーケンス は型指定子と constexpr のみを含むことができ、 (C++11以降) クラス または 列挙型 を定義できません。
宣言の決定変数は、宣言された変数です。
構造化バインディング宣言この宣言には以下の制限があります:
この宣言の決定変数は、宣言によって導入される発明された変数 e です 。 |
(C++26以降) |
説明
A for 文と同等のステートメント:
{
|
|||||||||
ただし
- init-statement のスコープと condition のスコープは同一である。
- statement のスコープと expression のスコープは互いに素であり、 init-statement および condition のスコープ内にネストされている。
- statement 内で continue 文 を実行すると、 expression が評価される。
- 空の condition は true と等価である。
ループを statement 内で終了させる必要がある場合、 break statement を終了文として使用できます。
現在の反復処理を statement 内で終了させる必要がある場合、 continue statement をショートカットとして使用できます。
注記
while
ループの場合と同様に、
statement
が複合文でない場合、その中で宣言された変数のスコープは、あたかも複合文であったかのようにループ本体に限定されます。
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) 初期化文では同じdecl-specifier-seqを使用できる限り\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) 初期化文では同じdecl-specifier-seqを使用できる限り 複数の名前を宣言できます: 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
関連項目
range-
for
ループ
(C++11)
|
範囲に対するループを実行 |
|
Cドキュメント
for
for
|
|