开关盒中的逗号

comma in switch case

我对输入和输出感到困惑,谁能告诉我为什么会得到这样的输出。

#include<iostream>
#include<stdlib.h>
using namespace std;

int main()
{
    int ival, oddcnt(0), evencnt(0);
    while (cin >> ival) {
        switch (ival) {
        case 1, 3, 5, 7, 9:
            oddcnt++;
            break;
        case 2, 4, 6, 8, 10:
            evencnt++;
            break;
        }
    }
    cout << "Quantity of odd number:" << oddcnt << "\n"
        << "Quantity of even number:" << evencnt << endl;
    system("pause");
    return 0;
}

这是我得到的结果: Input:1 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 6 6 6 7 7 7 7 8 8 9 9 10 10 10 结束符 Output:Quantity 的奇数 number:2 偶数 number:3

switch (var) {
    case value1: /* ... */ break;
    case value2: /* ... */ break;
    /* ... */
}

case 标签中使用逗号在标准 C++ 中是非法的。这在语法上是不正确的。符合标准的编译器必须发出诊断消息以响应此代码,即使它以某种方式接受它也是如此。

可能(或可能不)涉及一些复杂的细节。

  • 在原始的 C++98 语言中,逗号运算符被禁止在 case 标签中使用。根据语言规范的两个不同部分 "blocked":

    首先,constant-expression 的语法不允许在常量表达式中使用顶级逗号运算符。从语法上讲,逗号运算符只能出现在包含在 ().

    中的常量表达式中

    其次,C++98 规范明确禁止常量表达式中嵌套任何级别的逗号运算符()(参见 5.19/1)。

    (这与C语言要求基本相同。)

  • 然而,C++11 做了一些改变:它 allowed comma operator in constant expressions。然而,语法保持不变。这意味着现在允许在常量表达式中使用逗号运算符,但仅限于包含在 () 中时。例如。从 C++11 开始你可以使用

    case (1, 3, 5, 7, 9):
    

    这是逗号运算符的普通应用。它使整个事情等同于

    case 9:
    

与此同时,您的

    case 1, 3, 5, 7, 9:

至今在 C++ 中仍然是非法的。如果您的编译器以某种方式支持它,那么它必须是您的编译器实现的语言扩展。请查阅您的编译器文档以了解其含义。

根据您获得的输出判断,您的编译器认为 case 1, 3, 5, 7, 9: 等同于 case (1, 3, 5, 7, 9):,因此等同于 case 9:。这解释了输出。该程序简单地计算输入中的 9s 和 10s。您有两个 9 和三个 10

另请参阅:
Is the comma operator allowed in a constant-expression in C++11?
Why was the restriction on the comma operator being in a constant expression removed in C++11?

您可以在开关内试试这个:

switch (ival) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 9:
     oddcnt++;
     break;

    case 2:
    case 4:
    case 6:
    case 8:
    case 10:
     evencnt++;
     break;
}
 switch (ival) {
        case 1, 3, 5, 7, 9:
            oddcnt++;
            break;
        case 2, 4, 6, 8, 10:
            evencnt++;
            break;
        }

案例 1、3、5、7、9: 这种类型的 switch 语句会导致语法错误,但在您的情况下不会。

语法错误(编译器 gcc 版本 5.4.0 (GCC)):

error: expected ‘:’ before ‘,’ token  
       case 1, 3, 5, 7, 9:
             ^
error: expected ‘:’ before ‘,’ token
     case 2, 4, 6, 8, 10:
           ^
error: expected primary-expression before ‘,’ token

尽管如此,您可以尝试以下转换案例:

switch (ival) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 9:
            oddcnt++;
            break;
        case 2:
        case 4:
        case 6:
        case 8:
        case 10:
            evencnt++;
            break;
        }