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 书不是说只有在没有匹配的情况下才会执行默认设置吗?
谢谢。

4

4 回答 4

5

如果没有其他案例匹配,则仅从语句跳转到默认案例。switch在其中一个匹配后,代码会像不case存在任何语句一样执行,除非它遇到break. 所以这个default案子并没有像你想象的那样“跳过”。

K&R对此有点不清楚,您所指的行似乎是:

如果一个案例与表达式值匹配,则从该案例开始执行。所有 case 表达式必须不同。如果其他情况都不满足,则执行标记为 default 的情况

但这是在谈论switch语句是如何分支的。Fallthrough 行为在下一页:

因为 case 就像标签一样,在一个 case 的代码完成后,除非你采取明确的行动来逃避,否则执行会落到下一个 case。

这不取决于是否有default案例。

C标准更清晰:

switch 语句会导致控制跳转到、进入或超过作为 switch 主体的语句,具体取决于控制表达式的值......如果转换后的值与提升的控制表达式的值匹配,则控制跳转到后面的语句匹配的案例标签。否则,如果有默认标签,则控制跳转到有标签的语句。

一旦控制跳转,casedefault标签就不再重要了。

于 2014-08-30T18:10:50.863 回答
1

语句的“主体”switch是一个连续的线性复合语句。case标签就是 -标签,它定义了该连续语句的不同入口点。default标签也只是一个标签,case在这方面与标签没有什么不同。

一旦您通过标签进入switch复合语句,执行将以正常方式继续:顺序一直到复合语句的末尾(在那个阶段case/default标签不再起作用)。如果你想防止这种情况发生,你有责任在适当的时候跳出那个复合语句。您可以为此使用任何跳转语句,请记住您也可以使用break(在大多数情况下这是最合适的选择)。

换句话说,switch它不是一个高度结构化的分支选择器,因为它可能一见钟情。switch只是稍微结构化的多目标goto。它所做的只是一个运行时参数化跳转。跳跃之后的一切都是你的责任。

在您的代码示例中,您在复合语句break的最后放置了一个单独的。switch在那个位置它实际上什么也没做,因为复合语句无论如何都到此结束。

于 2014-08-30T19:03:35.993 回答
0

除了默认值之外,switch case 中不包含“break”。

当 switch 语句没有中断使用时,即使找到匹配的 case,代码也会继续执行。

请参阅下面的更正代码:

    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 回答
0

每次需要结束特定案例时都需要添加 break 语句,否则它将贯穿所有案例语句

于 2014-08-30T18:31:27.937 回答