3.7 goto文
3.7.1 無条件ジャンプ
これまでの分岐や繰り返しは、何らかの条件を指定して制御を行いましたが、無条件で指定した場所にプログラムをジャンプさせることもできます。無条件ジャンプを行うには goto 文を用います。
goto ラベル;
ラベルには、ジャンプ先の文が持つラベルを指定します。ラベルは「3.3 switch 文」で少し紹介しましたが、簡単に言うと文につける識別子のようなものです。文にラベルをつければ goto 文でその場に移動できるようになります。ラベルは次のように指定します。
ラベル: 文
こうすることで、文にラベルを付けることができます。ラベルに使う名前は変数などの命名規則と同様です。文にラベルをつければ、goto 文を用いて自由にプログラムの流れを変更することができるようになります。ただし、goto 文は同一の関数内でなければ移動することができません。他の関数の文に直接ジャンプすることはできないので、注意してください。
#include <stdio.h> int main() { int iCount = 0; LOOP: printf("カウンター = %d\n" , iCount); iCount++; if (iCount < 10) goto LOOP; return 0; }
このプログラムは、繰り返し処理を goto 文で再現したものです。iCount 変数が 10 以下であれば goto 文を用いて LOOP ラベルまで戻り、そうでなければプログラムを終了させます。
ただし、for 文や while 文を使う方法と goto 文を使う方法では、間違いなく for 文や while 文を使って繰り返し処理を行うべきであり、goto 文を使うべきではありません。多くの場合、goto 文を使う必要はなく、if や for 文のような制御文で十分目的の処理を実現させることができます。goto 文を乱用した場合、プログラムの流れが把握できなくなり、保守が難しくなるため goto 文は原則として使うべきではないと考えられています。
goto 文を使うべき場所として考えられるのは、goto 文を使うことでプログラムをスマートに記述できるような特別なアルゴリズムを書く場合か、数段階に入れ子になった制御文から抜け出すような場合でしょう。例えば、for 文を入れ子にしたプログラムが、途中で処理を終わらせたい場合、break 文を使っても一段階外の制御に抜け出すだけで、全ての制御を抜け出すことはできません。そこで goto 文を使って抜け出すことができます。
for(;;) { for(;;) { ... if(error) goto ERROR; } } ERROR: ...
このように、入れ子構造の繰り返し処理の内部で、エラーが発生するなどの理由からトップレベルの制御に移行したい場合、goto 文を使って強制的に抜け出すというような手段が有効です。