我制作了一个递归的C ++程序,如下所示:
using namespace std;
#include <iostream>
bool recursive(int num)
{
if (num == 6)
{
return false;
}
else if (num > 6)
{
return true;
}
else
{
if (recursive(num + 1))
{
return true;
}
else
{
return false;
}
}
}
int main()
{
if (recursive(0))
{
cout << "Not found!" << endl;
}
else
{
cout << "Found..." << endl;
}
}
它有效,我认为这是(大致)最好的方法。
我的朋友制作了一个更简单的递归程序,如下所示:
using namespace std;
#include <iostream>
bool recursive(int num)
{
if (num == 6)
{
return false;
}
else if (num > 6)
{
return true;
}
else
{
recursive(num + 1);
}
}
int main()
{
if (recursive(0))
{
cout << "Not found!" << endl;
}
else
{
cout << "Found..." << endl;
}
}
他的作品与我的作品一样,但我不明白为什么会这样。对我来说,看起来在他的else块中没有返回任何内容,所以我不明白布尔值是如何返回到原始函数调用的。
出于好奇,我在JavaScript中制作了类似的程序:
function recursive(index)
{
if (index == 6)
{
return true;
}
else if (index > 6)
{
return false;
}
else
{
recursive(index + 1);
}
}
if (recursive(0))
{
console.log("found");
}
else
{
console.log("not found");
}
但JavaScript程序不起作用,这让我觉得这是特定于C ++的。
为什么我朋友的计划有效?它完全有效,还是未定义的行为?
答案 0 :(得分:6)
为什么会这样?答:它没有。
else
{
recursive(num + 1);
}
您朋友的节目缺少return
声明。
else
{
return recursive(num + 1);
}
不从非void
函数返回值会导致未定义的行为。
在这种情况下,碰巧在您测试的计算机上,递归调用的返回值自动被&#34;返回&#34;对来电者 - 也许是因为它碰巧在正确的登记册中。这是纯粹的偶然事件。你不能依赖它。在不同的机器上,或者不同的编译器,甚至是不同的调用,程序也可以返回别的东西,或者崩溃,或做任何你能想象到的事情。
答案 1 :(得分:3)
在没有return语句的情况下结束函数是C ++中未定义的行为。我能做的最好的事情是推测关于发生了什么,我最好的猜测是调用recursive(index + 1)
,这是函数返回之前堆栈中的最后一件事,被拿起作为回报值。所以在(非标准的,非便携式的,一般用途的建议很差)意义上,代码隐式插入了return语句。
答案 2 :(得分:2)
这是未定义的行为。由于函数声明为返回布尔值,因此它将始终返回一些内容,但不一定是正确的值。
如果使用-Wall
标记进行编译,GCC之类的编译器会向您发出此类代码的警告。
答案 3 :(得分:2)
当然,它有效!好吧,不是真的。
地球上的每个编译器(可能不会)会警告您:
clang:
control may reach end of non-void function
gcc:
control reaches end of non-void function
MVSC:
not all control paths return a value
它 工作,因为你的朋友很幸运,不会让你的程序爆炸,内爆或在你的卧室里造成黑洞。未定义的行为就是这样:您无法告诉您的程序将如何表现。
这就是标准所说的:
在构造函数,析构函数或具有cv void返回类型的函数的末尾流动,相当于没有操作数的返回。否则,流出函数的末尾而不是main(3.6.1) 导致未定义的行为。