C 预处理器和操作顺序

问题描述 投票:0回答:5

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

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

运行后,为什么

a
最终变成了
11

c++ c macros c-preprocessor
5个回答
24
投票

它扩展为

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

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

现在尝试使用

square(x++)
,你会遇到更多问题(未定义的行为)。如果可以的话,请避免将其作为宏来执行。


13
投票

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

1
投票

尝试:

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

1
投票

因为

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

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

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

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


0
投票

想想当宏展开时你会得到什么。 C 预处理器会将其扩展为

a = 2 + 3 * 2 + 3

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

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

宏展开是这样的:

a = ((2 + 3) * (2 + 3))
© www.soinside.com 2019 - 2024. All rights reserved.