当我定义这个宏时:
#define SQR(x) x*x
Run Code Online (Sandbox Code Playgroud)
让我们说这个表达式:
SQR(a+b)
Run Code Online (Sandbox Code Playgroud)
此表达式将被宏替换,如下所示:
a+b*a+b
Run Code Online (Sandbox Code Playgroud)
但是,如果我++在表达式之前放置一个运算符:
++SQR(a+b)
Run Code Online (Sandbox Code Playgroud)
现在的表达是什么样的?这是++放置在SQR参数的每个部分吗?像这样:
++a+b*++a+b
Run Code Online (Sandbox Code Playgroud)
在这里我给出一个简单的程序:
#define SQR(x) x*x
int a, k = 3;
a = SQR(k+1) // 7
a = ++SQR(k+1) //9
Run Code Online (Sandbox Code Playgroud)
在定义宏时,您基本上总是希望将宏参数放在parens中以防止第一个示例中的那种奇怪的行为,并将结果放在parens中,以便可以安全地使用它而不会产生副作用.运用
#define SQR(x) ((x)*(x))
Run Code Online (Sandbox Code Playgroud)
使SQR(a+b)扩展到((a+b)*(a+b))数学上是正确的(不像a+b*a+b,等于ab + a + b).
在宏之前或之后放置内容不会进入宏.因此++SQR(x)成为++x*x在你的榜样.
请注意以下事项:
int a=3, b=1;
SQR(a+b) // ==> a+b*a+b = 3+1*3+1 = 7
++SQR(a+b) // ==> ++a+b*a+b ==> 4 + 1*4 + 1 = 9
// since preincrement will affect the value of a before it is read.
Run Code Online (Sandbox Code Playgroud)
你看到++SQR(a+b)似乎增加了2,因为在a我读取任何一个时间之前,前增量开始,即a增量,然后使用两次,因此结果比预期高2.
注意 @JonathanLeffler指出,后一个调用调用未定义的行为; 评估不保证从左到右进行.它可能会在不同的编译器/操作系统上产生不同的结果,因此永远不应该依赖它们.