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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9432226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:49:28  来源:igfitidea点击:

How do I select a range of values in a switch statement?

c++switch-statement

提问by Robin Van den Broeck

When I try to compile I get this error:

当我尝试编译时,出现此错误:

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 ==========

Code:

代码:

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

How can I fix this problem? It's a console application, Win32 and my IDE is Windows Enterprise C++ 2010.

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

I'm learning from Beginning C++ Through Game Programming.

我正在从游戏编程开始学习C++

回答by Ankit Patel

Some compilers support case rangeslike case x ... yas an extensionto the C++ language.

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

Example:

例子:

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

GCC 4.9, Clang 3.5.1 and Intel C/C++ Compiler 13.0.1 seem to support it (tried on http://gcc.godbolt.org/). On the other hand, Visual C++ 19 doesn't (tried on http://webcompiler.cloudapp.net/).

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/ 上尝试过)。

回答by dasblinkenlight

In C++ case labels are constantexpressions, not expressions in general. You need a chain of if-then-else statements to do what you are trying to do.

在 C++ 情况下,标签是常量表达式,而不是一般的表达式。您需要一串 if-then-else 语句来完成您想要做的事情。

Alternatively, you can enumerate the values in the switch. This runs marginally faster (though it does not matter in cases like yours), but it is considerably less readable:

或者,您可以枚举开关中的值。这运行速度稍快(尽管在像您这样的情况下无关紧要),但可读性要低得多:

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...

}

回答by mah

You can fix this problem by using a series of if/else ifstatements. Switch/case cannot be used like this in C++.

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

回答by Slava

It can be done using a std::mapwith switch:

可以使用std::mapwith来完成switch

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: ...
}

回答by Fifi

Switch-caseis not a great option for testing ranges. The best option is to use several if:

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

If running time is an issue, the following solution is faster :

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

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

回答by BoBTFish

In C++ a switch statement can only match constant integer values:

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

switch (i)
{
    case 1:
    //... stuff
    break;
    case 2:
    //... stuff
    break;
    default:
    //... stuff
}

回答by Janus Troelsen

There's a GCC extensionthat does exactly what you want.

有一个GCC 扩展可以完全满足您的需求。

回答by Sebastian Mach

The standard does not allow for this:

该标准不允许这样做:

6.4.2 The switch statement [stmt.switch]

[...] Any statement within the switch statement can be labeled with one or more case labels as follows:

case constant-expression :

where the constant-expression shall be an integral constant expression (5.19).

6.4.2 switch 语句[stmt.switch]

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

case constant-expression :

其中,constant-expression 应为整数常量表达式 (5.19)。

In other words, you can only use case-values that expand into a single, integral, "hard" compile time constant (e.g. case 5+6:, enum {X = 3}; ... case X*X:).

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

The way around this is to use if-statements. E.g., to replace

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

switch (x)
case 0..100:

you'd instead

你反而

if (x>=0 && x<=100)

.

.

回答by Bubu

I had the same problem with a score based problem and while the " if/elseif "statements were good to use, for intervals i found that the best option (for me at least because i like how it looks and it's easier for me as a beginner to see my mistakes) is " 1 ... 10 ". but don't forget to use a space between the number and the dots or the program will think that your interval is a number and u will get an error "2 many decimal dots...". Hope it helps.

我在基于分数的问题上遇到了同样的问题,虽然“if/elseif”语句很好用,但对于间隔我发现这是最好的选择(至少对我来说是因为我喜欢它的外观,而且对我来说更容易初学者看到我的错误)是“ 1 ... 10 ”。但不要忘记在数字和点之间使用一个空格,否则程序会认为您的间隔是一个数字,你会得到一个错误“2 个小数点...”。希望能帮助到你。

int score;

int main()
{
    cout<<"Enter score"<<endl;
    cin>>score;

  switch(score){
    case 100:
        cout<<"Your score is Perfect"<<endl;
    break;
    case 90 ... 99:
        cout<<"You got A"<<endl;
    break;
    case 80 ... 89:
        cout<<"You got B"<<endl;
        break;
    case 70 ... 79:
        cout<<"You got C"<<endl;
        break;
    case 60 ... 69:
        cout<<"You got D"<<endl;
        break;
    case 50 ... 59:
        cout<<"You got E"<<endl;
        break;
    case 0 ... 49:
        cout<<"You got F"<<endl;}

  }

回答by KitsuneYMG

That's simply not how switch works. It only takes single values. You'll have to use if-elseif blocks

这根本不是 switch 的工作方式。它只需要单个值。你必须使用 if-elseif 块