简体   繁体   English

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

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

I was given a question and was asked to give the output.我被问到一个问题,并被要求提供输出。

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;  
}

The above code gives output as "Case 1 is executed" in Turbo C, But on codeblocks and compile online, it gives a compiler error.上面的代码在 Turbo C 中给出了“Case 1 is execution”的输出,但是在代码块和在线编译上,它给出了一个编译器错误。

Which one is correct?哪一个是正确的? Is it a compiler error or not?是否是编译器错误? And if not, why does the code run only on Turbo C?如果不是,为什么代码只能在 Turbo C 上运行?

is it a compiler error or not.是否是编译器错误。

The code is invalid in both languages: the case expression must be a constant expression, and a constant expression can't contain a comma operator.代码在两种语言中都无效: case表达式必须是常量表达式,常量表达式不能包含逗号运算符。 (In C, this is stated explicitly; in C++, you have to unpick the grammar to find that a constant-expression must be a conditional-expression , which can't contain a comma). (在 C 中,这是明确说明的;在 C++ 中,您必须取消选择语法才能发现常量表达式必须是条件表达式,它不能包含逗号)。

Even if you were allowed to use the comma operator here, the switch statement would still be invalid since two cases would both have the same value, 1.即使您被允许在此处使用逗号运算符, switch语句仍然无效,因为两个 case 都具有相同的值 1。

And if not why does the code run only on turbo C.如果不是,为什么代码只在 Turbo C 上运行。

Because both languages have changed significantly since that prehistoric compiler was last updated.因为自从上次更新史前编译器以来,这两种语言都发生了重大变化。 Don't use it if you want to learn variants of C or C++ from this century.如果您想从本世纪学习 C 或 C++ 的变体,请不要使用它。

What does comma operator mean in a switch statement? switch 语句中的逗号运算符是什么意思?
It means you have an old compiler.这意味着你有一个旧的编译器。

Edit post (to show case range example)编辑帖子(以显示case range示例)

The first two examples (including your original code ) exhibit incorrect switch statement syntax (with explanations).前两个示例(包括您的原始代码)表现出不正确的 switch 语句语法(带有解释)。 The third code example shows how stacking case labels is done correctly:第三个代码示例显示了如何正确完成堆叠案例标签:

In your code, the compiler should have flagged the first comma after case 1, <-- here在您的代码中,编译器应该在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;  
}  

And, even modified like this you should also get a duplicate label error:而且,即使这样修改,你也应该得到一个重复的标签错误:

#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;  
}

This example is perfectly legal (C99, C11) and useful: ie, there are no duplicate labels, and the syntax complies with correct switch usage by stacking unique labels to handle conditions where case 1: OR case 2: OR case 3: should be handled the same way, (in the same block).这个例子是完全合法的(C99, C11)和有用的:即,没有重复的标签,并且语法符合正确的开关用法,通过堆叠唯一标签来处理case 1: OR case 2: OR case 3:应该是以相同的方式处理,(在同一个块中)。 And of course the same is true for cases 4, 5 and 6.当然,情况 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;  
}

This last example is included just for completeness.包含最后一个示例只是为了完整性。 It illustrates the case range expression.它说明了case range表达式。 Although gaining interest among C programmers, it is not yet part of C99 or C11, rather an extension of Sun (a flavor of unix) and GNU C compiler (et al) :尽管在 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");  
    }
...

The reason for the ambiguous results you are seeing from one compiler to another may be that Turbo C is really really old.从一个编译器到另一个编译器看到的结果不明确的原因可能是 Turbo C 真的老。 The version you are using was likely implemented against a version of the C standards that is no longer current.您正在使用的版本可能是针对不再是最新的 C 标准版本实现的。

Consider changing to a current compiler.考虑更改为当前编译器。 An inexpensive (free) alternative is MinGW .一个便宜(免费)的替代品是MinGW MinGW is a very well maintained, open source compiler. MinGW 是一个维护良好的开源编译器。 If you like using Integrated Development Environments (IDE), Code::Blocks is one option, also free, and as an option comes bundled with MinGW.如果您喜欢使用集成开发环境 (IDE), Code::Blocks是一个选项,也是免费的,并且作为选项与 MinGW 捆绑在一起。

Regarding compatibility, search for Comparison to Other Compiler Suites in this link to read about MinGW extensions.关于兼容性,请在此链接中搜索与其他编译器套件的比较以阅读有关 MinGW 扩展的信息。 MinGW extensions, while expanding capabilities, sometimes make code written using them non-portable with other current compilers. MinGW 扩展在扩展功能的同时,有时会使使用它们编写的代码与其他当前编译器不可移植。 Recommend using caution when using them.建议使用时小心谨慎。

Turbo C uses comma operator on switch cases and takes the last value, for example case 1, 2, 3: will be compiled as case 3: case 2, 3, 1 as case 1: hence Turbo C will not give you any error. Turbo C 在 switch case 上使用逗号运算符并取最后一个值,例如 case 1, 2, 3: 将被编译为 case 3: case 2, 3, 1 as case 1: 因此 Turbo C 不会给你任何错误。 Where as other compilers will not allow you case 1, 2, 3: kind of statement itself.其他编译器不允许你使用 case 1, 2, 3: 这种语句本身。

But in your case even Turbo c will give error because case statements are something like this case 1, 2, 1: and case 3, 2, 1: which will be complied as case 1: and case 1: hence as per switch case rules you can have only 1 case with a value and you cannot repeat the case但是在您的情况下,即使 Turbo c 也会出错,因为 case 语句类似于 case 1, 2, 1: 和 case 3, 2, 1: 将作为 case 1: 和 case 1: 因此根据 switch case 规则您只能有 1 个带有值的案例,并且您不能重复该案例

I prefer to use gcc compiler rather Turbo C我更喜欢使用 gcc 编译器而不是 Turbo C

is it a compiler error or not.是否是编译器错误。

It will cause a compilation error (don't know about TURBO C++ but in modern compilers).它会导致编译错误(不知道TURBO C++但在现代编译器中)。
This is not the way switch statement works (invalid syntax in c/c++).这不是 switch 语句的工作方式(c/c++ 中的语法无效)。 You cannot reuse a case value in switch statement (see the link given by chris ) The way you can do this;您不能在switch语句中重用case值(请参阅chris给出的链接)您可以这样做的方式;

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

You can not use twice the same 'case' value您不能使用两次相同的“案例”值
This is not correct: case 1: case 2: case 1: printf("Case 1 is executed");这是不正确的: case 1: case 2: case 1: printf("Case 1 is executed");
Tried to compile on VS2010 => (error C2196: case value '1' already used)尝试在 VS2010 上编译 =>(错误 C2196:case value '1' already used)

FYI, today one may use the GCC case ranges extension when it is appropriate (which is not often) for similar results (only ranges are supported, not arbitrary lists of values).仅供参考,今天可以使用GCC 案例范围扩展,当它适合(不经常)类似的结果时(仅支持范围,而不是任意的值列表)。

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

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

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