解释这个C ++函数中的程序流程

时间:2014-10-02 08:45:35

标签: c++

我写了一个奇怪的函数来查找数字的阶乘

int strange_fact(int n=0)
{
    static int i=n;
    static int j=i;
    if(j>1)     
    {       
        i *= --j;
        strange_fact();         
        return 0x7777;    //<------ This line
    }
    else
        return i;
}

当我评论第9行时,我得到了预期的输出。但是在添加该行后我遇到了一种奇怪的(或者可能不那么奇怪的)行为。当我取消注释它时发生的是程序流到达第9行,即使递归函数调用在它之前。我的问题是,流量如何到达第9行?

4 个答案:

答案 0 :(得分:6)

当递归调用函数结束时,将到达第9行。见这(更短)的例子:

int foo(int i) {
    if(i > 0) {
        foo(i-1);
        return 0x7777;
    } else {
      return i;
    }
 }

因此,当调用foo(1)时,如果(因为1> 0)和foo(0)将被调用,它将首先通过。现在这个调用(foo(0))程序将进入else barnch(因为0不是&gt; 0)而foo(0)将返回0.所以现在我们将回到我们的第一个调用(foo(1))并且当foo(0)返回时,foo(1)将返回0x7777。

答案 1 :(得分:2)

这一行

 strange_fact();

执行递归并丢弃结果。

下一行

return 0x7777;

最终将返回该值。

如果删除该行并使用上面的警告进行编译,则会通知您所有路径都没有返回值

答案 2 :(得分:1)

您需要了解递归的工作原理。

在致电strange_fact()后,您已发出退货声明。这意味着一旦执行了该函数,它仍然会返回0x7777,这会使答案搞砸。

检查一下,这应该按预期工作:

int strange_fact(int n=0)
{
    static int i=n;
    static int j=i;
    if(j>1)     
    {       
        i *= --j;
        strange_fact();         
        // return 0x7777;    // We don't want to return a value yet
    }
    if(j<=1)          // We need to check this condition after strange_fact is executed
        return i;

    // This line will never be executed
    return 0x7777;    //<------ This line
}

如果你消除了静态变量,你会得到这样的东西:

long fact(long i)
{
    if(i > 0)
        return i * fact(i-1);
    if(i == 0)              // factorial(0) = 1
        return 1;

    throw exception("Negative numbers cannot have factorials"); // Or you can handle it by returning a -ve error code
}

答案 3 :(得分:1)

整个事情,由图解释

让我们考虑一下strange_fact(3)

的情况

enter image description here

因此,无论在递归步骤中发生什么都变得毫无意义,因为最终,当控件返回到第一个调用时,0x7777将被return编辑。