2011-12-20 7 views
1

人!長いコードを短くする

次のコードを宿題として作成するように指示されました。 コンパイルした場合、その目的がわかります。さて、私の質問は、それをもっと短くする方法があるかどうかです(私はC言語を初めて使っています)。私は構造体と構造体ポインタを使用する必要があります。これは残念な質問と思われるかもしれません - 申し訳ありません。 また、「main()」を繰り返し呼び出すことが大丈夫かどうかを知りたいと思います。ここで

#include <stdio.h> 

typedef struct frac{ 
    int num; 
    int den; 
}; 

int reducer(struct frac *fi){ 
    if(fi->num == 0) return 0; 
    if(fi->den == 1) return 1; 
    if(fi->num % fi->den == 0){ 
     fi->num /= fi->den; 
     fi->den /= fi->den; 
     return reducer(fi); 
    } 
    if(fi->num % 2 == 0 && fi->den % 2 == 0){ 
     fi->num /= 2; 
     fi->den /= 2; 
     return reducer(fi); 
    } 
    else if(fi->num % 3 == 0 && fi->den % 3 == 0){ 
     fi->num /= 3; 
     fi->den /= 3; 
     return reducer(fi); 
    } 
} 

int main(){ 
    char c , tt; 
    struct frac one , two , multi , quot , sum , diff , *o , *t , *m , *q , *s , *d; 
    printf("Please, enter the first fraction, ieg. 3/8:\n"); 
    scanf("%d/%d%c" , &one.num , &one.den , &tt); 
    printf("Now the second fraction (numerator/denominator):\n"); 
    scanf("%d/%d%c" , &two.num , &two.den , &tt); 
    o = &one; 
    t = &two; 
    m = &multi; 
    q = &quot; 
    s = &sum; 
    d = &diff; 
    m->num = o->num * t->num; // product numerator 
    m->den = o->den * t->den; // product denominator 
    q->num = o->num * t->den; // quotient numerator 
    q->den = o->den * t->num; // quotient denominator and so on... 
    s->num = q->num + q->den; 
    s->den = m->den; 
    d->num = q->num - q->den; 
    d->den = m->den; 
    reducer(q); 
    reducer(m); 
    reducer(s); 
    reducer(d); 
    printf("%d/%d + %d/%d = %d/%d\n" , o->num , o->den , t->num , t->den , s->num , s->den); 
    printf("%d/%d - %d/%d = %d/%d\n" , o->num , o->den , t->num , t->den , d->num , d->den); 
    printf("%d/%d * %d/%d = %d/%d\n" , o->num , o->den , t->num , t->den , m->num , m->den); 
    printf("%d/%d : %d/%d = %d/%d\n" , o->num , o->den , t->num , t->den , q->num , q->den); 
    printf("\nWould you like to make another calculation? (y/n):\n"); 
    scanf("%c" , &c); 
    if(c == 121 || c == 89){ 
     return main(); 
    } 
    return 0; 
} 
+1

私は考えています*この種の質問は、stackoverflowではなくcodereviewに属します。確かにわからない – MByD

+1

*コンパイルした場合、その目的は簡単にわかります。*どうしてですか?他の方法ではなく、私たちが助けてくれる場所を説明するのはあなたの義務です。 – Constantinius

+1

'main()'の呼び出しはC++では違法ですが、C言語でも許されていますが、それは良い考えではありません。あなたの推論には根本的に欠陥があります。 'while'ループがあります。 –

答えて

1

いくつかの提案は以下のとおりです。

  • ではなく、再帰のループを使用してください。それは、このシナリオでは、より自然だし、それは、スタックは、各反復と一緒に成長がありません:

    int finish; 
    do 
    { 
        //... 
        printf("\nWould you like to make another calculation? (y/n):\n"); 
        scanf("%c" , &c); 
        finish = c != 121 && c == 89; 
    } 
    while (!finish) 
    
  • あなたはすべてのポインタの宣言を削除し、分画そのものを直接操作することができます。

    multi.num = one.num * two.num; // product numerator 
    // ... 
    reducer(&quot) 
    

それが役に立てば幸い!

1

これは間違っています。それは分数21/49を減らすことができますか?それは見えません。減速機機能は必ずしも復帰しない。レデューサー関数では、それ以上分割できなくなるまで、上位と上位の分母(tip:whileループを使用)を計算する必要があります。

メイン再帰が機能します。しかし、これは本当に悪い習慣であり、乱雑なコードで終わる傾向があります。あなたが再帰の後にそのreturn 0の前に何かを置くと、あなたのコードは狂った動作を始めます。代わりにwhileループまたはdo ... whileループを使用してください。

さらに、メイン関数内にいくつかの変数があることを避けることができます。

+0

もし私が1/199982239283の割合を持っていたなら、それは高次分母と高次分母のループを作るのに合理的でしょうか? –

+0

まあ、実際にループはmin(num、den)に行きます。しかし、あなたが5367545/18367213のようなものを持っているなら、これはまだ理想とはかけ離れています。理想的には、LCM機能を実装する必要があります。 –

関連する問題