我对C ++(以及大部分编程)都比较陌生,而且我正在开设一个在线课程,其目的是建立一个游戏。在其中一个控制台应用程序项目中,我们必须编写代码,询问用户是否要再次玩游戏。该程序的那部分目标是通过仅键入“y”或“n”来要求用户回复如果用户通过做其他事情做出回应,则重新询问问题。
我试图编写执行此操作的代码,据我所知,代码工作正常。我的问题是,我写的代码是否在以下意义上有效:
我遵循的代码。在main
函数中:
.
.
.
do
{
PlayGame();
}
while (AskToPlayAgain());
AskToPlayAgain
的函数定义以及恰当的描述:
bool AskToPlayAgain()
{
bool Play = true;
string response = "";
cout << "Would you like to play again? y/n... ";
getline(cin, response);
if (response == "y") { }
else if (response != "n")
{
cout << "Please enter a valid response." << endl;
// We want AskToPlayAgain called again to ask for a proper response again; however,
// just calling it outside a conditional will cause the current "Play" value to be returned.
// This value is true by default and this function will return it even if "n" is entered after
// an invalid response. As such, in this case, we want this function to be called in the event
// of an invalid response which will always happen and we don't want the return value of the nested
// AskToPlayAgain function to be returned, which is true by default unless the program has successfully exited.
// Furthermore, once the nested AskToPlayAgain returns false, we want the program to exit and not return the "Play"
// (which is set to true) by the higher level AskToPlayAgain.
if (AskToPlayAgain()) { }
else { return false; }
}
else
{
Play = false;
cout << "Thank you for playing! :D" << endl;
}
return Play;
}
我在代码注释中提出的推理是否有效?是否有测试用例会失败?我尝试了一些测试用例,但所有测试用例都有效。
非常感谢您提供任何帮助!
答案 0 :(得分:3)
您的递归方法没有任何问题,但您可以通过循环简化此操作,并避免与递归相关的潜在问题。循环和递归密切相关。 if (response == "y") { }
没有错,但这是一个奇怪的编程习惯。如果你在达到这个条件时不打算做任何事情,那就不要费心去测试了。
使用while
循环的另一种方法:
bool AskToPlayAgain()
{
while(true)
{
string response;
cout << "Would you like to play again? y/n... ";
getline(cin, response);
if(response == "y")
{
return true;
}
else if(response == "n")
{
cout << "Thank you for playing! :D" << endl;
return false;
}
cout << "Please enter a valid response." << endl;
}
}
<小时/> 的 编辑
另一个递归函数的例子:
这次我们为演示添加counter
值。
如果您运行此程序并继续提供无效输入,那么counter
将会上升。它显示了递归函数如何等待所有其他递归函数完成。
我添加了未使用的char buf[1000]
。它的目的是引起问题!
潜在问题:每个函数需要分配1000
字节堆栈内存(加上函数中其他堆栈变量的内存,以及std::string
的堆内存)。在函数存在之前,不释放该内存,因此它会建立起来。程序中的堆栈限制是几兆字节,所以现在可能存在堆栈溢出错误。
bool AskToPlayAgain(int counter)
{
char buf[1000]; //<-- allocate lots of stack memory to cause problems!
cout << "counter start: " << counter << " - memory allocated\n";
cout << "play again? y/n... ";
string response;
getline(cin, response);
if(response == "y")
{
return true;
}
else if(response == "n")
{
cout << "Thank you for playing! :D\n";
return false;
}
cout << "invalid response\n";
bool result = AskToPlayAgain(counter + 1);
cout << "counter: " << counter << " - memory cleanup\n";
return result;
}
int main()
{
do
{
printf("play...\n");
} while(AskToPlayAgain(1));
return 0;
}
因此,最好使用循环来支持递归函数。但是再一次,递归函数有时是有用的,如果内存分配受到控制(如在你的例子中)并且有明确的路径来打破递归,那么继续使用它。
答案 1 :(得分:2)
我建议您在AskToPlayAgain()
函数中检查response == "y"
和response == "n"
,然后执行else
部分。虽然这不会对您的代码产生太大影响,但它更容易阅读和理解,如果稍后出现问题,您将不必花费太多时间再次查看代码。
即。
if (response == "y") { }
else if (response == "n"){
// your code
}
else {
// your code to handle the invalid response
}
另外,正如@Barmak Shemirani在评论和答案中所建议的那样,最好只使用一个循环来完成重复询问的任务,直到有效的回复。它比具有多个函数调用“更便宜”。