在使用递归函数调用时,何时使用“返回”?

时间:2019-10-21 06:37:32

标签: c function recursion

我在使用递归函数调用时何时使用“ return”感到困惑。

我正在尝试找到两个数字的“ GCD(最大公约数)”。我实际上认为可行的是:

  include <stdio.h>
  int gcd (int a, int b);

  int main ()
  {
   int a, b;
   printf ("Enter two numbers \n");
   scanf ("%d %d", &a, &b);
   printf ("GCD for numbers %d and %d is %d\n", a, b, gcd(a,b));
   return (0);
   }

   int gcd (int a, int b)
   {
    while (a!=b)
     {
      if (a > b)
       gcd(a-b,b);
      else if (b > a)
       gcd(a,b-a);
     }
    return (a);
   }

但是上面的代码不断从终端接受数字,并且无法运行代码。

但是,当我按如下所示替换函数定义时,代码按预期方式工作,返回正确的值。

   int gcd (int a, int b)
   {
    while (a!=b)
     {
      if (a > b)
       return gcd(a-b,b);
      else if (b > a)
       return gcd(a,b-a);
     }
    return (a);
   }

如您所见,唯一的变化是在递归函数调用之前添加了“ return”。为什么在我调用gcd(arg1,arg2)函数的两种情况下都需要返回?

2 个答案:

答案 0 :(得分:3)

  

为什么在我调用gcd(arg1,arg2)函数的两种情况下都需要返回?

出于同样的原因,您需要在其他任何时间调用函数,并希望返回该函数调用返回的值;因为调用它只会调用它,并且对结果值不做任何其他操作。

  

我在使用递归函数调用时何时使用“ return”感到困惑。

每当您将return用于任何其他函数调用时,即使用return进行递归调用,即:该调用何时以及由于该原因返回您希望这次返回的值。 / p>

想象一下我们有

#include "magic.h" /* defines gcd2(), which computes GCD in some mysterious way */

然后,我们不进行递归调用,而是将一些工作委托给该工作:

/* Of course this solution also works, but is not interesting
int gcd(int a, int b)
{
    return gcd2(a, b);
} */

/* So, let's do something that actually shows off the recurrence relation */
int gcd(int a, int b)
{
    if (a > b)
        return gcd2(a-b, b);
    else if (b > a)
        return gcd2(a, b-a);
    else
        return a;
}

(我还删除了while循环,因为它与算法无关;当然,在每种情况下都达到了return,这打破了循环。)

我认为我不需要复习数学理论;而且我也很清楚,return结果为什么需要gcd2

但是实际上并不重要如何委派作品;如果gcd是可以正确计算GCD的函数,并且gcd2也是这样,则对gcd2的调用可以由对gcd的调用代替。这就是秘密-递归调用函数与正常调用函数实际上没有什么不同。只是考虑到这种可能性,就需要对调用函数的工作方式以及其实际功能有更清楚的了解。


当然,也可以充分利用原始的while循环-通过在进行递归之前尽可能地减去 。可能看起来像:

int gcd(int a, int b)
{
    if (a > b)
        while (a > b)
            a -= b; /* prepare a value for the recursion. */
        return gcd(a, b); /* and then recurse with that value. */
    else if (b > a)
        while (b > a)
            b -= a; /* similarly. */
        return gcd(a, b);
    else /* a == b */
        return a;        
}

但是,我们不妨一路将其转换为迭代方法:

int gcd(int a, int b)
{
    while (a != b)
        /* whichever is greater, adjust it downward, leaving an (a, b)
           pair that has the same GCD. Eventually we reach an equal pair,
           for which the result is known. */
        if (a > b)
            a -= b;
        else
            b -= a;
    return a; /* since the loop exited, they are equal now. */
}

(而且我们也可以做模运算来一次完成多次减法,这是一个练习。)

答案 1 :(得分:0)

第一个gcd函数“尝试”计算gcd,但最后总是返回未更改的a

第二个gcd函数递归计算gcd,每次调用都会返回一个gcd。