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))