2011-11-16 5 views
5

今日のケーススイッチのコードを見て、どのように動作するのか少し驚いていました。コードはでした:ケーススイッチはこのように動作しますか?

switch (blah) 
{ 
case a: 
    break; 
case b: 
    break; 
case c: 
case d: 
case e: 
    { 
    /* code here */ 
    } 
    break; 
default : 
    return; 
} 

変数がcたシナリオで驚いたことに、パスは「コードここでは、」セグメント内で行ってきました。私はケーススイッチの一部であるcの最後に休憩がないことに同意しますが、代わりにdefaultを通過すると想像しました。あなたがcase blah:行に着陸するとき、あなたの現在の値が特定の場合と一致しているかどうかをチェックしていないのですか?が特定のセグメントに入ってしまいますか?それ以外の場合は何が起こっているのでしょうか?

答えて

13

これはフォールスルーケースと呼ばれ、望ましい挙動です。ケース間でコードを共有することができます。

場合のフォールスルーの動作を使用する方法の例は:

あなたがスイッチ blah == aを入力した場合
switch(blah) 
{ 
case a: 
    function1(); 
case b: 
    function2(); 
case c: 
    function3(); 
    break; 
default: 
    break; 
} 

、あなたはfunction1()function2()、およびfunction3()を実行します。

この動作をしたくない場合は、breakステートメントを含めてオプトアウトすることができます。

switch(blah) 
{ 
case a: 
    function1(); 
    break; 
case b: 
    function2(); 
    break; 
case c: 
    function3(); 
    break; 
default: 
    break; 
} 

switch文が動作する方法は、それが(多かれ少なかれ)あなたのケースのラベルにジャンプするgotoを実行し、その時点から走り続けるということです。実行がbreakに達すると、スイッチブロックから出ます。

+0

: - 丁寧な返信をお願いします!私はそれがどのように機能するかを知っている。それは、私の常識に反しているということだけです。私はまだその行動が直感的ではないと思います。私は日付まで、それらの「事件(ああ)」は、あなたの変数が本当に(まあまあ)..明らかにそれはCの仕組みではありません! – Manish

+2

@Manish:スイッチはしばしば "[支店テーブル](http://en.wikipedia.org/wiki/Branch_table)"で実装されています。プログラミングには常識は存在しません。代わりに "プログラマーセンス"が必要です:) –

+2

@Manish両方の動作が望ましいですが、デフォルトのフォールスルーと明示的に「ブレークアウト」、またはデフォルトのブレークアウトがあり、必要に応じて次のケースに明示的に「続ける」ことができます。常識的な見方からすれば、後者はより自然に見えるかもしれませんが、実装を念頭に置いて、デフォルトのフォールスルーはより自然なので選択されました。 –

10

これは正しい動作であり、「落ちる」と呼ばれます。これにより、同じコードで複数のケースを扱うことができます。先進的な状況では、あるケースでいくつかのコードを実行し、別のケースに進むことができます。

不自然な例は:

switch(command) 
{ 
    case CMD_SAVEAS: 
    { 
     this->PromptForFilename(); 
    } // DO NOT BREAK, we still want to save 
    case CMD_SAVE: 
    { 
     this->Save(); 
    } break; 


    case CMD_CLOSE: 
    { 
     this->Close(); 
    } break; 

    default: 
     break; 
} 
+1

転倒の有名な例は[Duff's device](http://en.wikipedia.org/wiki/Duff%27s_device)です。 –

+0

これは非常にクールな使い方ですが、速度を最適化するときにコンパイラが通常あなたのためにやることだと思います。私は本当に良い理由があって、それがなぜ必要なのか、どのように保守するのかを説明する適切なコメントブロックがない限り、Cで書かれたものを見ることは決してありません。 – shenles

2

「後藤」のラベルとしてスイッチのラベル​​を考えると、switch(blah)は、単に対応するラベル、その後、コード「に行く」:-)幸いにも私たちのために、C++は、あなたの想像力に依存しませんそこからちょうど流れます。

2

実際にswitch文は、あなたが観察したとおりに動作します。それは、休憩に遭遇してふるいのように働くまで、いくつかのケースを一緒に組み合わせることができるように設計されています。ここで

は私のプロジェクトの一つから実際の例です:

struct keystore_entry *new_keystore(p_rsd_t rsd, enum keystore_entry_type type, const void *value, size_t size) { 
     struct keystore_entry *e; 
     e = rsd_malloc(rsd, sizeof(struct keystore_entry)); 
     if (!e) 
       return NULL; 
     e->type = type; 
     switch (e->type) { 
     case KE_DOUBLE: 
       memcpy(&e->dblval, value, sizeof(double)); 
       break; 
     case KE_INTEGER: 
       memcpy(&e->intval, value, sizeof(int)); 
       break; 

     /* NOTICE HERE */ 

     case KE_STRING: 
       if (size == 0) { 
         /* calculate the size if it's zero */ 
         size = strlen((const char *)value); 
       } 
     case KE_VOIDPTR: 
       e->ptr = rsd_malloc(rsd, size); 
       e->size = size; 
       memcpy(e->ptr, value, size); 
       break; 

     /* TO HERE */ 
     default: 
       return NULL; 
     } 
     return e; 
} 

KE_STRINGKE_VOIDPTR例のコードは、文字列の場合の大きさの計算を除いて同一です。

4

これはフォールスルーと呼ばれます。

あなたが見ていることを正確にしています。いくつかのケースでは、同じコードを実行することになります。

また、特定のケースのための余分な処理を行うことで、便利であり、いくつかの共有ロジック:

// psuedo code: 
void stopServer() { 
    switch (serverStatus) 
    case STARTING: 
    { 
     extraCleanUpForStartingServer(); 
     // fall-thru 
    } 
    case STARTED: 
    { 
     deallocateResources(); 
     serverStatus = STOPPED; 
     break; 
    } 
    case STOPPING: 
    case STOPPED: 
    default: 
     // ignored 
     break; 
} 

これは、スイッチケースでフォールスルーの典型的な使用です。 STARTINGとSTARTEDの場合は、deallocateResourcesを実行してステータスをSTOPPEDに変更する必要がありますが、STARTINGでは追加のクリーンアップが必要です。上記の方法で、あなたはSTARTINGで '共通ロジック'と余分なロジックを明確に提示することができます。

STOPPED、STOPPING、およびdefaultは似ていますが、すべてデフォルトロジック(これは無視されます)になります。

このようにコードを書くのは必ずしも良い方法ではありませんが、うまく使用されていれば、ロジックをより良く表現できます。

関連する問題