关于c ++:逗号运算符在switch语句中的含义是什么?

What does comma operator mean in a switch statement?

有人问我一个问题,要求我给出结果。

1
2
3
4
5
6
7
8
9
10
11
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中以"case 1 is executed"的形式给出输出,但在代码块和在线编译上,它给出了一个编译器错误。

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


is it a compiler error or not.

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

即使允许您在这里使用逗号运算符,switch语句仍然无效,因为两种情况的值都相同,1。

And if not why does the code run only on turbo C.

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


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

编辑日志(显示case range示例)

前两个示例(包括原始代码)显示不正确的switch语句语法(带解释)。第三个代码示例显示了如何正确地堆叠案例标签:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
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;  
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include
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也是如此。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include
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(一种风格的UNIX)和GNU C编译器(等)的扩展:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
    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),代码::块是一个选项,也是免费的,而且作为一个选项,它与mingw捆绑在一起。

关于兼容性,请搜索与此链接中其他编译器套件的比较,以了解mingw扩展。mingw扩展在扩展功能的同时,有时会使使用它们编写的代码与其他当前编译器不可移植。建议使用时小心。


turbo c在开关案例中使用逗号运算符,并取最后一个值,例如案例1、2、3:将编译为案例3:案例2、3、1将编译为案例1:因此turbo c不会给出任何错误。其中,与其他编译器一样,CASE 1、2、3不允许使用语句本身。

但在你的案例中,即使是turbo C也会出错,因为案例陈述是这样的案例1、2、1:和案例3、2、1:将符合案例1:和案例1:因此,根据开关案例规则,只有一个案例具有值,不能重复案例

我更喜欢使用gcc编译器,而不是turbo c


仅供参考,今天我们可以在类似结果(仅支持范围,不支持任意值列表)适用时使用GCC案例范围扩展。

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

不能使用相同"case"值的两倍这是不正确的:case 1: case 2: case 1: printf("Case 1 is executed");。尝试在vs2010=>上编译(错误C2196:已使用事例值"1")。


is it a compiler error or not.

它会导致编译错误(不知道Turbo C++,但在现代编译器中)。这不是开关语句工作的方式(C/C++中的无效语法)。您不能以这样的方式重用switch语句中的case值(请参见chris给出的链接);

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