1. 程式人生 > >對遞迴執行過程的簡單描述

對遞迴執行過程的簡單描述

#include <stdio.h>  
  
void fun(int n)  
{  
    printf("1th - Level: %d  Address: %d\n", n, &n);  
    if(n < 3)  
        fun(n+1);  
    printf("2th - Level: %d  Address: %d\n", n, &n);  
}  
  
int main()  
{  
    fun(1);  
    return 0;  
}  

輸出結果為:


分析

1) 主函式呼叫fun(1);

2) 此時n的值為1,隨即輸出第一行,並得到n的地址並將其抽象為aaaa;

3) 判斷,1 < 3,執行遞迴語句, 重新執行fun函式;

4) 由於傳遞引數為n+1,所以本層n的值為2,隨即輸出第二行,並得到n的新地址將其抽象為bbbb;

5) 判斷,2 < 3,執行遞迴語句, 重新執行fun函式;

6) 同理可得本層n的值為3,得到第三行結果,並將n的新地址抽象為cccc;

7) 判斷,3 < 3不成立,不執行遞迴, 直接執行第二條輸出語句,即輸出第四行結果,此時顯示n的地址為cccc,容易理解;

8) 本層結束,返回上一層斷點處繼續執行,即n為2的那一層,當時程式去已經執行遞迴,所以接下來執行第二次輸出,即得到第五行輸出結果,此時n的地址顯示為bbbb;

9) n為2時的一層執行結束,返回上一層,即n為1,當時程式去已經執行遞迴,所以接下來執行輸出語句,即得到第六行輸出結果,此時n的地址顯示為aaaa;

程式結束。

總結:

1. 每一級的遞迴都使用它自己的私有的變數n,可以檢視地址的值來證明。

2. 每一次函式呼叫都會有一次返回.當程式流執行到某一級遞迴的結尾處時,它會轉移到前一級遞迴繼續執行。

3. 位於遞迴呼叫語句前的語句的執行順序和各個被呼叫函式的順序相同,位於遞迴呼叫語句後的語句的執行順序和各個被呼叫函式的順序相反。

4. 遞迴函式中必須包含可以終止遞迴呼叫的語句來避免死迴圈。


輸出結果為:


分析

1) 主函式呼叫fun(1);

2) 此時n的值為1,隨即輸出第一行,並得到n的地址並將其抽象為aaaa;

3) 判斷,1 < 3,執行遞迴語句, 重新執行fun函式;

4) 由於傳遞引數為n+1,所以本層n的值為2,隨即輸出第二行,並得到n的新地址將其抽象為bbbb;

5) 判斷,2 < 3,執行遞迴語句, 重新執行fun函式;

6) 同理可得本層n的值為3,得到第三行結果,並將n的新地址抽象為cccc;

7) 判斷,3 < 3不成立,不執行遞迴, 直接執行第二條輸出語句,即輸出第四行結果,此時顯示n的地址為cccc,容易理解;

8) 本層結束,返回上一層斷點處繼續執行,即n為2的那一層,當時程式去已經執行遞迴,所以接下來執行第二次輸出,即得到第五行輸出結果,此時n的地址顯示為bbbb;

9) n為2時的一層執行結束,返回上一層,即n為1,當時程式去已經執行遞迴,所以接下來執行輸出語句,即得到第六行輸出結果,此時n的地址顯示為aaaa;

程式結束。

總結:

1. 每一級的遞迴都使用它自己的私有的變數n,可以檢視地址的值來證明。

2. 每一次函式呼叫都會有一次返回.當程式流執行到某一級遞迴的結尾處時,它會轉移到前一級遞迴繼續執行。

3. 位於遞迴呼叫語句前的語句的執行順序和各個被呼叫函式的順序相同,位於遞迴呼叫語句後的語句的執行順序和各個被呼叫函式的順序相反。

4. 遞迴函式中必須包含可以終止遞迴呼叫的語句來避免死迴圈。