逗号运算符在switch语句中的含义是什么?

时间:2013-10-19 14:03:36

标签: c++ c

我收到了一个问题,并被要求提供输出。

int main(void){  
    int x = 2;  
    switch(x){  
        case 1,2,1: printf("Case 1 is executed");  
            break;  
        case 2,3,1: printf("Case 2 is executed");  
            break;  
        default : printf("Default case us executed");  
    }  
    return 0;  
}

上面的代码在Turbo C中给出了输出“案例1被执行”,但在代码块和在线编译时,它给出了编译器错误。

哪一个是正确的?这是编译器错误吗?如果没有,为什么代码只在Turbo C上运行?

6 个答案:

答案 0 :(得分:38)

  

是否是编译器错误。

两种语言的代码都无效:case表达式必须是常量表达式,而常量表达式不能包含逗号运算符。 (在C中,这是明确说明的;在C ++中,您必须取消语法以发现常量表达式必须是条件表达式,这不能包含逗号)。

即使你被允许在这里使用逗号运算符,switch语句仍然无效,因为两个案例都具有相同的值,1。

  

如果没有,为什么代码只能在turbo C上运行。

因为自上次更新史前编译器以来,这两种语言都发生了重大变化。如果你想从本世纪学习C或C ++的变体,不要使用它。

答案 1 :(得分:10)

逗号运算符在switch语句中的含义是什么?
这意味着你有一个旧的编译器。

编辑帖子 (以显示case range示例)

前两个示例(包括您的原始代码)显示错误的switch语句语法(带有解释)。第三个代码示例显示堆栈案例标签是如何正确完成的:

在您的代码中,编译器应该在case 1,之后标记第一个逗号< - here

#include <ansi_c.h>
int main(void){  
    int x = 2;  
    switch(x)
    {  
        case 1,2,1: printf("Case 1 is executed");  
        break;  //error flagged at first comma, and all comma after in case
        case 2,3,1: printf("Case 2 is executed");  
        break;  
        default : printf("Default case is executed");  
    }  
    return 0;  
}  

而且,即使像这样修改,你也应该得到重复的标签错误:

#include <ansi_c.h>
int main(void){  
    int x = 2;  
    switch(x)
    {  
        case 1:
        case 2:
        case 1: printf("Case 1 is executed"); //duplicate label 1 error. (and others below) 
            break;  
        case 2:
        case 3:
        case 1: printf("Case 2 is executed");  
            break;

        default : printf("Default case is executed");  
    }
    return 0;  
}

此示例 完全合法(C99,C11)且非常有用:即,没有重复的标签,并且语法符合通过堆叠唯一标签来处理case 1: OR case 2: OR case 3:应以相同方式处理的条件(在同一块中),从而纠正交换机使用情况。当然,对于案例4,5和6也是如此。

#include <ansi_c.h>
int main(void){  
    int x = 2;  
    switch(x)
    {  
        case 1:
        case 2:
        case 3: printf("Case 1,2 or 3 is executed"); //duplicate label 1 error. (and others below) 
            break;  
        case 4:
        case 5:
        case 6: printf("Case 4,5 or 6 is executed");  
            break;
    }
    getchar();
    return 0;  
}

最后一个示例 仅用于完整性。它说明了case range表达式。虽然在C程序员中引起了兴趣,但 还不是C99或C11 的一部分,而是 Sun (a flavor of unix) 的扩展 GNU C compiler (等)

...
    switch(x)
    {  
            case 'a' ... 'z':  //note: spaces between all characters ('a') and ellipses are required
                    printf("lowercase alpha char detected");
                    break;
            case 'A' ... 'B':
                    printf("uppercase alpha char detected");
                    break;

            default: printf("Default case is executed");  
    }
...

从一个编译器到另一个编译器的模糊结果的原因 可能是Turbo C真的真的旧。您使用的版本可能是针对不再是最新的C标准版本实施的。

考虑 更改为当前编译器。一种便宜(免费)的替代方案是 MinGW 。 MinGW是一个维护良好的开源编译器。如果您喜欢使用集成开发环境(IDE), Code::Blocks 是一个选项,也是免费的,并且作为选项与MinGW捆绑在一起。

关于兼容性 ,请在此链接中搜索 Comparison to Other Compiler Suites 以阅读有关MinGW扩展的信息。 MinGW扩展虽然扩展了功能,但有时会使用它们编写的代码与其他当前编译器不兼容。建议在使用时小心谨慎。

答案 2 :(得分:1)

Turbo C在开关案例中使用逗号运算符并取最后一个值,例如案例1,2,3:将编译为案例3:案例2,3,1作为案例1:因此Turbo C不会给你任何错误。其他编译器不允许你使用案例1,2,3:声明本身。

但是在你的情况下,甚至Turbo c都会给出错误,因为case语句是这样的 案例1,2,1:和案例3,2,1:将被视为案例1:和案例1:因此根据案例规则,您只能有1个案例值,而您不能重复案例

我更喜欢使用gcc编译器而不是Turbo C

答案 3 :(得分:0)

  

是否是编译器错误。

这会导致编译错误(不知道 TURBO C ++ ,但在现代编译器中)。
这不是switch语句的工作方式(c / c ++中的语法无效)。您无法在case语句中重复使用switch值(请参阅link给出的chris)您可以这样做的方式;

 switch(x){
            case 1: case 2: case 3: printf("Case 1 is executed");
            break;
            default : printf("Default case us execyted"); 
          }

答案 4 :(得分:0)

您不能使用两次相同的“案例”值
这不正确:case 1: case 2: case 1: printf("Case 1 is executed");
试图在VS2010上编译=&gt; (错误C2196:已使用案例值'1')

答案 5 :(得分:0)

仅供参考,今天人们可以在适当的时候(通常不会)使用GCC case ranges extension来获得类似的结果(只支持范围,而不是任意的值列表)。

case 1 ... 5:
case 'A' ... 'Z':