2

次のコードを検討してください

int x = 1
switch(x) {
    case 1:
        System.out.println("1");
    case 2:
        System.out.println("2");
    default:
        System.out.println("no value found");
 }

それは印刷します

1
2
no value found

予想どおりbreak、各ケースステートメントがないため、 xが2に等しくない ため
、最初のステートメントにブレークがない場合、各ケースステートメントに実行がどのように移動するかは疑問ですが、その実行ブロックも実行ブロックですが、プログラムなしで実行を続行するため、1つを理解しましたそして実行します
case 2
defaultbreakdefault statement

4

9 に答える 9

2

これは、C プログラミング言語の名残りです。Cでは、式の値に応じてswitcha に対する構文糖衣が少ししかないため、実行は単に適切な場所にジャンプしてそこから続行します。間にあるラベルはまさにそれです: ラベル。それらはジャンプ ターゲットですが、それ以外の場合は制御フローに影響しません。コンパイラの観点からは、他の場所にジャンプする価値のあるラベルはありません (INTERCAL がどこかにある場合を除く)。したがって、他のオプションに陥りたくない場合は、すべてのケースの後に明示的に配置する必要があります。gotocaseCOMEFROMbreak

Java は多かれ少なかれこれらのセマンティクスを継承し、クレイジーな C のイディオムをいくつか避けました。

一方、C# は、空でないcaseラベルでのフォールスルーを完全に禁止することで、もう少し進んでいます。

私の意見では、これはちょっとした設計ミスでした。デフォルトでのフォールスルーは、コンパイラで実装するのがはるかに簡単かもしれません (goto末尾に a を追加する必要がなくswitch、その下で実際に動作する方法と非常にうまく一致するため)、私の経験では、はるかに多くの機能があります。誤ってフォールスルーを使用しないことによるプログラミング エラーよりも、フォールスルーを誤って使用することによるプログラミング エラーの可能性があります。

私の目に最も深刻な設計上の誤りは、switch現代言語のすべての奇妙さを備えたステートメントを含めることです。

于 2013-07-21T08:14:09.523 に答える
0

正しい振る舞いです。「デフォルト」は、可能なすべての回答を意味するわけではありません。場合によっては、これらが書かれていないすべての回答を意味します。

int x=1
switch(x)
    {
        default:
             System.out.println("no value found");
        case 1:
            System.out.println("1");
        case 2:
            System.out.println("2");
    }

印刷します

1
2

印刷されません

no value found
1
2

休憩を使用する場合。ステートメントとデフォルト値は、各値に対して 1 つの「ブランチ」のみと呼ばれます。

于 2013-07-21T08:18:33.580 に答える
0

各 break ステートメントは、囲んでいる switch ステートメントを終了します。一致する case ラベルの後のすべてのステートメントは、後続の case ラベルの式に関係なく、break ステートメントが検出されるまで順番に実行されます。

if-then-elseを使用できます。テストのオーバーヘッドが増加します...これは switch-case では回避されますが、適切な実行にはブレークが必要です...

于 2013-07-21T08:18:55.667 に答える
0

C++ から継承された理由により、実行は switch の終わりまたはブレークまで自然に進行します。遭遇した場合のケースに対するテストはありません。

于 2013-07-21T08:12:02.750 に答える
0

switchフォールスルーです。必要でない限りbreak、次の前に追加する必要がありcaseます。

switch (x) {
    case 1:
        System.out.println("1");
        break;
    case 2:
        System.out.println("2");
        break;
    default:
        System.out.println("no value found");
}
于 2013-07-21T08:12:03.433 に答える
0

switch ステートメントは分岐テーブルの抽象化であり、分岐テーブルにも暗黙的なフォールスルーがあり、それを回避するには追加のジャンプ命令が必要です。このSOの回答も読んでください。

JLS 14.11に従って:

switch ステートメントの本体は、switch ブロックと呼ばれます。

ケース定数の 1 つが式の値と等しい場合、ケースが一致すると言い、switch ブロック内の一致するケース ラベルの後のすべてのステートメントがあれば、それらが順番に実行されます。

これらのステートメントがすべて正常に完了した場合、または一致する case ラベルの後にステートメントがない場合は、switch ステートメント全体が正常に完了します。

于 2013-07-21T08:12:49.470 に答える
0

それは、コンパイル方法と最適化に関係しています。

これが、チェーン化された一連の if ステートメントよりもスイッチの方が望ましい理由です。

于 2013-07-21T08:13:15.930 に答える
0

Javaドキュメントから:

break ステートメントがないと、switch ブロック内のステートメントが失敗するため、break ステートメントが必要です。一致する case ラベルの後のすべてのステートメントは、後続の case ラベルの式に関係なく、break ステートメントが検出されるまで順番に実行されます。

于 2013-07-21T08:13:51.380 に答える
0

switch ステートメントはステートメントとはif-then-else異なります。switchステートメントには複数の実行パスがあります。

ドキュメントには次のように記載されています。

制御フローは、switch ブロックに続く最初のステートメントから続行されます。break ステートメントがないと、switch ブロック内のステートメントが失敗するため、break ステートメントが必要です一致する case ラベルの後のすべてのステートメントは、後続の case ラベルの式に関係なく、break ステートメントに遭遇するまで順番に実行されます。

于 2013-07-21T08:16:05.740 に答える