我写了一个奇怪的函数来查找数字的阶乘
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行?
答案 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)
因此,无论在递归步骤中发生什么都变得毫无意义,因为最终,当控件返回到第一个调用时,0x7777
将被return
编辑。