Namespaces
Variants

for loop

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
for
range- for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

条件付きで文を繰り返し実行します。ここで、文はループ条件を管理する必要がありません。

目次

構文

attr  (オプション) for ( init-statement condition  (オプション) ; expression  (オプション) ) statement
attr - (C++11以降) 任意の数の 属性
init-statement - 以下のいずれか
(C++23以降)

任意の init-statement はセミコロンで終了しなければならないことに注意。これが、しばしば非公式に「式または宣言の後にセミコロンが続くもの」と説明される理由である。

condition - 条件
expression - (通常はループカウンタをインクリメントする式)
statement - (通常は複文)

条件

condition は、 expression または simple declaration のいずれかです。

  • 構文的に structured binding 宣言として解決できる場合は、structured binding 宣言として解釈されます。
(C++26 以降)
  • 構文的に式として解決できる場合は、式として扱われます。それ以外の場合は、構造化束縛宣言ではない宣言として扱われます (since C++26) (C++26以降)
注記: - HTMLタグと属性は翻訳せず、元の書式を保持しました - ` `, `
`, ``タグ内のテキストは翻訳対象外ですが、このテキストには該当しませんでした
- C++専門用語("expression", "declaration", "structured binding declaration")は翻訳せず、技術的な正確性を保ちました
- 重複する"(since C++26)"表記については、自然な日本語表現になるよう調整しました

制御が条件式に到達すると、条件式は値を返し、その値に基づいて statement が実行されるかどうかが決定されます。

condition が式である場合、その評価結果は式が文脈的に bool に変換された値となります。この変換が不適格な場合、プログラムは不適格となります。

宣言

condition が単純な宣言である場合、その結果の値は決定変数(下記参照)の値を文脈的に bool に変換したものである。その変換が不適格な場合、プログラムは不適格となる。

非構造化バインディング宣言

この宣言には以下の制限があります:

  • 構文的には以下の形式に従います:
  • type-specifier-seq declarator = assignment-expression
(C++11まで)
  • attribute-specifier-seq (オプション) decl-specifier-seq declarator brace-or-equal-initializer
(C++11以降)

宣言の決定変数は、宣言された変数です。

構造化バインディング宣言

この宣言には以下の制限があります:

この宣言の決定変数は、宣言によって導入される発明された変数 e です

(C++26以降)

説明

A for 文と同等のステートメント:

{
init-statement
while ( condition )
{
statement
expression ;
}

}

ただし

  • 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++
    // ...
}

キーワード

for

#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) 範囲に対するループを実行