我正在学习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:\Users\SUPER USER>type a.c
#define square(x) x*x
int main()
{
a = square(2+3); //a = 11
}
C:\Users\SUPER 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))