c语言 - 如何 '(1U << 1) |(1U << 5)"与"0x22"不同吗?



有人能解释一下具有相同值VAL1VAL2的行为有何不同吗?对于第一个if语句,VAL1等于零?谢谢

#include <stdio.h>
#define VAL1 (1U << 1) | (1U << 5)
#define VAL2 0x22
int main()
{
printf("VAL1: %drn", VAL1);
printf("VAL2: %drn", VAL2);
if (VAL1 == 0)
{
printf("TRUE 1rn");
}
if (VAL2 == 0)
{
printf("TRUE 2rn");
}
if (VAL1 == VAL2)
{
printf("TRUE 3rn");
}
}

输出:

VAL1: 34
VAL2: 34
TRUE 1
TRUE 3

这两个数字都是相同的,但当宏在您的条件下展开时,由于运算符优先级的原因,它的行为与您预期的不一样。

换句话说,以下是扩展后的结果:

(1U << 1) | (1U << 5) == 0
// is equivalent to
(1U << 1) | ((1U << 5) == 0)

if (VAL1 == 0)中,宏替换将源代码更改为if ((1U << 1) | (1U << 5) == 0)

if内部的表达式被评估为(1U << 1) | ((1U << 5) == 0),因为希望保持C的运算符先验与早期语言B的运算符先验一致。

因此,我们有if ((1U << 1) | ((1U << 5) == 0)),其中(1U << 1)的求值为2,((1U << 5) == 0)的求值为0,从而得到if (2 | 0),它变为if (2),因此执行具有if的语句。

通常定义一个宏替换,它是一个带括号的表达式,以确保它被分组为一个项目:

#define VAL1 ((1U << 1) | (1U << 5))

相关内容

最新更新