名前空間
変種
操作

goto 文

提供: cppreference.com
< c‎ | language

所望の位置に無条件に制御を転送します。

条件構文を用いて所望の位置に制御を転送することができないときに使用されます。

目次

[編集] 構文

goto label ;
label : statement

[編集] 説明

goto 文は、名前付きの label (goto 文と同じ関数内に現れなければなりません) が付けられた文に、無条件にジャンプ (制御を転送) させます。 ただし、このジャンプが可変長配列または別の可変修飾型のスコープに入るときは除きます。 (C99以上)

label は識別子にコロン (:) と文が続いたものです。 ラベルは関数スコープを持つ唯一の識別子です。 これらは、それが現れたのと同じ関数のあらゆる場所から (goto 文で) 使用できます。 任意の文の前に複数のラベルがあっても構いません。

可変修飾でない変数のスコープに入ることは許されます。

goto lab1; // OK、普通の変数のスコープに入ります。
    int n = 5;
lab1:; // 注: n は初期化されません (int n; と宣言されたかのように)。
 
//  goto lab2;   // エラー、 VM 型のスコープに入ることはできません。
    double a[n]; // VLA
    int (*p)[n]; // VM ポインタ
lab2:

goto が VLA のスコープから抜ける場合は、その VLA は解放されます (そして、その初期化が再度実行された場合は、再確保されます)。

{
    int n = 1;
label:;
    int a[n]; // 毎回異なるサイズで、10回再確保されます。
    if (n++ < 10) goto label; // VM のスコープを抜けます。
}
(C99以上)

[編集] キーワード

goto

[編集] ノート

宣言は文ではないため、宣言の前のラベルは空文を使用しなければなりません (コロンの直後にセミコロンを置きます)。 ブロックの終わりの前のラベルも同じです。

C++ では、 goto 文に追加の制限が課されますが、宣言の前のラベルが許可されます (C++ では宣言は文です)。

[編集]

#include <stdio.h>
 
int main(void)
{
    // goto は複数段のループを簡単に抜けるために使用できます。
    for (int x = 0; x < 3; x++) {
        for (int y = 0; y < 3; y++) {
            printf("(%d;%d)\n",x,y);
            if (x + y >= 3) goto endloop;
        }
    }
endloop:;
}

出力:

(0;0)
(0;1)
(0;2)
(1;0)
(1;1)
(1;2)

[編集] 参考文献

  • C11 standard (ISO/IEC 9899:2011):
  • 6.8.6.1 The goto statement (p: 152-153)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.8.6.1 The goto statement (p: 137-138)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 3.6.6.1 The goto statement

[編集] 関連項目