【问题标题】:why does this recursion program work?为什么这个递归程序有效?
【发布时间】:2016-04-01 23:00:59
【问题描述】:
#include <iostream>

using namespace std;

int main() {
    int n,x;
    int fact(int);

    cin >> n;

    x = fact(n);

    cout << x;

    return 0;
}

int fact(int n) {
    if(n!=1)
        return n*fact(n-1);
}

在最后一种情况下,当传递给函数 fact 的参数是 1 时,如果我没有在代码中指定它,它如何能够计算出 fact(1) 等于 1?

【问题讨论】:

  • 这不起作用:coliru.stacked-crooked.com/a/2c7260c2ee17d556。你需要一个更好的编译器/警告。
  • 当你的代码在没有return的情况下到达函数fact的末尾时,你有未定义的行为。
  • 我用codeblocks ide编译了上面的代码,它给了我正确的答案,codeblocks不可靠吗?
  • @srishti77714 我认为学习如何正确定义递归方法会对您有所帮助。代码中的内容充其量只是递归解决方案的一半。
  • @srishti77714 显然您的编译器没有向您发出警告消息。这可能与您在 Code::Blocks 的偏好中要求或未要求的警告级别有关。

标签: c++ recursion


【解决方案1】:

此程序依赖于未定义的行为。当然不能保证能正常工作,但是你可能发现了这样一种情况,你发送的参数(1)在调用代码感知为返回值的地方。不要依赖这种行为。

许多 C++ 编译器会因为存在语义问题而拒绝此代码:并非所有控制路径都从 fact()

返回值

【讨论】:

    【解决方案2】:
    int fact(int n);
    

    此函数签名返回一个整数,但当 n=1 时,您的实现中没有相应的返回语句。在这种情况下,函数可能会返回任何int 值(即内存中的垃圾)并且行为是未定义。你不应该依赖它,即使你的编译器允许它运行。

    我很确定您在编译程序时看到了警告。在我的环境中(Mac OSX 上的 g++),编译器发出以下警告:

    警告:控制可能到达非空函数的末尾 [-Wreturn-type]

    就个人而言,我认为编译器没有任何充分的理由允许这种错误(即它应该无法编译)。

    参考:下面有一个类似的问题:

    C++ return value without return statement

    【讨论】:

    • 嗨托比,我已经更新了答案以添加完整的描述。感谢您的评论。
    • 我看到一个 MSVC++ 10 有点过分热心了。我用switch 语句编写了一个非空函数,all 的所有情况,包括default,都返回了一个值。编译器抱怨我没有 return 语句作为函数右花括号之前的最后一条语句。控制无法到达右花括号,但我不得不添加一个虚假的 return 语句以避免错误消息。
    • 我认为这有点离题,但很有趣。在我看来,MSVC++10 应该允许在您指定所有可能的情况时编译您的程序。即,我认为编译器没有任何充分的理由不允许一个好的程序;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多