goto
ラベルとgoto
ラベルは、関数内のコード行に名前を付けます。
行にラベルを付けるには、その行に名前を付けてから、行が始まる前にコロン(:)を付けます。
gotoキーワードを使用すると、プログラムフローを同じ関数内のどこからでもラベル付きの行に転送できます。
警告
gotoの使用は、CおよびC ++プログラミングではお勧めできません。
プログラムを書くためにgotoを使う必要は決してありません。
あなたが何をしているのか分からない限り、gotoを使うことは、同じことをするgotoのないプログラムよりも、
デバッグし理解するのが難しいコードを奨励する傾向があります。
しかし、状況によりgootの利用が有用なケースがあります。 具体的な例については以下を参照してください。
ラベルとgotoの利用
ラベルとゴトはおそらく例を用いて最もよく説明されます。
まず、行にラベルを付ける方法の例を見てみましょう。
以下のループ関数の最初の行(int x = analogRead(some_pin);)には、readpinというラベルが付いています。
3行目(delay(x);)にはラベルstartdelayがあります。 2番目の行(SerialUSB.println(x);)にはラベルがありません:
code:gotoSample1.ino
void loop() {
readpin:
int x = analogRead(some_pin);
SerialUSB.println(x); // for debugging
startdelay:
delay(x);
// ... more code ...
}
変数名になりうるものは、ラベルにすることができます。
シリアルモニターで見ている誰かが、彼らがいつものよりも長い待ち時間をしていることを知っているだけなので、
これをやりたいと思うかもしれません。
xが2000より小さい場合、印刷をスキップするgoto文を使用してこれを達成できます。
code:gotoSample2.ino
void loop() {
readpin:
int x = analogRead(some_pin);
if (x < 2000) {
goto startdelay;
}
SerialUSB.println(x); // for debugging
startdelay:
delay(x);
// ... more code ...
}
この変更されたプログラムでは、xが2000より小さい場合は、2行目のif文の本文が実行されます。
if本体の中のgoto文は、startdelayというラベルの付いた行にまっすぐにスキップし、出力を行っている行を渡します。
gotoは「前進する」必要はありません。 それは "後方に行く"こともできます。
たとえば、次のプログラムは "5"を永遠に表示します(なぜ?):
code:gotoSample3.ino
void loop() {
printfive:
SerialUSB.println(5);
goto printfive;
SerialUSB.println(6);
}
gotoを使うべきな状況
前述のように、gotoの使用は一般的にはお勧めしません。
ただし、gotoを注意して使用すると、特定のプログラムを簡素化できます。
gotoの重要なユースケースの1つは、深くネストされたforループまたはロジックブロックの場合です。 ここに例があります:
code:gotoSample4.ino
for(int r = 0; r < 255; r++) {
for(int g = 255; g > -1; g--) {
for(int b = 0; b < 255; b++) {
if (analogRead(0) > 250) {
goto bailout;
}
// more statements ...
}
// innermost loop ends here
}
}
bailout:
// more code here
上記の例では、ピン0のアナログ値が250を超えると、プログラムは救済可能と表示された行にジャンプし、
3つのループを一度に終了します。
ループを中断するためのbreakキーワードは既にありますが、最も内側のループから抜け出すだけです。
だから、 "goto bailout;"の代わりに "break;"があった場合、プログラムはヘッダ "for(int b = 0; b <255; b ++)"のループから抜けるだけです。 プログラムは "//ここで終わるループはここで終わります"という行で続きますが、これは3つのループを一度に残したい場合には明らかに望ましくありません。
gotoが良い選択である場合のより多くの例は、Donald Knuthの論文「goto文を用いた構造化プログラミング(Structured Programming with goto Statements)」で解説されています。 下のリンクを参照してください。
関連項目
このドキュメントはleafLabs, LLC.が執筆し、たま吉が翻訳・一部加筆修正したものです。