【问题标题】:Recursion and return statements in CC中的递归和返回语句
【发布时间】:2013-08-25 03:14:20
【问题描述】:

请解释嵌套递归函数的返回调用如何一直传播到主函数?

我在一本书中遇到了以下代码段。 printf 输出是 '6, 12'

在递归函数sumdig()中,在第三次递归调用中调用return语句。

当 sumdig() 现在返回到第二个递归调用时, sumdig() 应该计算为 表达式,而不是 return 语句(即 return sumdig(n))。

但这似乎并非如此。递归函数的返回调用一直传播到 main。

谁能解释一下嵌套递归函数的返回调用是如何一直传播到main的?

如果递归调用类似于“return sumdig(n)”,那么下面的代码对我来说是有意义的。

main()
{

  int a, b;

  a = sumdig( 123 );
  b = sumdig( 123 );

  printf( "%d, %d\n", a, b);

}

sumdig(int n)
{
  static int s = 0;
  int d;

  if(n != 0)
  {
    d = n % 10;
    n = (n - d) / 10;
    s = s + d;

    sumdig(n);

  }
  else
    return(s);
}

对 Sumdig 的递归调用

Initial call           :n = 123, s = 0
First recursive call   :n = 12,  s = 3
Second recursive call  :n = 1,   s = 5
Third recursive call   :n = 0,   s = 6   // Return statement happens here

同样 对于第二次调用...静态变量将再次增加 6 变为 12。

如果我的问题不清楚,请帮我改进。

【问题讨论】:

  • sumdig 返回什么?一个整数?
  • 您使用的是哪个编译器?编译过程中是否有警告?我得到这样的输出 4199344, 4199344
  • 是的,我从书中提取了代码。 Sumdig 以旧式 K&R 格式声明。所以 return 是一个隐式 int。
  • 在 linux 64 位上使用 gcc。没有警告。

标签: c recursion nested return


【解决方案1】:

返回值是未定义的,因为只有最里面的递归调用返回一个定义的值s。之前对sumdig() 的所有调用都返回一个未定义的值,因为当 sumdig 在没有完全填充 if` 子句的情况下返回时,即从递归调用返回时,没有 return 语句。

因此,如果寄存器中的返回值保持不变,s 可能会传播回来,这可能是,也可能不是。

为了安全起见,递归调用应该是:

return sumdig(n);

【讨论】:

    【解决方案2】:

    这是非常古老的 C 风格。函数的返回值将是函数中最后一次求值的结果(在本例中为 sumdig())。

    【讨论】:

    • noz,我是这么想的。所以我写了一个声明'd = 99;'在 sumdig() 函数的末尾。但是输出仍然是 '6, 12'?
    • @kutichatan:尝试在调试器的帮助下运行程序,您将获得完整的跟踪信息。
    • 奇数 - 也许 d=99 已经被优化了?
    • 刚刚通过调试器运行,在 Eclipse 中具有反汇编视图。 d=99 语句似乎被执行了。
    • 即使在旧式 C 中,函数的返回值也不是最后一个表达式的结果。如果在没有遇到 return 语句的情况下到达函数的末尾,然后您尝试使用该函数的返回值,则行为一直是未定义的。什么是旧风格,但不允许返回 types 给函数。
    【解决方案3】:

    你的问题本身就有答案。静态变量s 更新每个递归,如果条件为假,则只有函数返回主函数。所以 s 的最后更新值返回到 main.

    【讨论】:

    • 不完全是因为 s 仅从底层调用返回(当 n 为 0 时)
    猜你喜欢
    • 2010-10-30
    • 2014-02-03
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 2019-10-07
    • 2021-07-04
    • 2016-02-13
    • 2017-07-21
    相关资源
    最近更新 更多