2016-05-10 11 views
-2

こんにちは、stackoverflowコミュニティ!私は自分のコードにいくつか問題があります。私は現在学生ですので、基本的に私は初心者です。ユークリッドアルゴリズムを使用すると、下に示すコードは、商が0に達するまで2つの数値を除算し、除算する必要がありますが、商が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

CとC++ 2つの異なる言語である - いずれかを選択 – PaulMcKenzie

+0

。あなたのコードをデバッグしようとしましたか? – wimh

+3

'do ... while'ループで、' remainder = x%y; 'の結果が0ならば、次の繰り返しでゼロ除算 –

答えて

3

あなたの「ユークリッドアルゴリズムは、」2つの数の最大公約数を計算している場合は、ここでそれを行うための一つの方法は次のとおりです。

(すでにこのような既存の問題があるかどう申し訳ありません)ここでは、コードです。 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 

注意引数を交換する必要はありません。アルゴリズムはどのような方法でも動作します。

+0

条件付きチェックにおける恥ずかしそうな変数の割り当て(while)?笑。私はそれが生成する警告を取り除くために、かっこをいくつか追加しました。 –

+0

@MichaelDorganはあなたの提案を修正しましたが、私は最初の投稿を「慣用的」と呼びます。私はブール値テストでは明示的ではなく、 'true'と' false'を使うことはありません。警告はありません。 –

+0

もちろん、宿題のままでこれを変えれば、彼はかなり説明することになるでしょう... –

2

x = remainder2;では、x0の値をとる可能性があることに注意してください。次に、次の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; 
}