名前空間
変種
操作

for ループ

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

文がループ条件を管理する必要がない場合に、文を繰り返し条件付きで実行します。

目次

[編集] 構文

attr(省略可能) for ( init-statement condition(省略可能) ; expression(省略可能) ) statement
attr - (C++11以降) 任意の数の属性
init-statement - 以下のいずれか
  • 式文(ヌル文 ; であることもある)
  • 単純宣言(通常は初期化子付きのループカウンタ変数の宣言)、任意の数の変数を宣言可能、または構造化束縛(C++17以降)
(C++23から)

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

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

[編集] 条件

condition は、または単純宣言のいずれかです。

  • 構文的に構造化束縛宣言として解決できる場合は、構造化束縛宣言として解釈されます。
(C++26以降)
  • 構文的に式として解決できる場合は、式として扱われます。そうでなければ、宣言として扱われます(構造化束縛宣言ではない)(C++26以降)

制御が condition に達すると、condition は値を生成し、その値は 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以降)

[編集] 説明

for 文は以下と等価です

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

}

ただし、以下の点を除きます

  • init-statement のスコープと condition のスコープは同じです。
  • statement のスコープと expression のスコープは分離しており、init-statementcondition のスコープ内にネストされています。
  • statement 内で continueを実行すると、expression が評価されます。
  • 空の conditiontrue と等価です。

statement 内でループを終了させる必要がある場合、breakを終了文として使用できます。

statement 内で現在のイテレーションを終了させる必要がある場合、continueをショートカットとして使用できます。

[編集] ノート

while ループと同様に、statement が複合文でない場合、その中で宣言された変数のスコープは、あたかも複合文であったかのようにループ本体に限定されます。

for (;;)
    int n;
// n goes out of scope

C++ の前方進行保証の一環として、観測可能な振る舞いを持たないループ自明な無限ループではない)(C++26以降)が終了しない場合、その振る舞いは未定義です。コンパイラはそのようなループを削除することが許可されています。

C言語では init-statementcondition のスコープで宣言された名前は statement のスコープで隠蔽(シャドウ)できますが、C++では禁止されています。

for (int i = 0;;)
{
    long i = 1;   // valid C, invalid C++
    // ...
}

[編集] キーワード

for

[編集]

#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) 範囲に対するループを実行する[編集]
English 日本語 中文(简体) 中文(繁體)