如何在switch语句中选择一系列值?

Rob*_*eck 20 c++ switch-statement

当我尝试编译时,我收到此错误:

1>------ Build started: Project: snake, Configuration: Debug Win32 ------
1>  exercise.cpp
1>c:\users\robin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(13): error C2059: syntax error : '>='
1>c:\users\robin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(16): error C2059: syntax error : '>='
1>c:\users\robin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(19): error C2059: syntax error : '>='
1>c:\users\robin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(22): error C2059: syntax error : '>='
1>c:\users\robin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(25): error C2059: syntax error : '>'
1>c:\users\robin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(28): error C2059: syntax error : '=='
1>c:\users\robin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(34): warning C4065: switch statement contains 'default' but no 'case' labels
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

码:

#include <iostream>
using namespace std;

int main(){
    int score;

    //Vraag de score
    cout << "Score:";
    cin >> score;

    //Switch
    switch(score){
        case >= 100:
            cout << "a";
            break;
        case >= 50:
            cout << "b";
            break;
        case >= 25:
            cout << "c";
            break;
        case >= 10:
            cout << "d";
            break;
        case > 0:
            cout << "e";
            break;
        case == 0:
            cout << "f";
            break;
        default:
            cout << "BAD VALUE";
            break;
    }
    cout << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?它是一个控制台应用程序,Win32和我的IDE是Windows Enterprise C++ 2010.

我正在通过游戏编程学习初学C++.

小智 50

一些编译器支持案例范围,例如case x ... y作为C++语言的扩展.

例:

#include <iostream>
using namespace std;

int main(){
    int score;

    //Vraag de score
    cout << "Score:";
    cin >> score;

    //Switch
    switch(score){
       case 0:
            cout << "a";
            break;
       case 0 ... 9:
            cout << "b";
            break;
       case 11 ... 24:
            cout << "c";
            break;
       case 25 ... 49:
            cout << "d";
            break;
       case 50 ... 100:
            cout << "e";
            break;         
        default:
            cout << "BAD VALUE";
            break;
    }
    cout << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

GCC 4.9,Clang 3.5.1和Intel C/C++ Compiler 13.0.1似乎支持它(在http://gcc.godbolt.org/上试过).另一方面,Visual C++ 19没有(在http://webcompiler.cloudapp.net/上试过).

  • 请注意,这是GCC扩展(https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Case-Ranges.html#Case-Ranges)*不是*C++ 11的事情! (6认同)
  • 另请注意,GCC 至少需要 ... 周围有空格,而在 C++ 中大多数情况下并非如此。 (3认同)

das*_*ght 25

在C++中,标签是常量表达式,而不是通常的表达式.你需要一系列if-then-else语句来做你想做的事情.

或者,您可以枚举开关中的值.这种情况稍微快一点(尽管在像你这样的情况下并不重要),但它的可读性要低得多:

switch(score) {
    case 0: cout << "f"; break;
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10: cout << "e"; break;
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
    case 18:
    case 19:
    case 20:
    case 21:
    case 22:
    case 23:
    case 24:
    case 25: cout << "c"; break;
    // ...and so on, you get the idea...

}
Run Code Online (Sandbox Code Playgroud)

  • 该方法虽然有效,但不是特别可扩展的解决方案(考虑更大的范围或浮点值),并且还容易出现人为错误. (7认同)
  • @mah mah,你是对的.我提到了可读性,但可伸缩性是另一个重要问题.只有101个条目就可以了,但是一旦你进入数百个,这种方法就变得不实用了.对FP来说,`switch`甚至不是一个选择. (2认同)

mah*_*mah 18

您可以使用一系列if/ else if语句来解决此问题.在C++中不能像这样使用Switch/case.


Sla*_*ica 9

它可以用做std::mapswitch:

enum Interval {
   One,
   Two,
   Three,
   NotFound };

// [0,10[ is One, [10,30[ is Two, [30,55[ is Three
std::map<int,Interval> imap { 
    { { 0, One }, 
      { 10, Two },
      { 30, Three },
      { 55, NotFound } };
Interval ivalue = NotFound;
auto f = imap.lower_bound( value );
if( f != imap.end() ) ivalue = f->second;
switch( ivalue ) {
    case One : ...
    case Two : ...
    case Three : ...
    default: ...
}
Run Code Online (Sandbox Code Playgroud)

  • 对于简单的范围检查来说,这似乎有点过头了。 (3认同)

BoB*_*ish 5

在C++中,switch语句只能匹配常量整数值:

switch (i)
{
    case 1:
    //... stuff
    break;
    case 2:
    //... stuff
    break;
    default:
    //... stuff
}
Run Code Online (Sandbox Code Playgroud)


Seb*_*ach 5

该标准不允许这样做:

6.4.2 switch 语句[stmt.switch]

[...] switch 语句中的任何语句都可以使用一个或多个 case 标签进行标记,如下所示:

case constant-expression :

其中常量表达式应为整型常量表达式 (5.19)。

换句话说,您只能使用扩展为单个整数“硬”编译时间常量的 case-values(例如case 5+6:, enum {X = 3}; ... case X*X:)。

解决这个问题的方法是使用if- 语句。例如,替换

switch (x)
case 0..100:
Run Code Online (Sandbox Code Playgroud)

你会改为

if (x>=0 && x<=100)
Run Code Online (Sandbox Code Playgroud)


Jan*_*sen 5

有一个GCC扩展,完全符合你的要求.


Fif*_*ifi 5

Switch-case对于测试范围不是一个很好的选择。最好的选择是使用几个if

if (score<0) cout << "BAD VALUE";
if (score == 0)  cout << "f";
if (score>0 && score<10) cout << "e";
if (score>=10 && score <25) cout << "d";
if (score>=25 && score <50) cout << "c";
if (score>=50 && score <100) cout << "b";
Run Code Online (Sandbox Code Playgroud)

如果运行时间是一个问题,则以下解决方案会更快:

if (score == 0)  cout << "f";
else if (score<10) cout << "e";
else if (score <25) cout << "d";
else if (score <50) cout << "c";
else if (score <100) cout << "b";
else if (score>=100) cout << "a";
else cout << "BAD VALUE";
Run Code Online (Sandbox Code Playgroud)