2013-06-19 11 views
14

スイッチケースの奇妙なスコープ

なぜこの有効なCですか?
このコードの実行に及ぼす効果は、予想される場所でブレースを閉じることと比較してどのような影響がありますか?
これが使用できる場合はありますか?

編集:私はすべての休憩を見ての例では(上記のように)存在していた - しかし、0または1

+0

これは、 'switch-case'の奇妙な' goto label'実装のためです。あなたの特定のケースはおそらく少し奇妙で、ユースケースを思いつくのは難しいですが(ただし、[* Duff's Device *](http://en.wikipedia.org/wiki/Duff%27s_device)を見てください)、 fall-throughの一般的な考え方(あなたが '休憩 'を離れたとき)は、実際にはかなり役に立つことがあります。 –

+2

あなたが* Duffのデバイス*の仕組みについての説明を求めている場合は、[こちら](http://stackoverflow.com/questions/514118/how-does-duffs-device-work)がいくつかあります。 – devnull

+0

このケースでは、 'case 1:'はコンパイラによって別のラベルとして扱われています。構文は完全に有効ですが、(状況から)この状況で論理エラーが発生することはほぼ確実です。 'state == 1'を送信してテストすれば、間違った結果が表示されます。 – Chad

答えて

12

ない場合のみでブレーク不在は、それが有効であるかどうかの答えにも行動を含むことができ、同様の構造をしています実際のコードで使用される、例えば、Duff's Device、バッファをコピーするための展開ループである:switch文は本当にただのアドレスを計算し、それにジャンプするので

send(to, from, count) 
register short *to, *from; 
register count; 
{ 
     register n = (count + 7)/8; 
     switch(count % 8) { 
     case 0: do { *to = *from++; 
     case 7:   *to = *from++; 
     case 6:   *to = *from++; 
     case 5:   *to = *from++; 
     case 4:   *to = *from++; 
     case 3:   *to = *from++; 
     case 2:   *to = *from++; 
     case 1:   *to = *from++; 
       } while(--n > 0); 
     } 
} 

、それが他と重複することができます理由は簡単です制御構造;他の制御構造内の行には、ジャンプ先となるアドレスもあります。

あなたが提示したケースでは、あなたのコードにswitchまたはbreakがないと想像してください。 if声明のthen部分の実行が終了したら、続行しているので、case 2:に入ります。あなたはswitchbreakを持っているので、今度はbreakが壊れる可能性があります。 MSDN page, “The C break statement”

によるとブレーク文はは、それが表示されるため、スイッチ、またはしばらく文を行う囲む最寄りの実行を終了します。制御は、終了したステートメントに続くステートメントに移ります。文はあなたのスイッチ場合は、そのリストに含まれていない旨の通知)、その後、あなたの場合」が

最寄りのため、行うを囲んでいるので、スイッチ、またはありながら、 thenブロック内にある場合は、switchステートメントの外側に転送されます。あなたがcase 0と入力するとどうなるのでしょうか?c == 'A'はfalseです。次に、ifは、thenブロックの閉じ括弧の直後に制御を移し、case 2でコードの実行を開始します。

+1

c!= 'A'の場合は、あなたが説明する方法に意味がありますが、それは直感的でコードから一目瞭然です。 – Ricibob

+0

@Ricibobそれは "高レベルアセンブリ"として視聴Cの一定量を取る、私は認めます。 Cコードがどのようにアセンブリ/マシンコードにコンパイルされているかを調べるのに少し時間を費やしていれば、少し楽になります。たとえば、 'if条件then'ステートメントでは、ジャンプは1つだけです。条件が_false_の場合は、 'then'部分の直後にジャンプします。あなたが 'then'部分で終わると、実行を続けるとそこにも行きます。 '休憩 'の必要はありません。しかし、反復形式では、例えば「条件ブロック中」ブロックはコンパイルされ、最初にジャンプしてテストを開始します。 –

+0

@Ricibob ...条件を再度実行し、ブロックに再度入るか、または後にジャンプしますブロック。だから、反復構造には、体が最初に戻ってくるので、「休憩」が必要です。 'switch'は奇妙なものですが、繰り返しはしません。プログラマがたった1つのケースを実行し、残りの部分を実行したくないということが非常に一般的であり、休憩せずにswitchステートメントの直後に新しいラベルを書いて、それぞれのケースから「goto」しなければならないので、 。いずれにせよ、あなたがそうしなければ、この種の制御フローインターリーブを行うのは良いスタイルではないかもしれません... –

3

CおよびC++では、任意の変数宣言を飛び越えない限り、ループおよびブロックにジャンプすることは合法です。 gotoを使用してthis answerの例を確認できますが、なぜ同じ考えがswitchブロックに適用されないのかわかりません。

}case 1を上回っていた場合とは意味が異なります。
state == 0c != 'A'の場合はcase 2になるので、if文の閉じ括弧があるので、実際にこのコードを実行します。その後、そのコードを処理し、case 2コードの最後にbreakステートメントをヒットします。

+0

+1変数の宣言をスキップすることについての言及 – legends2k