AND 0xFF做什么?

时间:2013-02-05 17:15:00

标签: c bit-manipulation bitwise-operators bit-shift

在以下代码中:

short = ((byte2 << 8) | (byte1 & 0xFF))

&0xFF的目的是什么? 因为其他有时我认为它写成:

short = ((byte2 << 8) | byte1)

这似乎也很好用吗?

7 个答案:

答案 0 :(得分:33)

使用0xFF定义一个整数只留下最低有效字节。例如,要获取short s中的第一个字节,可以编写s & 0xFF。这通常被称为“掩蔽”。如果byte1是单字节类型(如uint8_t)或已经小于256(并且因此除了最低有效字节之外全部为零),则无需屏蔽掉更高的字节类型位,因为它们已经为零。

当您使用签名类型时,请参阅下面的 tristopia PatrickSchlüter的答案。在进行按位操作时,我建议仅使用无符号类型。

答案 1 :(得分:26)

如果byte1是一个8位整数类型,那么它是没有意义的 - 如果它超过8位,它基本上会给你最后8位的值:

    0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
 &  0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
    -------------------------------
    0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1

答案 2 :(得分:19)

如果byte1的类型为char,则会出现第二个表达式的危险。在这种情况下,某些实现可以使用signed char,这将在评估时产生符号扩展。

signed char byte1 = 0x80;
signed char byte2 = 0x10;

unsigned short value1 = ((byte2 << 8) | (byte1 & 0xFF));
unsigned short value2 = ((byte2 << 8) | byte1);

printf("value1=%hu %hx\n", value1, value1);
printf("value2=%hu %hx\n", value2, value2);

将打印

value1=4224 1080     right
value2=65408 ff80    wrong!!

我在Solaris SPARC 64位上的gcc v3.4.6上尝试过,结果与声明为byte1的{​​{1}}和byte2相同。

TL; DR

屏蔽是为了避免隐式符号扩展。

编辑:我查了一下,这与C ++中的行为相同。

答案 3 :(得分:6)

假设您的byte1是一个字节(8位),当您使用0xFF对一个字节进行按位AND时,您将得到相同的字节。

因此byte1byte1 & 0xFF

相同

byte101001101,然后是byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1

如果byte1是某种其他类型的4个字节的整数,则与0xFF的按位AND会使您获得byte1的最低有效字节(8位)。

答案 4 :(得分:3)

byte1 & 0xff确保只有byte1的8个最低有效位可以为非零。

如果byte1已经是一个只有8位的无符号类型(例如,在某些情况下为char,或者在大多数情况下为unsigned char,则它不会产生任何差异/完全没有不必要的。

如果byte1是一个已签名或具有8位以上的类型(例如shortintlong),以及除8之外的任何位设置最低有效值,然后会有差异(即,在or与另一个变量之前它会将那些高位置为零,因此or的此操作数仅影响8个最低有效位结果)。

答案 5 :(得分:1)

它清除所有不在第一个字节中的位

答案 6 :(得分:0)

& 0xFF本身仅确保如果字节长于8位(语言标准允许),则忽略其余字节。

  

这似乎也很好用吗?

如果结果大于SHRT_MAX,则会得到未定义的行为。在这方面,两者的效果都相同。