递归函数的输出不正确,以计算数字的位数之和

时间:2011-08-12 19:13:02

标签: c algorithm recursion

我试图编写一个函数来计算使用递归计算数字位数的总和,但输出不正确。这是代码:

/*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);
}

以下是一些输出值:

 udit@udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
 Enter the number:123
 The sum of the digits of the number is 7

 udit@udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
 Enter the number:1234
 The sum of the digits of the number is 2919930

 udit@udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
 Enter the number:123456
 The sum of the digits of the number is 4620297

 udit@udit-Dabba ~/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*/

有人可以帮我弄清楚为什么这不能正常工作吗?

5 个答案:

答案 0 :(得分: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,这些变量都完全相互独立。该值不是通过它们传递的。如果要在递归函数之间传递值,最好的方法是使用递归调用的返回值,或者(如果必须)通过递归指针将指针传递给某个值。

希望这有帮助!

答案 1 :(得分:4)

当a为0时,您将返回未初始化的值(f未初始化)。

将其更改为:

if (a == 0)
        return 0;

您还忘记了函数末尾的返回:

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

强烈建议您始终使用标志-Wall进行编译,这会警告您这些错误。

答案 2 :(得分:2)

你的递归函数将不计算它返回未初始化的int或什么都没有。你需要在函数中返回你正在做的工作。

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

您只返回f是0,但如果不是,则返回值未定义。我想你想做:

int sum (int a) {

    int f;

    if (a == 0)
        return 0;

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

    return f;
}