How do I select a range of values in a switch statement?
当我试图编译时,我得到了这个错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 1>------ Build started: Project: snake, Configuration: Debug Win32 ------ 1> exercise.cpp 1>c:\users obin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(13): error C2059: syntax error : '>=' 1>c:\users obin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(16): error C2059: syntax error : '>=' 1>c:\users obin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(19): error C2059: syntax error : '>=' 1>c:\users obin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(22): error C2059: syntax error : '>=' 1>c:\users obin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(25): error C2059: syntax error : '>' 1>c:\users obin\documents\visual studio 2010\projects\snake\snake\exercise.cpp(28): error C2059: syntax error : '==' 1>c:\users obin\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 ========== |
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #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企业C++ 2010。
我从C++开始,通过游戏编程学习。
一些编译器支持ECDOX1(5)作为CA++语言的扩展。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #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、CLAN 3.5.1和英特尔C/C++编译器130.1似乎支持它(尝试在http://gcc.Gooth.org/)上。另一方面,VisualC++ 19没有(在http://WebCalpul.CyrdApp.NET/)上试用。
在C++中,标签是常量表达式,而不是一般表达式。你需要一系列if-then-else语句来完成你想要做的。
或者,可以枚举开关中的值。它运行得稍微快一点(尽管在像您这样的情况下并不重要),但可读性要差得多:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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... } |
您可以使用一系列
可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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++中,开关语句只能匹配常数整数值:
1 2 3 4 5 6 7 8 9 10 11 | switch (i) { case 1: //... stuff break; case 2: //... stuff break; default: //... stuff } |
有一个GCC扩展可以完全满足您的需要。
http:/ / / / / 895245 stackoverflow.com 35460297
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <functional> #include <iostream> #include <map> int main() { std::string ret; const std::map<int,std::function<void()>> m{ {0, [&](){ ret ="too small"; }}, {2, [&](){ ret ="[0,2)"; }}, {5, [&](){ ret ="[2,5)"; }}, {7, [&](){ ret ="[5,7)"; }}, }; const auto end = m.end(); for (auto i = -1; i < 8; ++i) { auto it = m.upper_bound(i); if (it == end) { ret ="too large"; } else { it->second(); } std::cout << i <<"" << ret << std::endl; } } |
输出:
1 2 3 4 5 6 7 8 9 | -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 |
使用方法:用
使用这种模式,在有效的映射类的初始化,staticallyλ,或其他支付每一次你
在这里,我们去,与
这是必要的转换到一个上下文捕获
输出的例子是在produces相同:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <functional> #include <iostream> #include <map> #include <string> class RangeSwitch { public: void method(int x, std::string &ret) { static const std::map<int,std::function<void(std::string&)>> m{ {0, [](std::string &ret){ ret ="too small"; }}, {2, [](std::string &ret){ ret ="[0,2)"; }}, {5, [](std::string &ret){ ret ="[2,5)"; }}, {7, [](std::string &ret){ ret ="[5,7)"; }}, }; static const auto end = m.end(); auto it = m.upper_bound(x); if (it == end) { ret ="too large"; } else { it->second(ret); } } }; int main() { RangeSwitch rangeSwitch; std::string ret; for (auto i = -1; i < 8; ++i) { rangeSwitch.method(i, ret); std::cout << i <<"" << ret << std::endl; } } |
本标准不允许:
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).
换言之,您只能使用扩展为单个整型"硬"编译时间常量的case值(例如
解决这个问题的方法是使用
1 2 | switch (x) case 0..100: |
你会代替
1 | if (x>=0 && x<=100) |
.
这不是开关的工作原理。它只取单个值。如果Elseif挡块你就得用了
我有一个基于分数的问题,尽管"if/elseif"语句很好用,但每隔一段时间,我发现最好的选择(至少对我来说,因为我喜欢它的外观,作为初学者,更容易看到我的错误)是"1…10"。但是不要忘记在数字和点之间使用空格,否则程序会认为你的间隔是一个数字,而你会得到一个错误"2多个小数点…"。希望它有帮助。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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;} } |
1 2 3 4 5 6 | 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"; |
如果运行时间是一个问题,以下是更快的解决方案。
1 2 3 4 5 6 7 | 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"; |
switch case语句是将变量与多个"整型"值进行比较的长if语句的替换("整型"值只是可以表示为整数的值,例如char的值)。switch语句的条件是一个值。案例说明,如果它的值是该案例之后的值,那么就执行结肠后面的任何操作。中断用于中断case语句。
因此,不能在case中使用这种条件语句。
选择结构:开关
这就是我的工作。将标记除以10,然后将大小写10和9设置为显示"A"(这将为90-100之间的任何值显示"A")。然后案例8显示"B",然后案例7将显示"C",表示70-79之间的值,依此类推。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #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; } } |
您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //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; //... |
}
这是我希望的方式,这是一个简单的CT表现和随访。
你可能会对如何做surprised GCC优化代码,它可以在声音等产生的。我会希望它至少是有效的开关的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #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 "; }) .in_range(11, 20, [&] { std::cout << x <<" maps to option B "; }) .otherwise([&] { std::cout << x <<" is not covered "; }); } int main(int argc, char **argv) { test(5); test(14); test(22); } |
我知道这是一个古老的问题,但由于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
这样,您就可以省略所有的
像这样?
1 | case 'A'..'Z' where a not in ['I','L','O']: |
不幸的是,我所知道的没有一个编译器实现这个特定的扩展,尽管gcc可以像其他答案所指出的那样做范围。为了便于携带,您可以剪切和粘贴此dwtfyw许可片段。如果您使用的是自定义枚举,那么您可以使用代码生成来生成类似的东西。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #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/上的在线版本),您可能只需要生成所需内容并将其粘贴到头中,例如。
1 | foldl (++)"" ["case" ++ show x ++":" | x <- ['A'..'Z'], not $ x `elem` ['I','L','O']] |
一个潜在的有用见解是,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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,让EDOCX1(20-24)对EDOCX1(25-29),而不是