我在使用递归函数调用时何时使用“ 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)函数的两种情况下都需要返回?
答案 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。