Укоротить длинный код - PullRequest
1 голос
/ 20 декабря 2011

люди!

Мне сказали создать следующий код как домашнее задание. Если вы скомпилируете его, вы легко увидите его назначение. Теперь мой вопрос: есть ли способ сделать его короче (я новичок в 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;
}

Ответы [ 2 ]

1 голос
/ 20 декабря 2011

Это неправильно. Это может уменьшить долю 21/49? Это не похоже на. Функция редуктора не всегда возвращается. В функции редуктора вам нужно будет вычислять все больший и больший знаменатели (совет: используйте цикл while), пока он не может быть разделен.

Основные рекурсивные работы. Но это действительно плохая практика, которая приводит к грязному ошибочному коду. Если вы поместите что-нибудь до этого return 0 после рекурсии, ваш код начнет вести себя сумасшедшим. Вместо этого используйте цикл while или do ... while.

Кроме того, вы можете избежать некоторых переменных в основной функции.

1 голос
/ 20 декабря 2011

Вот несколько предложений:

  • Используйте цикл вместо рекурсии. В этом сценарии это более естественно, и стек не увеличивается с каждой итерацией:

    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)
    

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...