这个程序的输出是 64。有人能解释一下吗?

Output of this program is 64. Can someone explain how?

#define sqr(a) a*a
int main()
{
int i;
i = 64 / sqr(4); //answer of this expression is 64.
printf("%d", i);
return 0;
}

在此代码中输出为 64,根据规则,表达式 i = 64 / sqr(4) 应求解为 i = 64 / 4*4,结果为 4,但程序的输出为64. 为什么?

你需要看一下操作顺序。先做乘法,所以就是(64 * 4) / 4。这是在您的宏周围加上括号的更新版本:

#define sqr(a) ((a)*(a))
int main()
{
int i;
i = 64 / sqr(4); //answer of this expression is 4.
printf("%d", i);
return 0;
}

宏不像函数那样求值,它们是就地展开的。声明

i = 64 / sqr(4);

扩展到

i = 64 / 4*4;

乘除运算符的优先级相同,并且是左结合的,所以上面的语句解析为

i = (64 / 4) * 4;

因此,您是将 64 / 4 的结果乘以 4,而不是将 64 除以 4 * 4 的结果。

他们避免像这样的宏的优先级和关联性问题的方法是将扩展括在括号中:

#define sqr(a) (a * a)
但是,

就其本身而言,这还不够 - 如果您执行类似 sqr(1+2) 的操作,它将扩展为 (1+2*1+2),其计算结果为 5 而不是预期的 [=23] =].您还需要将参数和整个表达式括起来:

#define sqr(a) ((a) * (a))

现在您的语句扩展为

i = 64 / ((4) * (4));

并且会按照您的预期进行评估。

我会尽量让这个答案简单:


宏是一组在编译时被替换的代码。

现在,如果您 sqr(4) 替换为 4*4
它变成了这样的东西:64/4*4.

现在,如果你应用 BODMAS 的基本规则。它被执行如下:
64/4= 16
16*4= 64

即首先除以 4 然后乘以 4 得到 64