Как избежать вложенных ifs в C?

#c #function #if-statement #struct #nested

#c #функция #if-оператор #структура #вложенный

Вопрос:

У меня есть этот код здесь на C, и я не хочу expCompare иметь вложенных ifs. Я хотел бы спросить, есть ли какой-либо другой способ, кроме этого?

 typedef struct expo Exponent;
struct expo {
    char tag;
    int ex;
    int ey;
    int ez;
};

int expCompare(Exponent alpha, Exponent beta) {
    if (alpha.ex > beta.ex) {
        return 1;
    } else if (alpha.ex == beta.ex) {
        if (alpha.ey > beta.ey) {
            return 1;
        } else if (alpha.ey == beta.ey) {
            if (alpha.ez > beta.ez) {
                return 1;
            } else if (alpha.ez == beta.ez){
                return 0;
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    } else {
        return -1;
    }
}
  

Комментарии:

1. как насчет использования логического оператора if ( (alpha.ex == beta.ex) amp;amp; (alpha.ey > beta.ey) )

Ответ №1:

В случае вашего примера абсолютно нет необходимости использовать any else , поскольку после a return поток программы все равно не может продолжаться.

Я бы написал функцию сравнения таким образом:

 int expCompare(Exponent alpha, Exponent beta) {
    if (alpha.ex > beta.ex)
        return 1;
    if (alpha.ex != beta.ex)
        return -1;
    if (alpha.ey > beta.ey)
        return 1;
    if (alpha.ey != beta.ey)
        return -1;
    if (alpha.ez > beta.ez)
        return 1;
    if (alpha.ez == beta.ez)
        return 0;
    return -1;
}
  

Даже без early return можно избежать всех отступов, используя последовательность else if подобных в:

 int expCompare(Exponent alpha, Exponent beta) {
    int result = -1;
    if (alpha.ex > beta.ex)
        result = 1;
    else if (alpha.ex != beta.ex)
        result = -1;
    else if (alpha.ey > beta.ey)
        result = 1;
    else if (alpha.ey != beta.ey)
        result = -1;
    else if (alpha.ez > beta.ez)
        result = 1;
    else if (alpha.ez == beta.ez)
        result = 0;
    return resu<
}
  

Обратите внимание, что для конкретного использования сравнения struct объектов по одному полю за другим я написал макрос, используемый в нашей базе кода, который значительно упрощает этот общий шаблон. Это было бы так:

 static int compareValues(int a, int b)
{
    if (a > b)
        return 1;
    if (a < b)
        return -1;
    return 0;
}

#define COMPARE_VALUES_RETURN_IF_DIFFERENT(a,b) 
    do { int result = compareValues((a), (b)); 
    if(result) return resu< } while(0)

int expCompare(Exponent alpha, Exponent beta) {
    COMPARE_VALUES_RETURN_IF_DIFFERENT(alpha.ex, beta.ex);
    COMPARE_VALUES_RETURN_IF_DIFFERENT(alpha.ey, beta.ey);
    COMPARE_VALUES_RETURN_IF_DIFFERENT(alpha.ez, beta.ez);
    return 0;
}
  

В нашем случае compareValues это переопределенная функция в C , которая может сравнивать не только несколько типов int , но вы понимаете суть.