Kus*_*hal 28 c macros parentheses c-preprocessor
我试着SQR
在下面的代码中使用宏的定义:
#define SQR(x) (x*x)
int main()
{
int a, b=3;
a = SQR(b+5); // Ideally should be replaced with (3+5*5+3), though not sure.
printf("%d\n",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它打印23
.如果我将宏定义更改为SQR(x) ((x)*(x))
然后输出是预期的,64
.我知道在C中调用宏会用宏的定义替换调用,但是我仍然无法理解它是如何计算的23
.
Bab*_*fas 31
在编译代码之前,预处理器宏执行文本替换,因此
SQR(b+5)
转换为(b + 5*b + 5)=(6b + 5)= 6*3 + 5 = 23
常规函数调用将在将参数传递给函数之前计算参数(b + 3)的值,但由于宏是预编译的替换,因此代数的操作顺序变得非常重要.
Luc*_*ore 10
因为(3+5*3+5 == 23)
.
鉴于((3+5)*(3+5)) == 64
.
执行此操作的最佳方法是不使用宏:
inline int SQR(int x) { return x*x; }
Run Code Online (Sandbox Code Playgroud)
或者简单地写x*x
.
pb2*_*b2q 10
考虑使用此宏替换宏:
#define SQR(x) (x*x)
Run Code Online (Sandbox Code Playgroud)
使用b+5
作为参数.自己做替换.在您的代码中,SQR(b+5)
将成为:(b+5*b+5)
,或(3+5*3+5)
.现在记住您的运算符优先级规则:*
之前+
.所以这被评估为:(3+15+5)
,或23
.
宏的第二个版本:
#define SQR(x) ((x) * (x))
Run Code Online (Sandbox Code Playgroud)
是正确的,因为你正在使用parens来根据运算符优先级的效果来表示你的宏参数.
这个页面解释C的操作员偏好有一个很好的图表.这是 C11参考文件的相关部分.
这里需要记住的是,你应该养成使用parens来屏蔽宏中任何参数的习惯.
宏扩展到
a = b+5*b+5;
Run Code Online (Sandbox Code Playgroud)
即
a = b + (5*b) + 5;
Run Code Online (Sandbox Code Playgroud)
所以23.