2014-10-12 84 views
0

我花了數小時試圖找出爲什麼這個遞歸函數工作,即使return語句只在if(基本情況)內。這個遞歸函數如何將一個值返回給main?

#include<stdio.h> 
int main(void) 
{ 
    int sum_recursive_function(int const number_copy);//function prototype 

    int number, sum_recursive; 

    puts("Please type a number and I will add its digits:"); 
    scanf("%d", &number); 

    sum_recursive = sum_recursive_function(number); 
    printf("%s%d\n", "The sum of the digits is: ", sum_recursive); 
} 

int sum_recursive_function(int const number_copy) 
{ 
    int last_digit, sum_pre = 0; 
    if(number_copy == 0){ 
     return sum_pre; 
    } 
    else{ 
     last_digit = number_copy % 10; 
     sum_pre = last_digit + sum_recursive_function(number_copy/10); 
    } 
} 

我明白這一點: 如果鍵入數字1,該if功能檢查裏面如果number_copy等於0,因爲它是沒有,它進入在else statment,則1的餘數由10 = 1分配給last_digitLast_digit(1)添加遞歸調用,發送1/10 = 0到sum_recursive_function。這次sum_recursive_function檢查參數是否等於0,因爲它等於0,所以返回sum_pre爲0. Sum_pre is = 1 + 0.然後我不明白sum_recursive_function如何返回Sum_pre(1)到main 。

+4

如果不指定返回值和控制傳遞出來的函數結束時,許多編譯器將返回無論發生什麼事是在棧上 - 在這種情況下,這將是最後一個計算值,sum_pre。但這是未定義的行爲 - 您應始終使用return語句將值傳遞給函數。 – antlersoft 2014-10-12 05:15:04

+0

謝謝antlersoft! – user3646717 2014-10-12 05:32:50

回答

2

您的驗證碼爲未定義的行爲sum_recursive_function()需要始終返回一個值。

讓我們來解決這個問題:

int sum_recursive_function(int const number_copy) 
{ 
    if (number_copy == 0) { 
     return 0; 
    } else { 
     int last_digit = number_copy % 10; 
     return last_digit + sum_recursive_function(number_copy/10); 
    } 
} 

也許正確的代碼可以讓你更好地理解這種。

+0

所以我根本不需要sum_pre,並且我從else語句立即返回整個事物。現在清楚了,謝謝! – user3646717 2014-10-12 05:34:27

2

實際上,即使它最初定義爲sum_recursive_function始終返回一個值。

讓我試着解釋說,是在該行發生的遞歸(這其中魔術是):

sum_pre = last_digit + sum_recursive_function(number_copy/10); 

假設輸入參數是多少:12345
檢查這些iterration:

1. sum_pre = 5 + sum_recursive_function(1234); 
2. sum_pre = 5 + 4 + sum_recursive_function(123); 
3. sum_pre = 5 + 4 + 3 + sum_recursive_function(12); 
4. sum_pre = 5 + 4 + 3 + 2 + sum_recursive_function(1); 
5. sum_pre = 5 + 4 + 3 + 2 + 1 + 0; 

在第一步驟last_digit的值是5,對下一個是4,則如圖3所示,然後如圖2所示,然後1. 在迭代#5的遞歸結束。

我希望這有助於更好地理解遞歸!

+1

它有助於加強這個想法,謝謝! – user3646717 2014-10-12 05:35:04

+0

如果您發現我的評論有用,請投票選! – 2014-10-12 05:36:14

2

即使沒有return語句(在這種情況下是偶然的),代碼工作的原因是因爲通過x86調用約定,函數(更具體地說整數或指針)的返回值存儲在EAX中寄存器。因此,只要函數存在,EAX寄存器中的最後一個值就是函數的返回值。

您可以通過將此內聯程序集附加到遞歸函數的末尾來對此進行測試。

asm ("mov $5, %eax"); 

現在你的程序將總是打印5而不是實際的總和。

https://en.wikipedia.org/wiki/X86_calling_conventions