C预处理器和操作顺序

时间:2011-04-27 16:01:59

标签: c++ c macros c-preprocessor

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

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

运行此操作时,为什么a最终成为11

5 个答案:

答案 0 :(得分:22)

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

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

现在使用square(x++)进行尝试,您将遇到更多问题(未定义的行为)。如果可以,请避免将其作为宏。

答案 1 :(得分:12)

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

答案 2 :(得分:1)

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

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

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

另请注意,您传递的任何表达式都将被计算两次,如果表达式具有副作用(如赋值或函数调用),则可能不需要这样做。在这些情况下,最好使用内联函数。

答案 3 :(得分:1)

尝试:

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

答案 4 :(得分:0)

考虑扩展宏时会得到什么。 c预处理器将把它扩展为

a = 2 + 3 * 2 + 3

您需要正确定义宏。始终将宏变量括在括号中。这会给你预期的结果。

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

宏观扩张将是:

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