为什么我的C语言GCD程序没有运行?

为什么我的C语言GCD程序没有运行?,c,algorithm,function,recursion,greatest-common-divisor,C,Algorithm,Function,Recursion,Greatest Common Divisor,我试图用欧几里德算法在C(递归)中找到两个数的GCD,我知道数学上它还不是完全完美的,因为它忽略了负数条件,但我现在只想让这个对正数有效 #include <stdio.h> int gcd(int m, int n); int main() { return gcd(60, 24); } int gcd(int m, int n) { if (m < n) { //swapping both a and b m = m +

我试图用欧几里德算法在C(递归)中找到两个数的GCD,我知道数学上它还不是完全完美的,因为它忽略了负数条件,但我现在只想让这个对正数有效

#include <stdio.h>

int gcd(int m, int n);

int main() {
    return gcd(60, 24);
}

int gcd(int m, int n) {
    if (m < n) {
        //swapping both a and b
        m = m + n;
        n = m - n;
        m = m - n;
    }
    if (m == n) {
        return m;
    } else {
        return gcd(n, m % n);   
    }
}
#包括
国际货币基金组织(国际货币基金组织,国际货币基金组织);
int main(){
返回gcd(60,24);
}
整数gcd(整数m,整数n){
if(m
gcd(60,24)
->
gcd(24,12)
->
gcd(12,0)

这意味着您需要添加一张支票

if ( n == 0 )
{
   return m;
}

您还可以通过对函数的另一次调用删除变量交换代码,该函数的值在调用中交换

int gcd(int m, int n) {

   if (m < n) {
      return gcd(n, m);
   }

   if (m%n == 0) {
      return n;
   } else {
      return gcd(n, m % n);   
   }
}
intgcd(intm,intn){
if(m
gcd(60,24)
->
gcd(24,12)
->
gcd(12,0)

这意味着您需要添加一张支票

if ( n == 0 )
{
   return m;
}

您还可以通过对函数的另一次调用删除变量交换代码,该函数的值在调用中交换

int gcd(int m, int n) {

   if (m < n) {
      return gcd(n, m);
   }

   if (m%n == 0) {
      return n;
   } else {
      return gcd(n, m % n);   
   }
}
intgcd(intm,intn){
if(m
递归GCD的代码如下所示

int gcd(int m, int n)
{
    if (n==0)
        return m;

    return gcd(n, m % n);
}

不需要交换参数,因为这将由递归处理。例如,考虑<代码> GCD(24, 60)< /代码>。在这种情况下,
n=60
m%n=24%60=24
。因此递归调用是gcd(60,24)
,自动交换参数。

递归gcd的代码如下所示

int gcd(int m, int n)
{
    if (n==0)
        return m;

    return gcd(n, m % n);
}


不需要交换参数,因为这将由递归处理。例如,考虑<代码> GCD(24, 60)< /代码>。在这种情况下,
n=60
m%n=24%60=24
。因此递归调用是
gcd(60,24)
,自动交换参数。

您的终止条件不够广泛;在(实际)算法结束时,m==n并不总是保持不变。示例帮助(例如gcd(4,2)->gcd(2,0)…)是的,这是真的,但是对于所有的正数,它最终会降到零,除了我想知道的主要问题是,为什么这个程序不为gcd(60,24)运行,如果我们遵循欧几里得算法,我很确定它会降到零。嗯,(60,24)->(24,12)->(12,0)。您的算法将继续。这是不好的…大多数情况下最终会达到
(m,0)
作为最终迭代。此时,它需要返回
m
。相反,它将尝试计算
m%0
,这当然会导致错误。将
m==n
条件更改为
n==0
以修复它。非常感谢Pachelbel和@Tom Karzes。尽管我保留了m==n的条件来阻止程序进入计算,因为很明显,如果m==n,gcd将是m。因此,我将只为if(n==0)添加另一个检查,而不是仅仅替换m==n if语句。谢谢你的终止条件不够宽泛;在(实际)算法结束时,m==n并不总是保持不变。示例帮助(例如gcd(4,2)->gcd(2,0)…)是的,这是真的,但是对于所有的正数,它最终会降到零,除了我想知道的主要问题是,为什么这个程序不为gcd(60,24)运行,如果我们遵循欧几里得算法,我很确定它会降到零。嗯,(60,24)->(24,12)->(12,0)。您的算法将继续。这是不好的…大多数情况下最终会达到
(m,0)
作为最终迭代。此时,它需要返回
m
。相反,它将尝试计算
m%0
,这当然会导致错误。将
m==n
条件更改为
n==0
以修复它。非常感谢Pachelbel和@Tom Karzes。尽管我保留了m==n的条件来阻止程序进入计算,因为很明显,如果m==n,gcd将是m。因此,我将只为if(n==0)添加另一个检查,而不是仅仅替换m==n if语句。谢谢d此项应替换
m==n
检查。也就是说,它不是一个添加的检查,而是一个更正的检查。此解决方案每次迭代执行两个
%
操作,而只需要一个操作(除非编译器公共子操作)。更好的解决方案是简单地检查零操作数。更不用说,如果一个操作数为零,这个解决方案就会失败(这是任何好的gcd算法都做不到的)。@TomKarzes,我曾想过使用第一个条件-
if(n==0)返回m。我犹豫了一下,因为我不确定非零数字和零之间的gcd的数学定义是什么。当来自
main
的调用是
gcd(20,0)
时会发生什么。我意识到那个电话会使程序崩溃。尽管如此,问题仍然存在。请看一下用户3386109发布的解决方案。它更简单、更高效。@TomKarzes,它肯定更干净。我不能确定它是否更有效。这应该取代
m==n
检查。也就是说,它不是一个添加的检查,而是一个更正的检查。此解决方案每次迭代执行两个
%
操作,而只需要一个操作(除非编译器公共子操作)。更好的解决方案是简单地检查零操作数。更不用说,如果一个操作数为零,这个解决方案就会失败(这是任何好的gcd算法都做不到的)。@TomKarzes,我曾想过使用第一个条件-
if(n==0)返回m。我犹豫了一下,因为我不确定非零数字和零之间的gcd的数学定义是什么。什么时候发生