2014-10-12 94 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