C++ 为什么我不能在 switch-case 语句中有一个变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8920872/
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-28 19:20:21  来源:igfitidea点击:

Why can't I have a variable in switch-case statement?

c++switch-statement

提问by infinitloop

Here is my code:

这是我的代码:

bool Character::keyPress(char c)
{
    switch(c)
    {
        case up_key:
            move(0, -1);
            break;

        case down_key:
            move(0, 1);
            break;

        case left_key:
            move(-1, 0);
            break;

        case right_key:
            move(1,0);
            break;

        default:
            return false;
    }

    return true;
}

And the compiler complains:

编译器抱怨:

error C2051: case expression not constant
error C2051: case expression not constant
error C2051: case expression not constant
error C2051: case expression not constant

In my header file I have:

在我的头文件中,我有:

protected:
    char up_key;
    char down_key;
    char right_key;
    char left_key;

I am using Visual C++2008.

我正在使用Visual C++2008。

回答by Janne

As the error message states, the case expressions must be constant. The compiler builds this as a very fast look-up table at compile time and it can't do that if there is a possibility that the values could change as the program runs.

正如错误消息所述,case 表达式必须是常量。编译器在编译时将其构建为一个非常快速的查找表,如果在程序运行时值可能会发生变化,它就不能这样做。

If you do need them to be variable, not constant, your best bet is to use if/else statements instead.

如果您确实需要它们是可变的,而不是恒定的,那么最好的办法是使用 if/else 语句。

回答by user3080666

Replace this long clumsy code,

替换掉这个冗长笨拙的代码,

switch(c)
{
    case up_key:
        move(0, -1);
        break;

    case down_key:
        move(0, 1);
        break;

    case left_key:
        move(-1, 0);
        break;

    case right_key:
        move(1,0);
        break;

    default:
        return false;
}

with something like this:

像这样:

move( (c==right_key) - (c==left_key) , (c==down_key) - (c==up_key) );

You can litterly replace that 17 lines long of code with that much more neat single line of code.

您可以用更整洁的单行代码替换那 17 行长的代码。

回答by MSN

You can't because the language doesn't work that way. For example, what would happen if up_key, down_key, right_key, and left_keywere all equal?

你不能,因为语言不能那样工作。例如,会发生什么,如果up_keydown_keyright_key,和left_key都是平等的吗?

回答by Greg Hewgill

Because the switchstatement can take only constants, you know when reading the code that the things you're comparing against are all constants. On the other hand, you would use ifstatements (or some other structure) to compare against variables:

因为该switch语句只能接受常量,所以在阅读代码时,您知道要比较的对象都是常量。另一方面,您将使用if语句(或某些其他结构)与变量进行比较:

if (c == up_key) {
    move(0, -1);
} else if (c == down_key) {
    move(0, 1);
} else ...

This provides a distinct difference in structure which can greatly aid those who come after you in reading your code. Imagine if you had to look up every caselabel to see whether it was a variable or not?

这提供了明显的结构差异,可以极大地帮助那些跟随您阅读代码的人。想象一下,如果您必须查找每个case标签以查看它是否是变量?

回答by dymk

I believe it's because the compiler generates a jump table, with the values hardcoded in, although I may be wrong. The way the tables are generated just doesn't allow for it.

我相信这是因为编译器生成了一个跳转表,其中包含硬编码的值,尽管我可能是错的。表格的生成方式不允许这样做。

回答by dasblinkenlight

Since other answers have covered why you are getting an error, here is a way to move in one of the four directions in response to a key press: use lookup tables instead of the conditionals/switches.

由于其他答案已经涵盖了您收到错误的原因,因此有一种方法可以响应按键按四个方向之一移动:使用查找表而不是条件/开关。

Setup portion:

设置部分:

std::map<char,pair<int,int> > moves;
moves[up_key] = make_pair(0, -1);
moves[down_key] = make_pair(0, 1);
moves[left_key] = make_pair(-1, 0);
moves[right_key] = make_pair(1, 0);

The function:

功能:

bool Character::keyPress(char c) {
    if (moves.count(c)) {
        pair<int,int> dir = moves[c];
        move(dir.first, dir.second);
        return true;
    } else {
        return false;
    }
}

回答by Samuel Ni

//here is the full functional code snippet which can be compiled and run with most of C++  
//compiler/link ...console app was demoed but you can apply the code/logic to win32 app...
//if you have any problem, send me email to [email protected]

#include <iostream.h>
#include <map>
#include <conio.h>

class CkbdHanler{
  private:
    map<char,pair<int,int> > moves;
  protected:
    char up_key;
    char down_key;
    char right_key;
    char left_key;
  public:

CkbdHanler(char a,char b,char c,char d):up_key(a),
                                        down_key(b),
                                       right_key(c),
                                       left_key(d)
{
    moves[up_key] = make_pair(0, -1);
    moves[down_key] = make_pair(0, 1);
    moves[left_key] = make_pair(-1, 0);
    moves[right_key] = make_pair(1, 0);
 }

bool keyPress(char c){
    if (moves.count(c)) {
            pair<int,int> dir = moves[c];
            move(dir.first, dir.second);
            return true;
   } else return false;

}
void move(int i,int j){
   cout<<"(i,j)=("<<i<<","<<j<<")"<<endl;
  }
};

int main(int argc, char* argv[])
{
  CkbdHanler CmyKbdH('u','d','l','r');

  cout << "Hello C++... here is a demo of Map to replace switch-case" << endl;
  CmyKbdH.keyPress('d');
  cout << endl << "Press any key to continue...";

  getch();
  return 0;
}