程序崩溃和编码中算术运算的一些问题

时间:2016-05-10 17:34:40

标签: c

您好stackoverflow社区!我的代码遇到了一些问题。我现在是学生,所以基本上我是初学者。使用欧几里得算法,下面显示的代码应该除以两个数字,直到商达到0,但它只是在商转0之前的最后一个分割过程中停止。我不知道程序是否会因此而崩溃。希望你们有一个初学者友好的回复。谢谢! (对不起,如果已经存在这样的问题)

以下是代码:

int quotient,quotient2,remainder,remainder2,x,y;

int foo()
{
    printf("Enter a number: ");
    scanf("%d", &x);
    printf("Enter another number: ");
    scanf("%d", &y);

    if(y >= x){
        quotient2 = y / x;
        remainder2 = y % x;
        printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2);

        if(quotient2 != 0){
            do{
                y = x;
                x = remainder2;
                quotient2 = y / x;
                remainder2 = y % x; 
                printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2); 
            } while(quotient2 != 0);    
        }
    } else if(x > y){
        quotient = x / y;
        remainder = x % y;
        printf("%d = %d(%d) + %d\n", x,y,quotient,remainder);

        if(quotient != 0){
            do{
                x = y;
                y = remainder;
                quotient = x / y;
                remainder = x % y;
                printf("%d = %d(%d) + %d\n", x,y,quotient,remainder);
            } while(quotient != 0);
        }
    }

    system("pause");
    return 0;
}

2 个答案:

答案 0 :(得分:3)

如果你的"欧几里得算法"正在计算两个数字的GCD,这是一种方法。注意它不除以0,当除数为0时停止。

所以重点是,无论如何防止除以0,无论如何都是迭代的结束条件。

#include <stdio.h>

unsigned gcd(unsigned x, unsigned y) {
    unsigned z;
    if (x == 0 || y == 0) {
        return 0;
    }
    while ((z = y % x) != 0) {
        y = x;
        x = z;
    }
    return x;
}

int main(void)
{
    printf("20 ~ 20 : %u\n", gcd(20, 20));
    printf("20 ~ 0  : %u\n", gcd(20,  0));
    printf(" 0 ~ 20 : %u\n", gcd( 0, 20));
    printf("20 ~ 16 : %u\n", gcd(20, 16));
    printf("16 ~ 20 : %u\n", gcd(16, 20));
    printf("20 ~ 15 : %u\n", gcd(20, 15));
    printf("15 ~ 20 : %u\n", gcd(15, 20));
    printf(" 1 ~  2 : %u\n", gcd( 1,  2));
    printf(" 2 ~  1 : %u\n", gcd( 2,  1));
    return 0;
}

节目输出:

20 ~ 20 : 20
20 ~ 0  : 0
 0 ~ 20 : 0
20 ~ 16 : 4
16 ~ 20 : 4
20 ~ 15 : 5
15 ~ 20 : 5
 1 ~  2 : 1
 2 ~  1 : 1

注意不需要交换参数。该算法无论在哪个方向都可以工作。

答案 1 :(得分:2)

请注意,对于x = remainder2;x可以采用0的值。然后下一个quotient2 = y / x; remainder2 = y % x;执行操作(除以0和余数0),这两个操作都是未定义的行为。程序崩溃当然是由于这个原因。

if(y >= x){
    quotient2 = y / x;
    remainder2 = y % x;
    printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2);

    if(quotient2 != 0){
        do{
            y = x;
            x = remainder2;
            quotient2 = y / x;
            remainder2 = y % x; 
            printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2); 
        } while(quotient2 != 0);    
    }

由于代码在每个操作中交换x,y的角色,因此代码可以简化为:(另请参阅What is gcd(0,a)gcd(0,a), where a is a positive integer?

unsigned gcd(unsigned a, unsigned b) {
  while (b) {
    a %= b;
    if (a == 0) return b;
    b %= a;
  }
  return a;
}