【问题标题】:How this recursive function returns a value to main?这个递归函数如何将值返回给 main?
【发布时间】:2014-10-12 13:52:54
【问题描述】:

我花了几个小时试图弄清楚为什么即使 return 语句仅在 if(基本情况)内,这个递归函数仍然有效。

#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 语句,然后将 1 除以 10 = 1 的余数分配给 @ 987654326@。 Last_digit (1) 添加了递归调用,将 1/10=0 发送到 sum_recursive_function。这次sum_recursive_function 检查参数是否等于 0,如果等于 0,则返回 sum_pre 为 0。Sum_pre 是 = 1 + 0。然后我不明白 @987654332 是怎么回事@ 将 Sum_pre (1) 返回到 main。

【问题讨论】:

  • 如果你不指定返回值并且控制权传递到函数的末尾,许多编译器将返回堆栈中发生的任何内容——在这种情况下,它将是最后计算的值, sum_pre。不过,这是未定义的行为——您应该始终使用 return 语句将值传递到函数之外。

标签: c recursion


【解决方案1】:

您的代码表现出未定义的行为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 );
    }
}

也许正确的代码能让你更好地理解这一点。

【讨论】:

  • 所以我根本不需要 sum_pre,我从 else 语句中立即返回整个内容。现在清楚了,谢谢!
【解决方案2】:

实际上,即使按照最初的定义,sum_recursive_function 也总是返回一个值。

让我试着解释一下这一行发生的递归(这就是魔法所在):

sum_pre = last_digit + sum_recursive_function( number_copy / 10 );

假设输入参数为数字:12345
检查那些迭代:

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 处,递归结束。

我希望这有助于更好地理解递归!

【讨论】:

    【解决方案3】:

    即使没有 return 语句(在这种情况下是偶然的)代码也能工作的原因是因为根据 x86 调用约定,函数的返回值(更具体地说是整数或指针)存储在 EAX 寄存器中.因此,一旦函数存在,EAX 寄存器中的最后一个值都会作为函数的返回值。

    您可以通过将此内联程序集附加到递归函数的末尾来进行测试。

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

    现在您的程序将始终打印 5 而不是实际的总和。

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

    【讨论】:

      猜你喜欢
      • 2012-04-24
      • 1970-01-01
      • 2013-02-17
      • 2023-03-11
      • 1970-01-01
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多