如何理解这个C宏?

Gau*_*lam 1 c c-preprocessor

我无法理解这段代码

#define sqt(x) x*x
int main(){
print("%d",sqt(3+1));
}
Run Code Online (Sandbox Code Playgroud)

手动我得到10的输出.但是当编写代码并编译它时我得到的答案为7.请解释一下.

Car*_*ate 9

请记住,因为您正在使用宏,3 + 1所以在sqt调用之前不进行评估.x变为3 + 1(非4),然后操作顺序导致产生意外答案,因为在乘法之后发生加法.

或者换句话说:

sqt(3 + 1)
Run Code Online (Sandbox Code Playgroud)

扩展为:

3 + 1 * 3 + 1
Run Code Online (Sandbox Code Playgroud)

那么,当你评价这个时,你会得到任何其他等式:

3 + 1 * 3 + 1 // Multiplication happens first
= 3 + 3 + 1
= 7
Run Code Online (Sandbox Code Playgroud)

这是一个很好的例子,说明为什么你不应该使用宏,除非它们是绝对必要的,或者你已经做了适当的注意,以确保不会发生操作错误顺序之类的事情.正如@Barmar指出的那样,通过让宏扩展为包含显式括号可以解决这个特殊情况:

#define sqt(x) ((x)*(x))
Run Code Online (Sandbox Code Playgroud)

哪会导致评估不同并给出正确的答案:

(3 + 1) * (3 + 1)
4 * 4
16
Run Code Online (Sandbox Code Playgroud)

  • 像这样的宏非常好,并且没有理由不使用它们 - 只要你包括括号. (2认同)