我意识到这可能听起来像一个愚蠢的问题,但我最后一次编程是在汇编程序中,所以我的想法可能已经关闭:
递归函数如下:
def fac(n):
if n == 0:
return 1
else:
return n * fac(n - 1)
为什么当函数达到n == 0时它不返回1而是返回阶乘的答案。我在思考类似于汇编程序的东西,当n == 0:
时mov eax, 1
ret
为什么上面的代码工作,我想python会在该条件之前返回堆栈的最后一个值?
答案 0 :(得分:12)
这样想,例如fac(5)
:
return 5 * fac(4)
return 4 * fac(3)
return 3 * fac(2)
return 2 * fac(1)
return 1 * fac(0)
1
因此1
将是第一个返回的值,但它将返回fac(1)
,而fac(1)
将返回fac(2)
,因此上。
答案 1 :(得分:1)
确实在n == 0时返回1.返回值从调用站点弹出堆栈,这是n * fac(n - 1)
的调用。 1
乘以n
并返回,等等。
答案 2 :(得分:0)
如果你打电话给fac(0),它将返回1(不是0,但我想这只是你问题中的一个错字)。如果你调用fac(1),它将进入else子句,并在那里调用fac(0)
。这将返回1.然后它将计算n * 1,即1,然后返回。如果你拨打fac(2)
,它也会进入else子句,它将调用fac(1)
,如上所述,它将返回1,因此n*fac(n-1)
将为2,这是{的返回值{1}}。等等。我希望能为你解释一下。
答案 3 :(得分:0)
没有任何东西被隐含地返回 - 当n = 0时,函数进入if语句,并直接从return 1
语句返回1。
然而,这不是将“作为因子的答案”返回给用户的点。相反,它可能会将此值返回到
调用函数调用fac(1),它位于n * fac(n - 1)
分支的中间。因此,它将返回“1”并返回n*1
,这是1到它的调用者。如果是fac(2),它将返回n * 1
,或者2返回它来电等等。
因此fac(5)被翻译成:
fac(5) = 5 * fac(4) = 5 * (4 * fac(3) = 5 * (4* (3 * fac(2)) = 5 * (4* (3 * (2 * fac(1)) = 5 * (4* (3 * (2 * (1 * fac(0)) = 5*4*3*2*1*1
只有在通过每个上层返回1值后,它才会返回到第一个调用者,并且每个阶段的乘法都会给出答案。
答案 4 :(得分:0)
James,当你对函数的最后调用(当n == 0)时,它只是调用堆栈中fac(n)的几个实例之一。如果你说print(fac(4)),那么堆栈基本上是:
fac(0)
fac(1)
fac(2)
fac(3)
fac(4)
print()
对fac(0)的最终调用适当地返回1,但是在Python中你已经请求了第一次调用fac(n),fac(4)的返回值。
不要认为它是一个循环,其中'ret'会爆发,返回只是简单地结束几个待处理的执行之一。