2015-11-05 83 views
0

我有問題,理解這個代碼:遞歸在C++函數

#include <iostream> 
using namespace std; 

void Print_numm(int numm){ 
    cout<<numm; 
    if (numm<=4) { 
     Print_numm(numm+1); 
    } 
    cout<<numm; 
} 


int main() { 
    Print_numm(1); 
    return 0; 
} 

輸出爲1234554321. 我瞭解遞歸,直到它打印123455.但是,爲什麼編譯器打印的號碼的休息下來1?編譯器是否每次都做第二個「cout」?如果是的話,它如何保持數字,直到他們打印到5,然後向下打印剩下的數字?

+4

由於第二個'cout << numm;',它在每個'Print_numm(numm + 1)'處停止並在其完成時繼續。 – AntiHeadshot

+0

你能詳細說一下嗎? –

+0

你爲什麼不[用調試器進入你的代碼](https://www.youtube.com/watch?v=C0vDKXIq_9A)?或者只用一張紙和一支筆手動追蹤它? – sashoalm

回答

3

您是否熟悉堆棧?

該函數調用自身並向上打印每個數字,然後從最終的遞歸調用返回,向下遍歷數字,因爲它從遞歸中反覆地返回。它只是執行它包含的代碼的其餘部分遞歸調用。

的一個簡單的表示是:

print_numm(1): 
    cout << 1 
    print_numm(1+1): 
     cout << 2 
     print_numm(2+1): 
      cout << 3 
      print_numm(3+1): 
       cout << 4 
       print_numm(4+1): 
        cout << 5 
//now the number is bigger than 4 so the function 
//will return from recursion 
        cout << 5 
//now the function is done,but the function that called print_numm(5) is waiting to finish 
//so it executes the rest of the code printing 4,same with all waiting for print_numm(4) and so on 
       cout << 4 
      cout << 3 
     cout << 2 
    cout << 1 
+0

謝謝!我想如果條件是真的,第二個cout什麼都不做。儘管對我來說這很奇怪,但我應該習慣它。 –

8

如果您直觀調用的執行會比較容易理解:

Print_numm(1) 
-> cout 1 
-> Print_numm(2) 
--> cout 2 
-->Print_numm(3) 
---> cout 3 
---> Print_numm(4) 
----> cout 4 
----> Print_numm(5) 
-----> cout 5 
-----> cout 5 
----> cout 4 
---> cout 3 
--> cout 2 
-> cout 1 
0

功能遞歸從1到5,和這些數字是在第一次調用cout << numm輸出(第一行該Print_numm功能。一旦if語句評估爲false遞歸開始展開,並作爲Print_numm回電話,他們遇到的最後cout << numm行函數的最後一行,並從5打印到1

2

下面的代碼獲取的是如何執行的,你可以很容易地分辨這種方式爲什麼你輸出討論:

Print_numm(1)-> 
    cout<<1 
    Print_numm(2)-> 
     cout<<2 
     Print_numm(3)-> 
      cout<<3 
       Print_numm(4)-> 
       cout<<4 
        Print_num(5)-> 
         cout<<5 
         cout<<5 
       cout<<4 
      cout<<3 
     cout<<2 
    cout<<1 

第二COUT被放置在遞歸調用後,這意味着它將畢竟內得到執行調用返回。

1

你可以看到它會這樣做(假設它返回)。

cout<<1; 
Print_numm(2); 
cout<<1; 

可擴展到:

cout<<1; 
cout<<2; 
Print_numm(3); 
cout<<2; 
cout<<1; 

並最終輸出 「1234554321」。

0

,如果你添加了一些額外的診斷你的代碼的執行會更容易顯現。考慮這種變化:

#include <iostream> 
using namespace std; 

void Print_numm(int numm){ 
    cout << "enter: " << numm << endl; 
    if (numm<=4) { 
     Print_numm(numm+1); 
    } 
    cout << "exit: " << numm << endl; 
} 


int main() { 
    Print_numm(1); 
    return 0; 
} 

主要生產:

enter: 1 
enter: 2 
enter: 3 
enter: 4 
enter: 5 
exit: 5 
exit: 4 
exit: 3 
exit: 2 
exit: 1 

您也可以使用調試器來逐步幫助你更好地理解這種。

一個重要的代碼理解原理。 添加良好的診斷功能大大減少了理解所發生的事情所需的精力和能力。

1

由於條件numm < = 4在numm = 5時變爲false。 因此,numm停止遞增並執行先前調用函數的代碼的其餘部分。