递归方法

时间:2015-02-27 01:49:49

标签: visual-studio-2010 recursion windbg

我很难抓住递归。例如,我有以下方法。当if语句返回true时,我希望从此方法返回。但是,查看Windbg和Visual Studio中的方法执行情况表明该方法继续执行。我为一般性问题道歉,但您的反馈意见真的很感激。

N如何按顺序递减以满足if条件?

long factorial(int N)
{
    if(N == 1)
        return 1;
    return N * factorial(N - 1);
}

2 个答案:

答案 0 :(得分:3)

编译和反汇编你应该得到类似于

的反汇编的函数
0:000> cdb: Reading initial command 'uf fact!fact;q'
fact!fact:
00401000 55              push    ebp
00401001 8bec            mov     ebp,esp
00401003 837d0801        cmp     dword ptr [ebp+8],1
00401007 7507            jne     fact!fact+0x10 (00401010)

fact!fact+0x9:
00401009 b801000000      mov     eax,1
0040100e eb13            jmp     fact!fact+0x23 (00401023)

fact!fact+0x10:
00401010 8b4508          mov     eax,dword ptr [ebp+8]
00401013 83e801          sub     eax,1
00401016 50              push    eax
00401017 e8e4ffffff      call    fact!fact (00401000)
0040101c 83c404          add     esp,4
0040101f 0faf4508        imul    eax,dword ptr [ebp+8]

fact!fact+0x23:
00401023 5d              pop     ebp
00401024 c3              ret
quit:

假设在输入函数时N == 5,即[ebp + 8]将保持5 只要[ebp + 8]> 1 jne将被采取

这里你可以看到N递减(sub eax,1) 递减的N再次传递给函数事实(在没有返回调用者的情况下递归)循环再次发生,并且递减的N重新发送到事实这继续发生直到没有采用直到N或[ebp + 8] ] == 1

当N变为1时,不采用jne但采用jmp 401023 在它返回调用者的地方,调用者是函数fact(int N)

即它将返回40101c,其中eax的乘法发生,结果存储回eax;

这将继续发生,直到ret指向main()中的第一个调用,在第一次执行pop ebp之前看到下面的堆栈

0:000> kPL
ChildEBP RetAddr  
0013ff38 0040101c fact!fact(
            int N = 0n1)+0x23
0013ff44 0040101c fact!fact(
            int N = 0n2)+0x1c
0013ff50 0040101c fact!fact(
            int N = 0n3)+0x1c
0013ff5c 0040101c fact!fact(
            int N = 0n4)+0x1c
0013ff68 0040109f fact!fact(
            int N = 0n5)+0x1c
0013ff78 0040140b fact!main(
            int argc = 0n2, 
            char ** argv = 0x00033ac0)+0x6f

答案 1 :(得分:1)

我认为最好的方法是手动处理代码。假设您调用factorial(4),会发生什么?4不等于1.返回4 * factorial(4-1)。

阶乘3的回报值是多少? 3不等于1返回3 *阶乘(3-1)。

阶乘2的回报价值是多少? 2不等于1返回2 *阶乘(2-1)。

阶乘1的回报值是多少? 1等于1是真的。返回1.这是基本情况。现在我们重新开始递归。 返回1.这是因子(2-1) 返回2 * 1。这是阶乘(3-1) 返回3 * 2这是阶乘(4-1) 返回4 * 6这是因子(4),你做的原始电话。

这个想法是你有一个具有基本情况的函数(当n = 1返回1时)并且函数调用自身的方式将函数移向基本情况(factorial(n ** - ** 1)) 。