C ++中的递归布尔函数

ThisIsNotAnId

我对C ++相对较新(大多数情况下通常都是编程),并且正在参加在线课程,其后进行教学以构建游戏为目标。在控制台应用程序项目之一中,我们必须编写代码来询问用户是否要再次玩游戏。该部分程序的目标是要求用户仅键入“ y”或“ n”来进行答复并重新询问该问题,如果用户通过其他方式做出响应。

我已经尝试编写执行此操作的代码,据我所知,代码工作正常。我的问题是,我编写的代码在以下意义上是否有效:

  1. 代码能否成功完成概述的任务?
  2. 如果这样的代码以后增加,是否会出现更多错误?

我的代码如下。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;
}

我在代码注释中提出的推理是否有效?是否有一个测试用例会失败?我已经尝试了一些测试用例,但是所有这些都有效。

非常感谢您对此提供的任何帮助!

巴马克·谢米拉尼(Barmak Shemirani)

递归方法没有什么问题,但是您可以通过循环简化此过程,并避免与递归相关的潜在问题。循环和递归紧密相关。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;
}

因此,最好使用循环来支持递归函数。但是再说一次,递归函数有时很有用,并且如果内存分配处于控制之下(如您的示例中所示),并且有明确的路径可以打破递归,则继续使用它。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章