4

だから私は次のように(出力を尋ねる)競争の質問に出くわしました:

#include <stdio.h>
int main()
{
    int i = 0;
    for(i = 0; i < 20; i++)
    {
        switch(i)
        {
            case 0: i+=5;
            case 1: i+=2;
            case 5: i+=5;
            default: i+= 4;
            break;
        }
        printf("%d ", i);
    }
    return 0;
}

出力は16, 21です。スイッチケースがどのように機能するかは知っていますが、このフォールスルーがどのように機能するかを説明することはできません. デフォルトが追加されるのはなぜですか? K&R C book には、デフォルトは一致するケースがない場合にのみ実行されると書かれていませんか?
ありがとう。

4

4 に答える 4

5

デフォルトのケースは、他のケースが一致しない場合にのみ、ステートメントからジャンプされます。switchそれらの 1 つが一致した後、コードは、caseステートメントが存在しないかのように実行されbreakます。そのため、defaultケースは期待どおりに「飛び越え」ません。

K&Rはこれについて少し不明確です。あなたが言及している行は次のようです:

ケースが式の値と一致する場合、そのケースから実行が開始されます。ケース式はすべて異なっている必要があります。デフォルトとラベル付けされたケースは、他のケースが満たされない場合に実行されます

しかし、これはswitchステートメントがどのように分岐するかについて話しています。フォールスルーの動作は次のページにあります。

ケースは単なるラベルとして機能するため、1 つのケースのコードが完了すると、明示的なアクションを実行してエスケープしない限り、実行は次のケースに移行します。

これは、ケースがあるかどうかに依存しませんdefault

C 標準はより明確です。

switch ステートメントは、制御式の値に応じて、制御が switch body であるステートメントにジャンプしたり、そこにジャンプしたり、そこを通り過ぎたりする原因となります ... 変換された値が昇格された制御式の値と一致する場合、制御は次のステートメントにジャンプします一致したケース ラベル。それ以外の場合、デフォルトのラベルがあれば、コントロールはラベル付きステートメントにジャンプします。

コントロールがジャンプすると、casedefaultラベルはもはや重要ではなくなります。

于 2014-08-30T18:10:50.863 に答える
1

ステートメントの「本体」switchは、1 つの連続した線形複合ステートメントです。caseラベルはまさにそのラベルあり、その連続したステートメントへのさまざまなエントリポイントを定義します。defaultラベルも単なるラベルであり、その点ではラベルと変わりませんcase

switchラベルを介して複合ステートメントに入ると、実行は通常の方法で続行されます。つまり、複合ステートメントの最後まで順番に実行されます (その段階で、 case/defaultラベルはもはや役割を果たしません)。これが起こらないようにしたい場合は、適切なタイミングでその複合ステートメントから飛び出すのはあなたの責任です。そのために任意の jump ステートメントを使用できますが、自由に使用できることも覚えておいてbreakください (ほとんどの場合、これが最も適切な選択です)。

言い換えれば、switch一見しただけでわかるように、高度に構造化されたブランチ セレクターではありません。switchは、わずかに構造化されたマルチターゲットgotoです。それが行うのは、実行時にパラメータ化された単一のジャンプだけです。その後のジャンプはすべてあなたの責任です。

コードサンプルでは、​​複合ステートメントbreakの最後にローンを配置しました。switchその位置では、複合ステートメントがとにかくそこで終わるため、実際にはまったく何も達成しませんでした。

于 2014-08-30T19:03:35.993 に答える
0

その特定のケースを終了する必要があるたびにブレークステートメントを追加する必要があります。そうしないと、すべてのケースステートメントが失敗します

于 2014-08-30T18:31:27.937 に答える
0

デフォルト以外のスイッチケースに含まれる「ブレーク」はありません。

switch ステートメントを中断せずに使用すると、一致するケースが見つかった後もコードが実行され続けます。

修正されたコードの下を参照してください。

    switch(i)
    {
        case 0: i+=5;
        break;
        case 1: i+=2;
        break;
        case 5: i+=5;
        break;
        default: i+= 4;
        break;
    }
于 2014-08-30T18:14:39.053 に答える