这是我的代码:
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;
}
编译器抱怨:
error C2051: case expression not constant
error C2051: case expression not constant
error C2051: case expression not constant
error C2051: case expression not constant
在我的头文件中,我有:
protected:
char up_key;
char down_key;
char right_key;
char left_key;
我正在使用Visual C++ 2008。
答案 0 :(得分:15)
如错误消息所述,case表达式必须是常量。编译器在编译时将其构建为一个非常快速的查找表,如果程序运行时值可能会发生变化,则无法执行此操作。
如果你确实需要它们是变量而不是常数,那么你最好的选择是使用if / else语句。
答案 1 :(得分:7)
替换这个长笨拙的代码,
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;
}
有这样的事情:
move( (c==right_key) - (c==left_key) , (c==down_key) - (c==up_key) );
你可以用更简洁的单行代码来代替那17行长的代码。
答案 2 :(得分:1)
你不能因为语言不能这样做。例如,如果up_key
,down_key
,right_key
和left_key
都相同,会发生什么?
答案 3 :(得分:1)
因为switch
语句只能使用常量,所以在读取代码时,你知道你所比较的东西都是常量。另一方面,您可以使用if
语句(或其他一些结构)来比较变量:
if (c == up_key) {
move(0, -1);
} else if (c == down_key) {
move(0, 1);
} else ...
这提供了明显的结构差异,可以极大地帮助那些在您阅读代码之后的人。想象一下,如果你必须查找每个case
标签,看看它是否是一个变量?
答案 4 :(得分:1)
我相信这是因为编译器会生成一个跳转表,其中的值是硬编码的,尽管我可能错了。生成表的方式不允许。
答案 5 :(得分:1)
由于其他答案已经涵盖了您收到错误的原因,因此可以采用四种方向之一移动以响应按键:使用查找表而不是条件/开关。
设置部分:
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);
功能:
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;
}
}
答案 6 :(得分:0)
//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 Samuel_Ni@yahoo.com
#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;
}