1. ホーム
  2. c

[解決済み] switch文はなぜブレークが必要な設計になっているのでしょうか?

2022-05-04 20:01:25

質問

単純なswitch文がある場合

switch (int)
{
    case 1 :
    {
        printf("1\n");
        break;
    }

    case 2 : 
    {
        printf("2\n");
    }

    case 3 : 
    {
        printf("3\n");
    }
}

ケース2でbreak文がないのは、ケース3のコードの中で実行が継続されることを意味します。 これは偶然ではなく、そのように設計されているのです。なぜこのような決定がなされたのでしょうか?ブロックに自動的なブレークセマンティックを持たせた場合と比較して、どのような利点があるのでしょうか?その根拠は何ですか?

解決方法は?

として、落ち切りに着目した回答が多いようです。 理由 を必要とするのは break ステートメントを使用します。

C言語が設計された当時は、これらの構成要素がどのように使用されるかについての経験がほとんどなかったため、単純にミスだったと考えています。

ピーター・ヴァン・デル・リンデンは、彼の著書「エキスパートCプログラミング」の中で、このことを述べています。

<ブロッククオート

Sun Cコンパイラのソースを解析したところ デフォルトのフォールディングの頻度を確認するために が使用されていました。 Sun ANSI C コンパイラのフロントエンドには244個のスイッチ ステートメントがあり、それぞれのステートメントには 平均7件 フォールスルー が発生するのは、全体の3%に過ぎない。

つまり、通常のスイッチ の動作は 97%の確率で。 コンパイラに限ったことではありません - それどころか 逆にフォールスルーが使われているところでは この分析では、多くの場合 より頻繁に発生する状況 他のソフトウェアに比べ、コンパイラで 例えば、演算子をコンパイルする場合 1個または2個を持つことができる のオペランドを指定します。

switch (operator->num_of_operands) {
    case 2: process_operand( operator->operand_2);
              /* FALLTHRU */

    case 1: process_operand( operator->operand_1);
    break;
}

ケースフォールスルーは非常に広く普及している 不具合として認識されているため という特別なコメント規約があるほどです。 上図のように、lint に "これは 本当に3%のケースのうちの1つで が望ましいとされています。

C#では、各ケースブロックの最後に明示的なジャンプ文が必要なのは良いアイデアだったと思います(ただし、複数のケースラベルを重ねることは可能です - 文のブロックが1つである限りは)。C#では、あるケースから別のケースにフォールスルーさせることは可能ですが、次のケースにジャンプするために goto .

Javaがこの機会にCのセマンティクスから脱却できなかったのは残念です。