#define MAX(x,y)(x)>(y)?(x):(y)
main()
{
int i=10,j=5,k=0;
k==MAX(i++,++j);
printf("%d %d %d",i,j,k);//11 7 0
}
为什么输出是11 7 0而不是11 6 0?
答案 0 :(得分:2)
声明扩展为
k==(i++)>(++j)?(i++):(++j)
让我们用一些额外的parens重写这一点,以强调在计算优先级规则时如何解析表达式:
( k == ( (i++) > (++j) ) ) ? (i++) : (++j)
请注意,>
的优先级高于==
。
现在,首先评估(i++) > (++j)
,评估为1
,i
和j
都会增加。然后将k
与1
进行相等性比较,得出0
。因此,条件运算符的计算结果为(++j)
,因此j
再次递增。
总计i
增加一次,j
增加两次,k
不会被修改。因此输出就像你描述的那样。
这是使用宏的危险的一个很好的例子。功能真的是你需要的。
其他一些观点:
main
声明不正确。它应该是int main(void)
。C:\Users\blah\Desktop>gcc main.c -Wall -o main.exe main.c: In function 'main': main.c:2:20: warning: suggest parentheses around comparison in operand of '==' [-Wparentheses] #define MAX(x,y)(x)>(y)?(x):(y) ^ main.c:6:8: note: in expansion of macro 'MAX' k==MAX(i++,++j); ^
答案 1 :(得分:1)
宏由预处理器替换为三元运算符:
k == (x) > (y) ? (x) : (y)
比较:(x)>(y)
将首先完成,并且将产生1,但是那时三元运算符的其余部分将不会被评估,因为运算符==
具有优先权。代码相当于:
( k == ( (x) > (y) ) ) ? (x) : (y)
我们必须将结果(1为1)与k:k==(x)>(y)
进行比较,得到结果0.然后只评估三元运算符的第三个运算符:(y)
。< / p>
总而言之,i
将被评估一次,j
将被评估两次。因此i
的最终结果为11,j
的结果为7。 (变量k
将保持为0,因为它从未被赋值。)
答案 2 :(得分:0)
使用真实表达式扩展宏:
WSARecv()
这是一个典型的条件表达式。
k == (i++) > (++j) ? (i++) : (++j);
expr1 ? expr2 : expr3;
是expr1
。这实际上包含两个逻辑操作。由于k == (i++) > (++j)
的优先级低于==
,因此首先评估此逻辑>
,并在第一次逻辑测试之前完成(i++) > (++j)
。 ++j
现在是6,我们j
是真的(10 > 6
)。现在来到第二个逻辑1
,它评估为false(k == 1
)。0
为false,因此会expr1
进行评估,即expr3
,并且++ post-fix再次表示(++j)
在评估之前递增。 j
现在变为7。答案 3 :(得分:-2)
宏在定义它们时需要小心,它们不一定按照您期望的方式扩展。 C中宏的一个关键特征是它们实际上执行替换,术语为术语。
这个概念在K&amp; R书中以及在线的多个教程中得到了很好的解释,只是google它。