このコラムでは、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文は限定的に「多重ループから一気に脱出」にしか使わないようにしておいてください。
※「多重ループから一気に脱出」しなければならないケースもそう多くはありませんが・・・
ブラウザの戻るボタンで戻ってください。