C++ - 在同一函数的定义中调用一个函数

Col*_*ton 5 c++ recursion function

我正在编写类似于下面代码的东西,我不小心在函数定义的主体内部调用了相同的函数.

double function(double &value)
{
     //do something with a here
     if(some condition)
     {
           function(a);
     }
     return a;
}
Run Code Online (Sandbox Code Playgroud)

考虑一下这种形式:

int function(int &m)   {
    m = 2*m;
    if(m < 20)
    {
        function(m);
    }
    return m;
};

int main()  {
    int a = 2;
    std::cout <<"Now a = "<<function(a);
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

据我说,这不应该运行,更不用说编译了.但它确实运行并给出正确的结果

现在a = 32

在我完成定义它之前,我已经调用了该函数.然而,它有效.为什么?

Lst*_*tor 12

调用自身的函数称为递归函数.这是有效的,因为编译器只需要声明一个函数而不是它的定义,因为你可以调用它.定义的第一行也作为声明.(有关详细信息,请参阅C++ 11标准的第8.4.1.2节.)

递归非常适合解决许多问题.递归函数的典型示例是factorial函数.它被定义为factorial(n) = n * factorial(n-1).

您可以尝试运行这段代码,以便更好地了解函数调用自身时会发生什么:

#include <iostream>

int factorial(unsigned int n)
{
    std::cout << "Computing factorial of " << n << "\n";

    int result;
    if (n == 0) {
        result = 1;
    } else {
        result = n * factorial(n-1);
    }

    std::cout << "factorial(" << n << ") = " << result << "\n";
    return result;
}

int main()
{
    factorial(5);
}
Run Code Online (Sandbox Code Playgroud)

有关声明与定义的更多信息,请参阅此答案.关于One Definition Rule的Wikipedia页面也可能有所帮助.

  • 我想补充一点,你应该更喜欢使用迭代来使用递归.所以,如果你想计算阶乘,你最好使用`int result; for(int i = 2; i <= n; ++ i)result*= i;`,因为1)它工作得更快,因为调用函数不是免费的; 2)如果你对递归过于深入,你可能会得到(ha-ha)堆栈溢出:)递归是一个非常强大的工具,许多算法没有它就没有意义.但要谨慎使用它. (3认同)