C预处理器和操作顺序

C preprocessors and order of operations

本文关键字:操作 顺序 处理器 预处理      更新时间:2023-10-16

我正在学习C语言,但是我不懂这个:

#define square(x) x*x
a = square(2+3) //a = 11

当这个运行时,为什么a最终是11 ?

展开为2+3*2+3,相当于2+(3*2)+3。使用括号来修复:

#define square(x) ((x)*(x))

现在用square(x++)试试,你会遇到更多的问题(未定义的行为)。如果可以,请避免在宏中执行此操作。

square(2+3)扩展为2+3*2+3,相当于2+(3*2)+3 [*优先级高于+]

在gcc中,你可以使用-E选项来查看你的预处理器生成了什么

C:UsersSUPER USER>type a.c
#define square(x) x*x
int main()
{
   a = square(2+3); //a = 11
}
C:UsersSUPER USER>gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"

int main()
{
   a = 2+3*2+3;
}
补救

试试这个

#define square(x) ((x)*(x))

尝试:

#define square(x) ((x)*(x))

由于2 + 3在表达式x * x中被逐字替换,因此它变成了2 + 3 * 2 + 3,并且*运算符具有更高的优先级,因此您无法获得预期的结果。

始终将宏参数和整个表达式括在括号中以避免这种情况:

#define SQUARE(x) ((x) * (x))

还要注意传递的任何表达式都将被求值两次,如果表达式具有诸如赋值或函数调用之类的副作用,则可能不希望这样做。在这些情况下,最好使用内联函数。

考虑一下在展开宏时会得到什么。c预处理器会将其展开为

a = 2 + 3 * 2 + 3

你需要正确定义你的宏。宏变量总是用圆括号括起来。这将给您预期的结果。

#define square(x) ((x)*(x))

宏展开是这样的:

a = ((2 + 3) * (2 + 3))