2011-08-12 10 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); 
} 

あなたは正しい軌道に乗っていると、あなたは一般的には正しい考えを持っているが実際の実装は少しバグがあります。まず第一に、のこれらの行を見てみましょう:

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

これは多くの手助けをしています。 ......ありがとうございました –

+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

'返信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); 
} 
関連する問題