我很好奇使用递归函数时返回是如何工作的。例如,在下面的阶乘函数中,在实际发生任何计算之前,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.那么它是如何工作的呢?
答案 0 :(得分:1)
每当你说“那个递归调用的值是多少?”时,你就会从上一次迭代中删除x *
。没有这样做:
factorial(3)
3 * factorial(2)
3 * (2 * factorial(1))
3 * (2 * 1)
= 6
递归调用与使用新参数的函数顶部不再是goto
。 1 我们使用新参数再次调用该函数,但只有该调用具有新参数value:调用者仍然具有其参数和变量的旧值。
1 除非我们讨论的是尾部递归,我们不是这样,而且这只是一种优化。
答案 1 :(得分:1)
它不是返回到顶部,而是调用factorial
函数中的factorial
函数。
实际上,最后,它返回1,但它会在行
中返回它return x * factorial(x - 1);
上一次factorial
来电的,其中x
为2.这又将2 * 1返回到factorial
的上一次调用,其中x
为3.所以这给出3 * 2,将结果 - 6 - 返回到函数的第一次调用。
答案 2 :(得分:0)
递归函数调用与普通函数调用没有什么不同。因此,一个呼叫的return
与另一个呼叫的return
之间没有任何关联。
在示例中,第一个return
语句是
return 3 * factorial(2)
将3乘以调用factorial
的返回值,参数为2。
但是factorial(2)的返回值是
return 2 * factorial(1)
将2乘以调用factorial
的返回值,参数为1。
但是factorial(1)的返回值是1。
所以return 2 * factorial(1)
与return 2 * 1
相同,即2。
因此return 3 * factorial(2)
与return 3 * 2
相同,即6。
答案 3 :(得分:0)
在第一步中,x = 3
。然后,您的函数返回3 * factorial(2)
,它本身返回2 * factorial(1)
(因为x
仍然不等于1),最后,factorial(1)
返回1.
所以最后得到3 * 2 * 1 = 6
。
答案 4 :(得分:0)
堆栈帧是在运行时用于存储有关函数调用的信息的记录,包括参数,局部变量,寄存器值和返回地址。对于每个连续的函数调用,我们将堆栈帧推入堆栈,当任何活动函数(位于堆栈顶部的函数)获得返回调用时,它的堆栈帧从堆栈弹出,并且它下面的函数变为活动状态。这是一个例子。
所以,最后函数factorial(3)返回值6 。