2013-04-21 158 views
0

我很好奇在使用递归函数时返回是如何工作的。例如,在下面的阶乘函数中,在任何计算实际发生之前x都将达到1。带递归函数返回

int factorial (int x){ 
    if (x==1){ 
     return 1;  
}else{ 
    return x * factorial(x - 1); 
    } 
} 

假设x = 3。继逻辑,现在看来,这应该循环3次,并返回1:

  • 3 != 1
  • 所以别人:3 * factorial (2)
  • 什么是factorial (2)
  • 那么返回顶部:2 != 1
  • 如此:2 * factorial (1)
  • 什么是factorial (1)
  • 返回顶部:1 == 1,
  • 所以:return 1

但是,当然它实际上会返回6.所以它是如何工作的?

+3

实验!你就是这样学习的。 – 2013-04-21 01:00:01

+1

你应该阅读一个基本的递归教程。基本上,您有一个调用堆栈,直到您到达基本案例(在本例中为'x == 1')为止,然后将调用堆栈解析为“向后”,直到它返回第一个函数调用。 – 2013-04-21 01:01:24

+0

[理解递归]的可能的重复(http://stackoverflow.com/questions/717725/understanding-recursion) – 2013-04-21 01:03:57

回答

1

每次你说“这个递归调用的价值是什么?”时,你会放弃上一次迭代的x *。如果不这样做:

factorial(3) 
3 * factorial(2) 
3 * (2 * factorial(1)) 
3 * (2 * 1) 
= 6 

递归调用是不是有新的论点再次喜欢goto到函数的顶部。 我们用新的参数再次调用该函数,但只有该调用具有新的参数值:调用方仍然具有其参数和变量的旧值。

除非我们正在谈论尾部递归,我们不这样做,而这只是一个优化。

1

这不是返回顶部,它调用factorial函数中的factorial函数。

实际上,在结束时,则返回1,但它返回它作为结果在线路

return x * factorial(x - 1); 
先前呼叫的

factorial到,其中x为2这又返回2 * 1到之前调用factorial的地方,其中x是3.所以这给出3 * 2,返回结果 - 6 - 函数的第一次调用。

0

递归函数调用与普通函数调用没有区别。因此,一个呼叫的return与另一呼叫的return之间没有关联。

在该示例中,第一return语句是

return 3 * factorial(2) 

其通过调用factorial为2的参数的返回值乘以3。

但是阶乘的返回值(2)是

return 2 * factorial(1) 

其通过调用factorial用的1

参数但是阶乘的返回值的返回值乘以2(1)是1。

所以return 2 * factorial(1)相同return 2 * 1,它是2。

所以return 3 * factorial(2)是叔他与return 3 * 2相同,即6.

0

第一步,x = 3。你的函数然后返回3 * factorial(2),这本身就返回2 * factorial(1)(因为x仍然不等于1),最后,factorial(1)返回1

所以最后你得到3 * 2 * 1 = 6

0

栈帧是一个记录,它在运行时用于存储有关函数调用的信息,包括参数,局部变量,寄存器值和返回地址。对于每个连续的函数调用,我们都将堆栈帧压入堆栈,并且当任何活动函数(位于堆栈顶部的函数)返回调用时,堆栈框架将从堆栈中弹出,并且其下面的函数将被激活。这里是例子。

enter image description here

所以,最后的功能阶乘(3)的返回值6