AND 0xFF做什么?

Mui*_*uis 41 c bit-manipulation bit-shift bitwise-operators

在以下代码中:

short = ((byte2 << 8) | (byte1 & 0xFF))
Run Code Online (Sandbox Code Playgroud)

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

short = ((byte2 << 8) | byte1)
Run Code Online (Sandbox Code Playgroud)

这似乎也很好吗?

Joh*_*oni 35

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

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


D S*_*ley 28

如果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
Run Code Online (Sandbox Code Playgroud)


Pat*_*ter 21

第二个表达式的危险来临如果类型的byte1char.在这种情况下,某些实现可以拥有它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);
Run Code Online (Sandbox Code Playgroud)

将打印

value1=4224 1080     right
value2=65408 ff80    wrong!!
Run Code Online (Sandbox Code Playgroud)

我在Solaris SPARC 64位上的gcc v3.4.6上尝试过,结果byte1byte2声明相同char.

TL; DR

掩蔽是为了避免隐式符号扩展.

编辑:我检查过,它在C++中是相同的行为.


sr0*_*853 6

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

所以byte1是一样的byte1 & 0xFF

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

如果byte1是某种其他类型,比如4字节的整数,则按位AND与0xFF会留下byte1的最低有效字节(8位).


Jer*_*fin 5

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

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

如果byte1是带符号或具有超过 8 位的类型(例如,short, int, long),并且设置了除 8 个最低有效位之外的任何位,则将存在差异(即,它会在oring之前将这些高位归零)与另一个变量,因此该操作数or仅影响结果的 8 个最低有效位)。