当前位置:  开发笔记 > 编程语言 > 正文

为什么switch语句需要休息?

如何解决《为什么switch语句需要休息?》经验,为你挑选了6个好方法。

给出一个简单的switch语句

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

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

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

在案例2中没有break语句意味着在案例3的代码中将继续执行.这不是偶然的; 它是这样设计的.为什么做出这个决定?这提供了什么好处与块的自动中断语义?理由是什么?



1> Michael Burr..:

许多答案似乎都集中在作为要求声明的理由而失败的能力break.

我认为这只是一个错误,主要是因为在设计C时,对这些结构的使用方式几乎没有多少经验.

Peter Van der Linden在他的"专家C编程"一书中提到了这个案例:

我们分析了Sun C编译器源,以查看使用默认值的频率.Sun ANSI C编译器前端有244个switch语句,每个语句平均有7个case.在所有这些案例中仅有3%发生堕落.

换句话说,正常的开关行为在97%的时间是错误的.它不只是在编译器中 - 相反,在此分析中使用了跌倒通常用于编译器中比在其他软件中更频繁发生的情况,例如,在编译可以具有一个或两个操作数的运算符时:

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

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

案件失败被广泛认为是一种缺陷,甚至还有一个特殊的评论惯例,如上所示,它告诉lint"这实际上是需要堕落的3%的案例中的一个."

我认为C#在每个case块的末尾需要一个显式的跳转语句是一个好主意(同时仍然允许堆叠多个case标签 - 只要只有一个语句块).在C#中你仍然可以让一个案例掉到另一个案例中 - 你只需要通过跳转到下一个案例来明确地使用goto.

Java没有抓住机会摆脱C语义,这太糟糕了.


甚至Pascal都可以不间断地实现他们的开关 C编译器怎么能不考虑它@@

2> dmckee..:

在很多方面,c只是标准装配惯用语的简洁接口.当编写跳转表驱动的流控制时,程序员可以选择通过或跳出"控制结构",跳出需要显式指令.

所以,c做同样的事情......


虽然现在人们更多地使用清洁和自我保护的身份和语言功能,以防止自己射入脚,这是一个字节昂贵的区域(C在1970年之前开始)的再生.如果您的代码需要在1024字节以内,那么您将需要重复使用代码片段.通过从共享相同目的的不同入口点开始重用代码是实现此目的的一种机制.

3> FlySwat..:

显然,要实现Duff的设备:

dsend(to, from, count)
char *to, *from;
int count;
{
    int n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
               } while (--n > 0);
    }
}


是的,但是每次在SO上有一个switch语句时它是否必须出现?
呵呵呵.自作聪明.
我喜欢Duff的设备.如此优雅,快速邪恶.
该代码是我们在C#中没有落后的原因:(

4> Bill the Liz..:

如果案件被设计为隐含地破坏那么你就不会遭遇破坏.

case 0:
case 1:
case 2:
    // all do the same thing.
    break;
case 3:
case 4:
    // do something different.
    break;
default:
    // something else entirely.

如果开关设计为在每个案例后隐式突破,您将无法选择它.开关盒结构的设计方式更加灵活.


您可以对隐藏中断但具有"fallthrough"关键字的开关进行映像.尴尬,但可行.

5> LeopardSkinP..:

switch语句中的case语句只是标签.

当您打开一个值时,switch语句基本上会转到具有匹配值的标签.

这意味着中断是必要的,以避免传递到下一个标签下的代码.

至于原因为何有人以这种方式实现- switch语句的落空自然可以在某些情况下非常有用.例如:

case optionA:
    // optionA needs to do its own thing, and also B's thing.
    // Fall-through to optionB afterwards.
    // Its behaviour is a superset of B's.
case optionB:
    // optionB needs to do its own thing
    // Its behaviour is a subset of A's.
    break;
case optionC:
    // optionC is quite independent so it does its own thing.
    break;


有两个大问题:1)忘记需要的"休息".2)如果案例陈述的订单发生了变化,则可能导致错误的案例被运行.因此,我发现C#的处理要好得多(明确的`goto case`用于fallthrough,除了空案例标签).

6> R....:

允许这样的事情:

switch(foo) {
case 1:
    /* stuff for case 1 only */
    if (0) {
case 2:
    /* stuff for case 2 only */
    }
    /* stuff for cases 1 and 2 */
case 3:
    /* stuff for cases 1, 2, and 3 */
}

case关键字视为goto标签,它自然而然地变得更加自然.


我想,整个答案都是邪恶的运动.:-)
在第一种情况结束时的`if(0)`是邪恶的,并且只有在目标是混淆代码时才应该使用它.
推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有