C中宏的括号需要

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来屏蔽宏中任何参数的习惯.


Mat*_*Mat 7

宏扩展到

 a = b+5*b+5;
Run Code Online (Sandbox Code Playgroud)

 a = b + (5*b) + 5;
Run Code Online (Sandbox Code Playgroud)

所以23.