2011-08-12 42 views
2

我試圖編寫一個函數來計算使用遞歸的數字的數字總和,但輸出不正確。下面的代碼:遞歸函數的輸出不正確以計算數字的總和

/*Write a function to calculate sum of digits of a number using recursion*/ 
/*Author:Udit Gupta  Date:10/08/2011*/ 

#include<stdio.h> 

int sum (int); 

int main() { 
    int n,s; 

    printf ("Enter the number:"); 
    scanf ("%d",&n); 

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


int sum (int a) { 
    int f; 

    if (a == 0) { 
     return f; 
    } 
    f = (a% 10) + sum (a/10); 
} 

下面是一些輸出值:

[email protected] ~/Desktop/letusc/ch5/J $ ./a2.out 
Enter the number:123 
The sum of the digits of the number is 7 

[email protected] ~/Desktop/letusc/ch5/J $ ./a2.out 
Enter the number:1234 
The sum of the digits of the number is 2919930 

[email protected] ~/Desktop/letusc/ch5/J $ ./a2.out 
Enter the number:123456 
The sum of the digits of the number is 4620297 

[email protected] ~/Desktop/letusc/ch5/J $ ./a2.out 
Enter the number:12345 
The sum of the digits of the number is 15 /*Only this one seems correct*/ 

有人可以幫助我弄清楚這是爲什麼不能正常工作?

+0

對於5位數字的輸出是正確的,但在5位數字的上方和下方輸出是錯誤的結果。 –

+2

輸出是什麼?請編輯您的問題以包含樣本輸入,預期輸出和實際輸出。 –

+2

這不是一個論壇。問題像維基一樣工作。 *請輸出您的問題。* –

回答

5

讓我們來看看這個遞歸函數的詳細信息:

int sum (int a) { 
    int f; 

    if (a == 0) 
     return f; 

    f = (a% 10) + sum (a/10); 
} 

當你在正確的軌道上,必須在一般想法是正確的,你的實際執行是有點bug。首先,讓我們來看看這些行:

if (a == 0) 
    return f; 

你有正確的理念來終止遞歸時a達到零,但你這樣做的方式是有點過。尤其是,您要返回整數f的值,但您從未初始化過它。這意味着返回值是完全任意的。而不是寫這個的,我想你大概意思寫的東西更接近

if (a == 0) 
    return 0; 

其正確說「如果數字是零,其數字的總和是零。」

同樣,看看你的函數的最後一行:

f = (a% 10) + sum (a/10); 

同樣,你的直覺是現貨上:一個數的數字的總和是由它的第一個數字的總和給出和其餘數字的總和。但是,請注意,雖然你正確計算的數字的總和,你不正確返回的數字的總和。事實上,如果你執行這個代碼,你完全不會返回任何東西,所以函數的返回值是未指定的,因此是垃圾輸出。爲了解決這個問題,可以考慮改寫這樣的代碼:

return (a % 10) + sum (a/10); 

這實際上說交還,你剛纔生成這裏的價值,而不是將其存儲在一個局部變量,將盡快立即清理該函數返回。

我相信你用這種方式編碼這個功能的原因是你的印象是int f;的值是通過函數調用傳遞的。不幸的是,事實並非如此。在編寫遞歸函數時,函數的每個實例都與其他實例完全獨立,並且在一次遞歸調用中可訪問的局部變量在其他遞歸調用中不可訪問。因此,即使每次遞歸調用都有其自己的變量int f,這些變量都是完全相互獨立的。價值不是通過他們進行的。如果你想通過遞歸函數傳遞值,最好的方法是使用遞歸調用的返回值,或者(如果你必須的話)通過遞歸傳遞一個指向某個值的指針。

希望這會有所幫助!

+0

ya它有很大的幫助,並且你有正確的觀點,我認爲f正在跨越迭代......非常感謝 –

+1

@Udit Gupta-很高興幫助!如果你認爲這回答你的問題,你應該標記接受的答案,以便問題得到解決。 – templatetypedef

4

當a爲0時,返回一個未初始化的值(f未初始化)。

將其更改爲:

if (a == 0) 
     return 0; 

你也忘了在函數的最後返回:

return (a% 10) + sum (a/10); 

強烈建議您始終與標誌-Wall編譯,這將警告你這些錯誤。

+3

更不用說'sum'結尾處沒有return語句的事實。 –

+0

@Chris:好點,找到第一個後我停止尋找錯誤,我會更新答案。 – fbafelipe

0

你只返回f,它是0,但不是,如果它不是,這會使你的返回值不確定。我想你想做的事:

int sum (int a) { 

    int f; 

    if (a == 0) 
     return 0; 

    f = (a % 10) + sum (a/10); 

    return f; 
} 
1
return a == 0 ? 0 : ((a% 10) + sum (a/10)); 
+0

'return a?a%10 + sum(a/10):0;' –

+0

http://codegolf.stackexchange.com –

2

您的遞歸函數將不計算任何東西,它會返回一個未初始化的int值或不返回任何值。你需要返回你正在做的工作。

int sum (int a) { 
    if (a == 0) { 
    return 0; 
    } 
    return (a% 10) + sum(a/10); 
}