C预处理器和操作顺序

我正在学习C,但我不明白这一点:

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

当这个运行时,为什么最终会成为11

它扩展到2+3*2+3 ,相当于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 2+(3*2)+3 [ *优先级高于+ ]

在gcc上,您可以使用-E选项查看预处理器生成的内容

 C:\Users\SUPER USER>type ac #define square(x) x*x int main() { a = square(2+3); //a = 11 } C:\Users\SUPER USER>gcc -E ac # 1 "ac" # 1 "" # 1 "" # 1 "ac" int main() { a = 2+3*2+3; } 

补救

试试这个

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

尝试:

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

因为2 + 3 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))