繁体   English   中英

switch 语句中的逗号运算符是什么意思?

[英]What does comma operator mean in a switch statement?

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

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 execution”的输出,但是在代码块和在线编译上,它给出了一个编译器错误。

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

是否是编译器错误。

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

即使您被允许在此处使用逗号运算符, switch语句仍然无效,因为两个 case 都具有相同的值 1。

如果不是,为什么代码只在 Turbo C 上运行。

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

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(一种 unix 风格)GNU C 编译器(等)的扩展:

...
    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 捆绑在一起。

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

Turbo C 在 switch case 上使用逗号运算符并取最后一个值,例如 case 1, 2, 3: 将被编译为 case 3: case 2, 3, 1 as case 1: 因此 Turbo C 不会给你任何错误。 其他编译器不允许你使用 case 1, 2, 3: 这种语句本身。

但是在您的情况下,即使 Turbo c 也会出错,因为 case 语句类似于 case 1, 2, 1: 和 case 3, 2, 1: 将作为 case 1: 和 case 1: 因此根据 switch case 规则您只能有 1 个带有值的案例,并且您不能重复该案例

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

是否是编译器错误。

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

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

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

仅供参考,今天可以使用GCC 案例范围扩展,当它适合(不经常)类似的结果时(仅支持范围,而不是任意的值列表)。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM