为什么去掉这条return语句会影响整个递归函数的结果呢?

Why does the removal of this return statement affect the outcome of the entire recursive function?

我正在使用递归编写一个回文检查器。 我很困惑为什么要删除

return true

函数末尾的语句影响 return 值。

int firstChar = 0;
int lastChar = 0;
// These two variables are used to transverse the string from both ends 
// eventually meeting

代码#1:

bool palindromeCheck (string text, int firstChar, int lastChar)
{
    string tempCleanText = text;

    // Removes all punctation and space
    if (firstChar == 0)
    {
        // Cleans text, ignore.
        tempCleanText = cleanString(tempCleanText);

        // Sets this variable to the end of the string
        lastChar = tempCleanText.size() - 1;
    }

    // Base Case
    if (firstChar >= lastChar)
    {
        return true;
    }

    if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
    {
        palindromeCheck(tempCleanText, ++firstChar, --lastChar);
    }
    else
    {
        return false;
    }

    return true;    // Keeping this in works
}

这 return 是正确的,因为它应该适用于所有回文,而对于所有非回文都是错误的。

代码#2:

bool palindromeCheck (string text, int firstChar, int lastChar)
{
    string tempCleanText = text;

    // Removes all punctation and space.
    if (firstChar == 0)
    {
        // Cleans text, ignore.
        tempCleanText = cleanString(tempCleanText);

        // Sets this variable to the end of the string
        lastChar = tempCleanText.size() - 1;
    }

    // Base Case
    if (firstChar >= lastChar)
    {
        return true;
    }

    if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
    {
        palindromeCheck(tempCleanText, ++firstChar, --lastChar);
    }
    else
    {
        return false;
    }

    // there is no return true here, and so the output is no longer correct
}

这 return 仅对某些回文为真,对所有非回文为假。

回文,例如,

amanaplanacanalpanama <- 尺寸长度 21

Returns false,当它应该 return true.

通过测试表明,基本情况是使用最后一个回文输入的,这意味着该函数将其视为有效回文。但是,我假设程序然后展开调用堆栈,并且当它经过所有以前的函数调用时,某些东西使函数 return false.

对于初学者来说,该功能在任何情况下都是不正确的。例如,对于字符串 "1231",函数 returns true。希望你自己查一下。

这部分功能

if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
    palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
    return false;
}

return true;    // Keeping this in works

至少应替换为以下代码片段

if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
    return palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
    return false;
}

也就是这个return语句

return true;    // Keeping this in works

应完全删除。

至于你的问题,如果没有最后一个 return 语句,该函数具有未定义的行为,因为它 return 在 if 语句之后没有任何内容。那就是if语句

if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))
{
    palindromeCheck(tempCleanText, ++firstChar, --lastChar);
}
else
{
    return false;
}

执行成功前提是

tempCleanText.at(firstChar) == tempCleanText.at(lastChar))

函数 return 在执行 if 语句的子语句后做什么?没有什么! :)

除了字符串本身之外声明两个额外的参数(索引)也没有意义,因为在任何情况下字符串都是按值传递的,你总是可以通过调用成员函数来获得它的大小size().

我可以建议该函数的以下实现与您的函数类似,此函数实现 return在传递空字符串的情况下为真。

#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>

bool palindromeCheck( std::string s )
{
    if ( s.size() < 2 )
    {
        return true;
    }
    else if ( ispunct( ( unsigned char )s.front() ) || isspace( ( unsigned char )s.front() ) )
    {
        return palindromeCheck( s.substr( 1 ) );
    }
    else if ( ispunct( ( unsigned char )s.back() ) || isspace( ( unsigned char )s.back() ) )
    {
        return palindromeCheck( s.substr( 0, s.size() - 1 ) );
    }
    else if ( s.front() == s.back() )
    {
        return s.size() == 2 ? true : palindromeCheck( s.substr( 1, s.size() - 2) ); 
    }
    else
    {
        return false;
    }
}

int main() 
{
    std::cout << std::boolalpha << palindromeCheck( "" ) << '\n';
    std::cout << std::boolalpha << palindromeCheck( "1" ) << '\n';
    std::cout << std::boolalpha << palindromeCheck( "1 1" ) << '\n';
    std::cout << std::boolalpha << palindromeCheck( "1,2,2,1" ) << '\n';
    std::cout << std::boolalpha << palindromeCheck( "1 2 3 2 1" ) << '\n';
    std::cout << std::boolalpha << palindromeCheck( "12341" ) << '\n';

    return 0;
}

程序输出为

true
true
true
true
true
false

可能是

// ...

if (tempCleanText.at(firstChar) == tempCleanText.at(lastChar))

{
   return palindromeCheck(tempCleanText, ++firstChar, --lastChar); 
}

else
    return false;
// ...

在没有通过 return 关键字显式 return 值的情况下从非空函数返回会调用 未定义的行为 。根据 C++ 规范,调用未定义行为的程序可以自由地执行任何字面上的任何操作,所有由此产生的怪异行为都将归咎于编写调用未定义行为的代码的程序员。

在这种情况下实际可能发生的情况是,当您的函数 returns 通过删除函数的末尾(并且不执行 return false)时,函数所在的位置return 存储的值永远不会被写入——这意味着,就调用代码而言,函数 returned 的值将等于恰好存在的任何值在您的函数 returns 时的那个位置。该位置的预先存在的值将是任意的且难以预测,因为它是有关程序如何执行的各种细节的结果,因此程序的行为也将是任意的且难以预测.

解决方案是确保始终显式 return 一个值;在您的编译器中启用警告将允许它通过警告您来帮助您完成该任务,如果您忘记 return 某些代码路径中的值。