2015-07-20 55 views
0

我想了解下面的程序,其中遞歸函數調用存在,但越來越困惑,而跟蹤如何加載大頭釘。難以理解連續遞歸調用

void func(char*); // function prototype 

int main(){ 
    func("123"); 
    return 0; 
} 

void func(char a[]){ 
    if(a[1]=='\0') 
     return; 
    func(a+1); 
    func(a+1); 
    printf("%c",a[1]); 
} 

的輸出,這是3 3 2

希望如果有人能在這一個建議......

做這種多次遞歸調用以任何方式有益的或發現的應用具體問題領域..?

+2

這是最經常使用的例如用於遞歸(未的網站,但Fibonacci數計算)::http://www.programmingsimplified.com/c-program執行NTF陳述可以通過這個公式獲得-generate-fibonacci-series – RhinoDevel

+0

的確,我使用斐波那契計算作爲一個面試問題,要求候選人創建一個迭代和遞歸的解決方案。 –

回答

1

使用斷點調試是瞭解遞歸的一種方法。另一種方法是繪製遞歸調用樹。

Recursive calls tree

從圖中,在0級後,每一級,每兩個節點由於的這兩行代碼後發生的printf語句:

func(a+1); 
func(a+1); 

在一般情況下,這將成爲一個完美的二進制樹的長度大於0的任何輸入字符串。節點的總數由以下公式給出:

2^(k+1) - 1 // k is the depth; here k = 2 

pri

2^k - 1 // For k=2, there will be 3 printf statements each printing 3,3,2 respectively 
2

只需將自己置於CPU的位置並逐行執行(或使用調試器來完成該任務)。

第一呼叫是

func("123") 

此呼叫不滿足終止條件a[1] == '\0',所以它調用

func("23"); 

以進而FUNC( 「23」)的呼叫調用

func("3") 

哪些能滿足退貨條件。所以,該調用返回到前一個調用者func(「23」)。

FUNC(「23」)進行撥打另一個電話,以FUNC(「3」)由於線路

func(a+1); 
func(a+1); 

繼續在你的頭腦執行程序的過程中,並寫下來會是什麼每次致電printf。這將解釋你的輸出。

UPDATE

注意,調用printf()發生遞歸調用,所以如到

FUNC( 「123」)的調用

會繼續像

  • 輸入FUNC( 「123」)
  • 終止條件沒有得到滿足
  • 呼叫FUNC( 「23」)
  • 呼叫FUNC( 「23」)再次
  • printf的( 「3」)(其爲[1])
  • 返回
+0

感謝@Eric,以及如何將printf函數調用與調用func()..相關聯? –

+1

對於每次調用func(),只要func()的參數由於if(a [1] =='\ 0')返回而超過一個字符長度,printf()將最終被調用; 。棘手的部分是在兩次調用func(a + 1)後調用printf()*。這真的歸結爲「玩CPU」,並逐步完成。這可能有助於在紙上打印出來,並使用鉛筆逐行進行打印。如果您使用鉛筆,請記下每個電話的func()參數以幫助您保持跟蹤。 –

1

發佈的代碼是一個相當差的遞歸實例。

以下代碼具有正確的「尾」形式的遞歸。

將反轉的字符串傳回給main並讓main打印它可能會更好。

它顛倒的字符串傳遞給FUNC()由訂單的main()

請詢問運行時的問題,郵編編譯,包括頭文件所需的#includes時候,所以我們不猜測其標頭包括

#include <stdio.h> 

void func(char*); // function prototype 

int main(){ 
    func("123"); 
    return 0; 
} 

void func(char a[]) 
{ 
    if(a[1]=='\0') // check for end of recursive sequence 
    { 
     printf("%c", a[0]); // last tail action 
     return; 
    } 

    func(a+1); // step+next recursion 
    printf("%c", a[0]); // tail action 
    return; 
} 
0

遞歸可以簡單地理解如下。

例如:

Func(int a){ 
    while(a>1) 
     return a * func(a-1); 
} 

假設a = 5

會發生什麼,它返回5 * func(4)

現在func(4)返回4 * func(3)它會繼續如此。

結賬this example for use of recursion in fibonacci series