while循环中的高级开关语句? 我刚开始C++,但是对其他语言有一些以前的知识(很不幸的是VB很早就回来了),但是有一个奇怪的困境。我不喜欢使用这么多IF语句,我想使用switch/cases,因为它看起来更干净,我想参与实践。。但是
假设我有以下场景(理论代码):while循环中的高级开关语句? 我刚开始C++,但是对其他语言有一些以前的知识(很不幸的是VB很早就回来了),但是有一个奇怪的困境。我不喜欢使用这么多IF语句,我想使用switch/cases,因为它看起来更干净,我想参与实践。。但是,c++,logic,switch-statement,while-loop,break,C++,Logic,Switch Statement,While Loop,Break,假设我有以下场景(理论代码): while(1){ //循环可以是条件循环或1循环,我经常使用它,例如在我的游戏中 烧焦某物; std::cout>某物; //切换到“某物” 开关(某物){ 案例“a”: CUT< P>是的,C和C++没有办法说“退出多个可断块”(其中“可断块”是任何循环或开关)。解决方案包括“代码> Goto < /Calp>S”和使用布尔变量来记录外部“可破解块”是否也应该被破解(既不优雅,但就是生命)。.您只需在一个case语句中设置一个bool值,然后进行while循环
while(1){
//循环可以是条件循环或1循环,我经常使用它,例如在我的游戏中
烧焦某物;
std::cout>某物;
//切换到“某物”
开关(某物){
案例“a”:
CUT< P>是的,C和C++没有办法说“退出多个可断块”(其中“可断块”是任何循环或开关)。解决方案包括“代码> Goto < /Calp>S”和使用布尔变量来记录外部“可破解块”是否也应该被破解(既不优雅,但就是生命)。.您只需在一个case语句中设置一个bool值,然后进行while循环检查即可
bool done = false;
while(!done)
{
char something;
std::cout << "Enter something\n -->";
std::cin >> something;
//Switch to read "something"
switch(something) {
case 'a':
cout << "You entered A, which is correct";
done = true; // exit condition here
break;
case 'b':
cout << "...";
break;
}
}
booldone=false;
而(!完成)
{
烧焦某物;
std::cout>某物;
//切换到“某物”
开关(某物){
案例“a”:
cout两个break
语句不能使您脱离while循环。第一个break
语句只能使您脱离开关
语句,而第二个语句永远无法到达
您需要的是使while循环的条件为false,假设开关
语句后的循环中没有任何代码。如果开关后有其他代码,您应该检查开关
后的条件,并在那里检查中断
bool done = false;
while(! done)
{
// do stuff
switch(something)
{
case 'a':
done = true; // exit the loop
break;
}
// do this if you have other code besides the switch
if(done)
break; // gets you out of the while loop
// do whatever needs to be done after the switch
}
您还可以将循环封装到一个函数中,并在case内部调用return,以防标志中断while是不够的。
对于某些人来说,这不是一个好的编程实践,但如果你保持函数简单,我不明白为什么不这样做。你可以将开关更改为ifsystem。无论如何,它将被编译成相同的东西。你可以尝试:
- 使用旗帜
- 使用Goto
- 使内部的可断块成为一个函数
- 使用异常
- 使用longjump和setjmp
与这个问题非常相似的话题
我会将支票重构为另一个函数
bool is_correct_answer(char input)
{
switch(input)
{
case 'a':
cout << "You entered A, which is correct";
return true;
case 'b':
cout << "...";
return false;
}
return false;
}
int main()
{
char input;
do
{
std::cout << "Enter something\n -->";
std::cin >> input;
} while (!is_correct_answer(input));
}
bool是正确答案(字符输入)
{
开关(输入)
{
案例“a”:
不能输入;
}而(!答案正确吗(输入));
}
您可以用稍微过度设计的OO解决方案替换交换机
#include <iostream>
#include <map>
#include <set>
class input_responder
{
std::set<char> correct_inputs;
std::map<char, const char*> wrong_inputs;
public:
input_responder()
{
correct_inputs.insert('a');
wrong_inputs['b'] = "...";
}
bool respond(char input) const
{
if (correct_inputs.find(input) != correct_inputs.end())
{
std::cout << "You entered " << input << ", which is correct\n";
return true;
}
else
{
std::map<char, const char*>::const_iterator it = wrong_inputs.find(input);
if (it != wrong_inputs.end())
{
std::cout << it->second << '\n';
}
else
{
std::cout << "You entered " << input << ", which is wrong\n";
}
return false;
}
}
};
int main()
{
const input_responder responder;
char input;
do
{
std::cout << "Enter something\n -->";
std::cin >> input;
} while (responder.respond(input) == false);
}
#包括
#包括
#包括
类输入\响应器
{
设置正确的输入;
标准::映射错误的_输入;
公众:
输入_响应器()
{
正确输入。插入('a');
错误的_输入['b']=“…”;
}
布尔响应(字符输入)常量
{
if(correct_inputs.find(input)!=correct_inputs.end())
{
STD::CUT你可能对C++中的内容感兴趣。
#定义命名(blockname)转到blockname\
块名###u跳过:if(0)\
块名:
#定义中断(块名)转到块名####u跳过;
命名(外部)
而(1){
//循环可以是条件循环或1循环,我经常使用它,例如在我的游戏中
烧焦某物;
std::cout>某物;
//切换到“某物”
开关(某物){
案例“a”:
这是一个很好的论点,如果不重要的话,我不介意代码有点过于结构化。:PBe请务必添加一条注释,解释为什么要使用if/else if
,以便您(或其他人)不要在以后看到它,并将其更改为更明显的switch语句,从而破坏一切。这不是双关语。如果有人重构了您的代码,但没有注意到他们已经更改了方法的基本行为,我不确定我是否会信任他们首先阅读注释。它可能不会被编译为相同的内容。switch
通常使用跳转表来实现,如果有许多案例,跳转表可能会更快。@Nick Lewis:我想大多数人都会注意到中断问题,就像@Jason?@thoug:我相信编译器也会使用跳转表,如果他们注意到else-ifs中的一个简单重复模式的话这可能是一个达夫的设备问题。不。是否有一个无聊的标签?很高兴你的问题得到解决,这些事情不是最有趣的。标记并将块包装到函数中工作。Goto不好。异常在这里根本不合适。退出循环不是错误。Goto不坏。我认为Goto是合适的在这种情况下,使用标志就晚了。在我使用goto的示例代码中,如果switch语句后面有代码,它会保持代码整洁。我会说这个答案有点不理想(但没有任何错误)。如果在switch语句下添加代码,即使问题是直接退出外部循环,它也会运行。我会使用Dimas If(done)break;方法或goto。是的,这是此解决方案的一个陷阱,代码在该开关下执行。同意。有趣的是,我总是在(运行)时使用你们两个都没有抓住要点。在完成后执行一些样板代码(例如重置计数器或任何其他杂项代码)并没有什么问题。这不是一个陷阱,而是一个奖励。你必须跳出框框思考,看看在设置done=true后执行代码的能力在哪里有积极的影响。这不是一个短路,而是一个布尔值。需要修改其中一个函数以考虑大写或小写选择。只需更改开关(输入)
切换到开关(tolower(input))
。如果要检查是否(done),为什么不直接执行while(true)。这是多余的。这取决于……您可能希望或不希望在切换后立即断开。
bool is_correct_answer(char input)
{
switch(input)
{
case 'a':
cout << "You entered A, which is correct";
return true;
case 'b':
cout << "...";
return false;
}
return false;
}
int main()
{
char input;
do
{
std::cout << "Enter something\n -->";
std::cin >> input;
} while (!is_correct_answer(input));
}
#include <iostream>
#include <map>
#include <set>
class input_responder
{
std::set<char> correct_inputs;
std::map<char, const char*> wrong_inputs;
public:
input_responder()
{
correct_inputs.insert('a');
wrong_inputs['b'] = "...";
}
bool respond(char input) const
{
if (correct_inputs.find(input) != correct_inputs.end())
{
std::cout << "You entered " << input << ", which is correct\n";
return true;
}
else
{
std::map<char, const char*>::const_iterator it = wrong_inputs.find(input);
if (it != wrong_inputs.end())
{
std::cout << it->second << '\n';
}
else
{
std::cout << "You entered " << input << ", which is wrong\n";
}
return false;
}
}
};
int main()
{
const input_responder responder;
char input;
do
{
std::cout << "Enter something\n -->";
std::cin >> input;
} while (responder.respond(input) == false);
}
#define named(blockname) goto blockname; \
blockname##_skip: if (0) \
blockname:
#define break(blockname) goto blockname##_skip;
named(outer)
while(1) {
//Loop can be conditional or 1, I use it alot, for example in my game
char something;
std::cout << "Enter something\n -->";
std::cin >> something;
//Switch to read "something"
switch(something) {
case 'a':
cout << "You entered A, which is correct";
break(outer);
case 'b':
cout << "...";
break(outer);
}
}