如何在switch语句中select一系列值?
当我尝试编译时,我得到这个错误:
1> ------ Build开始: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语句包含'default'但没有'case'标签 ==========构build:0成功,1失败,0最新,0跳过==========
码:
#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; }
我该如何解决这个问题? 这是一个控制台应用程序,Win32和我的IDE是Windows Enterprise C ++ 2010。
我正在从Beginning C ++通过游戏编程学习。
在C ++情况下,标签是常量expression式,通常不是expression式。 你需要一系列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... }
一些编译器支持case 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; }
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/上试过)。;
您可以通过使用一系列if
/ else if
语句来解决此问题。 在C ++中,开关/shell不能像这样使用。
它可以使用switch
std::map
来完成:
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: ... }
有一个海湾合作委员会的扩展 ,正是你想要的。
在C ++中,switch语句只能匹配常量整数值:
switch (i) { case 1: //... stuff break; case 2: //... stuff break; default: //... stuff }
标准不允许这样做:
6.4.2 switch语句[stmt.switch]
[…] switch语句中的任何语句都可以使用一个或多个case标签进行标记,如下所示:
case constant-expression :
常数expression式应该是一个积分常数expression式(5.19)。
换句话说,只能使用扩展为单一的,整体的“硬”编译时间常量的case-values(例如case 5+6:
, enum {X = 3}; ... case X*X:
。
解决这个问题的方法是使用if
语句。 例如,要更换
switch (x) case 0..100:
你会代替
if (x>=0 && x<=100)
。
这根本不是如何开关工作。 它只需要单个值。 你将不得不使用if-elseif块
我有一个基于分数的问题相同的问题,而“if / elseif”语句很好用,间隔我发现最好的select(对我来说,至less因为我喜欢它看起来像它更容易作为初学者看我的错误)是“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;} }
std::map::lower_bound
+ C ++ 11 lambda
https://stackoverflow.com/a/35460297/895245提到;lower_bound
,但我们也可以摆脱那里的lambda(或inheritance,如果你没有它)的enum
。
#include <functional> #include <iostream> #include <map> int main() { for (auto i = -1; i < 8; ++i) { std::cout << i << std::endl; auto m = std::map<int,std::function<void()>> { {0, [](){ std::cout << "too small" << std::endl;}}, {2, [](){ std::cout << "[0,2)" << std::endl;}}, {5, [](){ std::cout << "[2,5)" << std::endl;}}, {7, [](){ std::cout << "[5,7)" << std::endl;}}, }; auto it = m.upper_bound(i); if (it == m.end()) { std::cout << "too large" << std::endl; } else { it->second(); } std::cout << std::endl; } }
输出:
-1 too small 0 [0,2) 1 [0,2) 2 [2,5) 3 [2,5) 4 [2,5) 5 [5,7) 6 [5,7) 7 too large
switch case语句是一个替代long if语句,用于将variables与几个“整数”值进行比较(“整数”值只是可以表示为整数的值,例如char的值)。 switch语句的条件是一个值。 这个案子说,如果它有这个案子后的任何东西的价值,那么做任何冒号后面的事情。 rest是用来打破案件陈述。
因此,您不能在这种情况下使用这样的条件语句。
select性结构:开关
这是为我工作。 将标记除以10,然后设置shell10和9以显示“A”(这将在90-100之间显示“A”,然后情况8显示“B”,然后情况7将显示“ C“的值为70-79等等。
#include <iostream> using namespace std; main () { int mark; cout << "enter your mark: "; cin >> mark; switch (mark/10) { case 10: case 9: cout << "A"; break; case 8: cout << "B"; break; case 7: cout << "C"; break; case 6: cout << "D"; break; case 5: cout << "PASS"; break; default: cout << "FAIL"; break; } }
您可以执行以下操作:
//summarize the range to one value If score < 0 score = -1 switch(score){ case 1: //... break; case 2: //... break; case -1: //complete neg. range //... break; //...
}
一个潜在的有用的见解是, switch
接受一个expression式,所以你可以折叠多个input值到一个开关的情况下。 这是一个很大的丑陋,但要考虑:
switch (score / 10) { case 10: cout << "a"; break; case 9: case 8: case 7: case 6: case 5: cout << "b"; break; case 4: case 3: cout << "c"; break; case 2: if (score >= 25) { cout << "c"; break; } // else fall through... case 1: cout << "d"; break; case 0: cout << (score > 0 ? "e" : "f"); break; default: cout << "BAD VALUE"; break; }
当然,你可以除以5,并有case 4:
20-24)与case 5:
(25-29),而不是if
case 2:
:,但/10
可以说是更直观。
我知道这是一个古老的questiion,但由于switch
语句实际上是标签周围的包装,我发现goto
可能是(良好)使用在这里。
int value = 40; if (value < 10) { std::cout << "value < 10" << std::endl; goto end; } if (value < 50) { std::cout << "value < 50" << std::endl; goto end; } if (value > 30) { std::cout << "value > 30" << std::endl; goto end; } end: // resume
这样,你可以省略else
所有的else
并保持紧凑。 虽然(一般)使用goto
时,你应该小心。
像这样的东西?
case 'A'..'Z' where a not in ['I','L','O']:
不幸的是没有编译器,我知道实现特定的扩展,虽然GCC有可以做其他答案指出范围。 为便于携带,您可以剪切并粘贴此DWTFYW许可代码段。 如果您使用自定义枚举,则可能会使用代码生成来做类似的事情。
#define CASE_NUMBER \ case'0':case'1':case'2':case'3':case'4':\ case'5':case'6':case'7':case'8':case'9' #define CASE_ALPHA_LOWER \ case'a':case'b':case'c':case'd':\ case'e':case'f':case'g':case'h':\ case'i':case'j':case'k':case'l':\ case'm':case'n':case'o':case'p':\ case'q':case'r':case's':case't':\ case'u':case'v':case'w':case'x':\ case'y':case'z' #define CASE_ALPHA_UPPER \ case'A':case'B':case'C':case'D':\ case'E':case'F':case'G':case'H':\ case'I':case'J':case'K':case'L':\ case'M':case'N':case'O':case'P':\ case'Q':case'R':case'S':case'T':\ case'U':case'V':case'W':case'X':\ case'Y':case'Z' #define CASE_ALPHA CASE_ALPHA_UPPER:CASE_ALPHA_LOWER #define CASE_ALPHANUM CASE_ALPHA:CASE_NUMBER
如果您访问GHCI,例如https://ghc.io/的在线版本,您可能只需生成所需内容并将其粘贴到标题中;
foldl (++) "" ["case" ++ show x ++ ":" | x <- ['A'..'Z'], not $ x `elem` ['I','L','O']]
这是我希望expression和简单的方法。
gcc / clang等可以优化它生成的代码,你可能会感到惊讶。 我希望它至less和交换机/机箱一样高效。
#include <iostream> template<class Value> struct switcher { constexpr switcher(Value const& value) : value_(value) {} constexpr switcher(Value const& value, bool enabled) : value_(value), enabled(enabled) {} template<class From, class To, class F> constexpr auto in_range(From&& from, To&& to, F&& f) { if (enabled and (from <= value_ and value_ <= to)) { f(); return switcher(value_, false); } else { return *this; } }; template<class F> constexpr auto otherwise(F&& f) { if (enabled) f(); } Value const& value_; const bool enabled = true; }; template<class Value> constexpr auto decision(Value const& value) { return switcher<Value>(value); } void test(int x) { decision(x) .in_range(0, 10, [&] { std::cout << x << " maps to option A\n"; }) .in_range(11, 20, [&] { std::cout << x << " maps to option B\n"; }) .otherwise([&] { std::cout << x << " is not covered\n"; }); } int main(int argc, char **argv) { test(5); test(14); test(22); }