このコラムでは、goto文について書きます。
多重ループからbreakを使って抜け出す際に、同じ条件を2回書かなければならないことを解消するため、goto文を紹介するのですが、このgoto文は非常に危険な命令ですので、色々と注意事項を書きながら進めていきます。
まずは文法です。
・goto文の文法
goto ラベル名;
これで、自分が設定したラベル名の部分へジャンプ(実行する行を移動すること)します。
ラベルの書き方は、
ラベル名: ← コロンです!間違えないように!
です。
1つサンプルを書いてみます。
<sample program col023-01>
#include <stdio.h> int main(void) { printf("Program Start\n"); goto LABEL; printf("Hello\n"); LABEL: printf("Program End\n"); return 0; } |
<実行結果>
Program Start Program End 続行するには何かキーを押してください・・・
goto文の後ろにジャンプ先のラベル(LABEL)を書きました。
このLABELという単語は特に意味はありません、皆さんが自由につけて良い名前です。
少し下の行に
LABEL: |
という記述が見えます。
goto文が実行されると、この場所にジャンプします。
今回のプログラムでは、goto文とラベルの間の文、
printf("Hello\n"); |
が実行されていません。
これはgoto文によってプログラムの実行がジャンプ(飛び越)されたからです。
このように、gotoとラベルの組み合わせで、自分の好きな箇所へジャンプさせることができるのです。
これを使って、多重ループから抜け出してみます。
※< sample program 059-05 >の書き換えです。
<sample program col023-02>
#include <stdio.h> int main(void) { int i; int j; for (i = 2; i < 10; i++) { for (j = 2; j < 10; j++) { printf("%3d", i * j); if (i == 5 && j == 5) { goto LABEL; } } printf("\n"); } LABEL: return 0; } |
<実行結果>
4 6 8 10 12 14 16 18 6 9 12 15 18 21 24 27 8 12 16 20 24 28 32 36 10 15 20 25続行するには何かキーを押してください・・・
iとjが5になった場合、goto文を使って一気に二重ループを抜け出します。
この形だと、同じような条件を2回も書かずに済みます。
※改行が実行されていないため、表示は少しおかしいですが・・・
このように、多重ループから一気に抜け出したい場合goto文は役に立ちます。
しかし、多くのプロジェクト等では、goto文は絶対に使ってはならない等の措置が取られています。
便利な命令ですが、なぜでしょうか?
これには、次のような理由があります。
goto文を多用(悪用)するとプログラムが見づらくなり、デバッグが非常に難しくなる
例えば、次のプログラムが何を行っているか考えてみてください。
<sample program col023-03>
#include <stdio.h> int main(void) { int i; i = 0; LOOP: printf("Hello\n"); i++; if (i >= 5) { goto EXIT; } goto LOOP; EXIT: return 0; } |
これは、下のプログラムをfor文を使わずに書いた例です。
<sample program col023-04>
#include <stdio.h> int main(void) { int i; for (i = 0; i < 5; i++) { printf("Hello\n"); } return 0; } |
<実行結果>
Hello Hello Hello Hello Hello 続行するには何かキーを押してください・・・
どちらが分かりやすいか、すぐに分ると思います。
ただ、このような例はまだ分かりやすいケースで、goto文を多用したプログラムはもっと悪質です。
当面はgoto文は限定的に「多重ループから一気に脱出」にしか使わないようにしておいてください。
※「多重ループから一気に脱出」しなければならないケースもそう多くはありませんが・・・
ブラウザの戻るボタンで戻ってください。