2016-11-10 57 views
2

我做了一个递归C++程序,看起来像这样:为什么这种递归在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++。

为什么我的朋友的程序工作?它是完全有效的,还是未定义的行为?

+2

你朋友的密码坏了。未定义的行为。 –

+0

您的原始代码有25行。这似乎过分了,实际上,Stack Overflow不会显示完整的代码,读者将被迫在代码框中向下滚动。您可以将相同的功能*舒适地*安装到七条线中。你甚至可以在保持可读性的同时将逻辑减少到一行:'return num <6?递归(num + 1):num> 6;'。但是在实际应用中,您应该放弃递归:'return num> 6;'。 –

回答

2

这是未定义的行为。由于该函数被声明为返回布尔值,它将总是返回一些内容,但不一定是正确的值。

如果使用-Wall标志进行编译,像GCC这样的编译器会给你这种类型的代码的警告。

6

它为什么有效?答:不。

else 
{ 
    recursive(num + 1); 
} 

您的朋友的程序缺少return声明。

else 
{ 
    return recursive(num + 1); 
} 

不返回来自非void函数的值会导致未定义的行为。

在这种情况下,您在计算机上测试的递归调用的返回值自动“返回”给调用者 - 可能是因为它碰巧在正确的寄存器中。这纯粹是偶然。你不能依靠它。在不同的机器上,或者不同的编译器,甚至不同的调用中,程序可能会返回其他东西,或者崩溃,或者做任何你能想象的事情。

2

在没有返回语句的情况下结束函数在C++中是未定义的行为。我能做的最好的是推测至于发生了什么,我最好的猜测是recursive(index + 1)的调用,作为函数返回之前堆栈中的最后一件事物,正在被拾取为返回值。因此,在一个(非标准的,不可移植的,通用性很差的建议)意义上,代码隐式地插入了return语句。

1

当然,它的工作原理!那么,不是真的。

地球(也许不是)会警告你在每一个编译器:

铛:control may reach end of non-void function

GCC:control reaches end of non-void function

MVSC:not all control paths return a value

确实工作因为你的朋友很幸运,不要h此计划爆炸,内爆或在你的卧室创造一个黑洞。未定义行为就是这样:你不能说出你的程序将如何表现。

这就是标准有什么看法:

流下的构造函数,析构函数,或用CV void返回类型的函数到底是等同于不带操作数的回报。否则,关闭,而不是主(3.6.1) 以外的函数的末尾导致未定义的行为

相关问题