C运算中的顺序重要吗?

时间:2018-08-06 08:05:16

标签: c variables math

我正在用基础C指导一些学生,但对于我正在编写的疯狂的基础C程序中的某些东西确实感到困惑。

我有以下

...
#define RATEM1 0.015
#define RATEM2 0.025
...
#define THRESHM 100000.00
...
#define BASE0 0.00
....
#define BASEM (BASE0 + RATEM1*THRESHM);

void ex3_8() {
    double gross, medicare, net;
    ... /* Reading in gross, performing other calculations, etc. */
    if (gross <= THRESHM) {
        medicare = RATEM1 * gross;
    } else {
        medicare = (gross - THRESHM) * RATEM2 + BASEM;
    }
    printf("Medicare: %9.2f\n", medicare);
    net = gross - tax - medicare;
    printf("net income         $%9.2f\n", net);
}
int main(int argc, char *argv[]) {
    ex3_8();
    return 0;
}

这有效。但是,如果将第二行medicare更改为medicare = BASEM + (gross - THRESHM) * RATEM2;,则会收到未使用的变量警告:warning: expression result unused [-Wunused-value]

谁能告诉我发生了什么事?

1 个答案:

答案 0 :(得分:3)

看看使用-E开关在gcc中显示预处理器输出时会发生什么:

void ex3_8() {
    double gross, medicare, net;
    ...
    if (gross <= 100000.00) {
        medicare = 0.015 * gross;
    } else {
        medicare = (0.00 + 0.015*100000.00); + (gross - 100000.00) * 0.025;
    }

}

由于宏以;结尾(这是一个很大的禁忌),因此表达式以宏结尾,其余的只是未使用的计算,因此(非常有用)警告。

在这种情况下,+运算符是编译器接受的一元+。如果它是*,那么您会得到一个错误(也是一个神秘的错误,只有未经预处理的输出)。

解决方案(如注释中所述):最后删除;

为了确保您的宏真正安全,请在每个成员后面加上括号,因为每个成员都是一个宏(与宏参数相同),其中可能包含计算,由于运算符的优先级,计算将出错:

#define BASEM ((BASE0) + (RATEM1)*(THRESHM))

注意:如果有多个语句,请始终将其括在do {} while(0)中,这样就不必在末尾也插入;