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
第二个表达式的危险来临如果类型的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);
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上尝试过,结果byte1与byte2声明相同char.
TL; DR
掩蔽是为了避免隐式符号扩展.
编辑:我检查过,它在C++中是相同的行为.
假设你byte1是一个字节(8位),当你用0xFF对一个字节进行按位AND时,你得到的是相同的字节.
所以byte1是一样的byte1 & 0xFF
说byte1是01001101,然后byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1
如果byte1是某种其他类型,比如4字节的整数,则按位AND与0xFF会留下byte1的最低有效字节(8位).
确保byte1 & 0xff只有 8 个最低有效位byte1可以是非零。
ifbyte1已经是一个只有 8 位的无符号类型(例如,char在某些情况下,或unsigned char在大多数情况下),它不会产生任何区别/完全没有必要。
如果byte1是带符号或具有超过 8 位的类型(例如,short, int, long),并且设置了除 8 个最低有效位之外的任何位,则将存在差异(即,它会在oring之前将这些高位归零)与另一个变量,因此该操作数or仅影响结果的 8 个最低有效位)。