2017-05-29 145 views
0

我想了解如何在C中使用遞歸,但我無法得到return如何工作。在遞歸函數中返回

請考慮下面的代碼:

int  recur(int i) 
{ 
    printf("recur: i = %d\n", i); 
    if (i < 3) 
    { 
     recur(i + 1); 
     return 10; 
    } 
    else if (i < 5) 
     recur(i + 1); 
    return i; 
} 

int  main(void) 
{ 
    int  i = 0; 
    i = recur(i); 
    printf("i = %d\n", i); 
    return 0; 
} 

輸出是:

recur: i = 0 
recur: i = 1 
recur: i = 2 
recur: i = 3 
recur: i = 4 
recur: i = 5 
i = 10 

是什麼最後的回報,return i,怎麼辦?這段代碼甚至有意義嗎?

+3

在遞歸函數中,遞歸調用返回的值會發生什麼?你只需把它們扔掉。另外,我建議你使用調試器來遍歷代碼,進入遞歸調用,看看會發生什麼。 –

+0

對不起,我的意思是'返回我'不'返回0' ...我編輯我的代碼 – nounoursnoir

+3

編寫一個沒有用處的函數,並且你會從中學到很多有用的東西。 –

回答

2

對函數的遞歸調用不會影響返回值。在遞歸函數的第一個實例中只會遇到第一個return將向父函數返回一個值。任何其他return會見只會停止功能的情況下目前的計劃是英寸

因此,當函數被調用主用參數0

int  i = 0; 
i = recur(i); 

遇到的第一個return所在的if聲明內:

if (i < 3) 
{ 
    recur(i + 1); 
    return 10; 
} 

在這種情況下,recur函數的值返回到main之前調用。它會創建recur的另一個實例,它將執行一些操作,但在recur的此實例結束之後,將繼續主要實例recur,在此情況下,將返回10到函數main

知道你的遞歸函數將返回main功能,你可以簡單地評論調用所有功能的新實例:

int  recur(int i) 
{ 
    if (i < 3) 
    { 
     //recur(i + 1); 
     return 10; 
    } 
    else if (i < 5) 
    { 
     //recur(i + 1); 
    } 
    return i; 
} 

在這種情況下,這是程序將改爲:

int  recur(int i) 
{ 
    if (i < 3) 
     return 10; 
    return i; 
} 
+0

你的意思是隻有返回的「主要實例」的遞歸函數很重要?而其他的只是一種退出遞歸函數的第N個實例的方法,而沒有實際返回任何東西到'main'? – nounoursnoir

+0

@nounoursnoir你說得對。我認爲這個函數有一個錯誤,那就是它的設計不正確。 –

+0

好的,謝謝,這是我的答案。 – nounoursnoir

-1

返回0是來自主函數的返回值,而不是來自您的遞歸代碼。

+0

抱歉的人,我的意思是'返回我'不'返回0' ...我編輯我的代碼 – nounoursnoir

0

我覺得這是最容易理解的遞歸函數之一。

int pow(int n, int x) 
{ 
    if (n != 1) 
     return pow(n - 1, x * x) 
    else 
     return x; 
} 

讓我們研究pow(3, 2) : 2^3 = 2 * 2 * 2 = 8

第一次迭代:pow(3, 2) returns pow(2, 4)
第二次迭代:pow(2, 4) returns pow(1, 8)
第三次迭代:n == 1所以pow(1, 8) returns x = 8

遞歸函數在i + 1步驟返回調用自身處理。爲了避免無限循環,你必須讓你有一個休息條件,這會導致返回與自己不同的事情。

0

您至少得到了一個有助於解釋代碼行爲的答案。

我想通過其他路徑提供幫助。兩者一起爲您提供不同的觀點。
爲此,我提供了一個由儀器增強的代碼版本,它可以更詳細地告訴您發生了什麼。
這允許你玩代碼並觀察,這會給你真正有用的答案。

注:

  • for(c線僅用於暗示縮進;
    我選擇不使用此功能,感覺它使有趣的函數調用
  • 我加了一個參數「嵌套」更加突出,它是
    • 使(希望有用)的一部分輸出
    • 顯示,通常遞歸嵌套有一定的影響
  • 我介紹了一個局部變量「J」,
    顯示什麼用reutrn值在大多數情況下
  • 發生

代碼:

#include <stdio.h> 

int  recur(int i, int nesting) 
{ int c; 
    for(c=0;c<nesting;c++) { printf(" ");} 
    printf("recur[%d](%i)", nesting, i); 
    if (i < 3) 
    { printf("i <3, calling recur[%d](%d)\n", nesting+1, i+1); 
     recur(i + 1, nesting+1); 
     for(c=0;c<nesting;c++) { printf(" ");} 
     printf("returning 10 from recur[%d], with i==%d\n", nesting, i); 
     return 10; 
    } 
    else if (i < 5) 
    { 
     int j=0; 
     printf("i <5, calling recur[%d](%d)\n", nesting+1, i +1); 
     j=recur(i + 1, nesting+1); 
     for(c=0;c<nesting;c++) { printf(" ");} 
     printf("ignored return value from recur[%d](%d) is %d", nesting+1, i+1, j); 
    } 

    printf("\n"); 
    for(c=0;c<nesting;c++) { printf(" ");} 
    printf("returning i from recur[%d], with i==%d\n", nesting, i); 
    return i; 
} 

int  main(void) 
{ 
    int  i = 0; 
    i = recur(i, 0); 
    printf("the last return value did not get ignored: i = %d\n", i); 
    return 0; 
} 

輸出:

recur[0](0)i <3, calling recur[1](1) 
    recur[1](1)i <3, calling recur[2](2) 
    recur[2](2)i <3, calling recur[3](3) 
     recur[3](3)i <5, calling recur[4](4) 
     recur[4](4)i <5, calling recur[5](5) 
      recur[5](5) 
      returning i from recur[5], with i==5 
     ignored return value from recur[5](5) is 5 
     returning i from recur[4], with i==4 
     ignored return value from recur[4](4) is 4 
     returning i from recur[3], with i==3 
    returning 10 from recur[2], with i==2 
    returning 10 from recur[1], with i==1 
returning 10 from recur[0], with i==0 
the last return value did not get ignored: i = 10 

注:
recur[n](m)當然沒有C語法。
它只是表示在參數「m」的嵌套級別「n」上調用函數「recur」。
(特別是不要將「[]」與數組混淆,它們不存在。)