C 言語 | フロー制御 | goto 文

指定した文へ無条件にジャンプする goto 文について説明する。

無条件ジャンプ

これまでに説明した分岐や繰り返しは、条件を指定してプログラムの流れを制御していた。条件なしで指定した位置へ処理を移動することもできる。無条件ジャンプには goto 文を使用する。

goto 文

goto ラベル;

ラベルには、ジャンプ先となる文のラベルを指定する。ラベルは switch 文でも少し説明したが、簡単に言えば文に付ける識別子である。文にラベルを付けると、goto 文でその位置へ移動できる。ラベルは次のように宣言する。

ラベルの宣言

ラベル: 文

ラベル名には変数などと同じ命名規則を使用する。文にラベルを付けると、goto 文でプログラムの流れを自由に変更できる。ただし、移動できるのは同じ関数の内部だけである。別の関数にある文へ直接移動することはできない。

コード 1

#include <stdio.h>

int main() {
  int iCount = 0;

LOOP:
  printf("counter = %d\n" , iCount);
 iCount++;
 if (iCount < 10) goto LOOP;

 return 0;
}

このプログラムは、繰り返し処理を goto 文で再現している。iCount 変数が 10 未満であれば goto 文で LOOP ラベルに戻り、それ以外の場合はプログラムを終了する。

ただし、for 文や while 文を使用できる場所では、それらを使って繰り返し処理を記述するべきであり、goto 文は使用しないほうがよい。ほとんどの場合、if 文や for 文などの制御文だけで目的の処理を実現できる。goto 文を乱用するとプログラムの流れを把握しにくくなり、保守も難しくなるため、原則として使用を避ける。

goto 文が有効なのは、ジャンプを使うことで明快に記述できる特別なアルゴリズムや、多段にネストした制御文を一度に抜けたい場合である。たとえば、break 文で抜けられるのは一段階だけだが、goto 文ならすべてのネストを抜けられる。

for(;;) {
  for(;;) {
   ...
   if(error) goto ERROR;
 }
}
ERROR:  ...

このように、ネストした繰り返し処理の内部でエラーが発生し、外側のエラー処理へ直接移動したい場合に効果的である。