我很困惑这个代码如何在给定序列顺序的情况下为每个n-1乘以n。让我解释一下我如何看待正在发生的事情,你可以指出我错在哪里。
如果n小于0,则比较为假,程序只返回1(如果这是第一次调用它)。如果不是,则调用L1并使其递减。这是我感到困惑的地方。看起来事实是在减量之后立即再次调用,并且乘法函数永远不会发生。在这种情况下,如果n = 5,那么它将简单地递减直到n = 0并最终在最后乘以1 x 5。
我最好的猜测是,我错过了推送/弹出堆栈上下值的内容,但我没有任何线索。
fact: addi $sp, $sp, -8 # adjust stack for 2 items
sw $ra, 4($sp) # save the return address
sw $a0, 0($sp) # save the argument n
slti $t0, $a0, 1 # test for n < 1
beq $t0, $zero, L1 # if n >= 1, go to L1
addi $v0, $zero, 1 # return 1
addi $sp, $sp, 8 # pop 2 items off stack
jr $ra # return to instruction after jal
L1: addi $a0, $a0, -1 # n >= 1; argument gets (n – 1)
jal fact # call fact with (n – 1)
lw $a0, 0($sp) # return from jal: restore argument n
lw $ra, 4($sp) # restore the return address
addi $sp, $sp, 8 # adjust stack pointer to pop 2 items
mul $v0, $a0, $v0 # return n * fact (n – 1)
jr $ra # return to the caller
编辑:
以下是C中将要发生的功能:
int fact (int n)
{
if (n < 1) return (1);
else return (n * fact(n – 1));
}
答案 0 :(得分:1)
让我们说你想要3!所以从n = 3开始。
n&lt; 1不正确
- &GT;返回3 *事实(2)
返回n = 2
的功能n&lt; 1不正确
- &GT;返回2 *事实(1)
回到n = 1的函数
再次n&lt; 1不正确
- &GT;返回1 * fact(0)
返回功能,n = 0
现在n&lt; 1 true
返回1
递归开始放松
1替换fact(0),函数返回1 * 1
1替换事实(1)in和函数返回2 * fact(1),即2
2代替事实(2),函数返回3 * fact(2),即6
递归结束。
答案 1 :(得分:0)
“我最好的猜测是,我错过了推送/弹出堆栈上下值的内容,但我没有任何线索。”
就是这样;
你忘了弹出堆叠,一旦你召唤4然后3然后2然后1(这里得到值1),你返回AT $ ra!函数继续并逐个进行乘法运算,然后逐个弹出每个堆栈级别,直到结束整个函数调用的最终$ ra。