我在线看这个功能,我想知道它是如何工作的:
/*
* reverseBytes - reverse bytes
* Example: reverseBytes(0x12345678) = 0x78563412
* Legal ops: ! ~ & ^ | + << >>
*/
int reverseBytes(int x)
{
int newbyte0 = (x >> 24) & 0xff;
int newbyte1 = (x >> 8) & 0xff00;
int newbyte2 = (x << 8) & 0xff0000;
int newbyte3 = x << 24;
return newbyte0 | newbyte1 | newbyte2 | newbyte3;
}
以下是我认为我理解的内容:
0xff
,0xff00
和0xff0000
分别为1111 1111
,1111 1111 0000 0000
和1111 1111 0000 0000 0000 0000
0xff
等)创建四个新字节,然后使用|
运算符将它们的值相加我真的不明白这是如何扭转字节的。我将非常感谢您的详细解释。谢谢!
答案 0 :(得分:2)
代码假定32位整数和8位字节。 32位整数由4个字节组成: 让我们说这4个字节在内存中如下所示:
+---------------------------------+
|Byte 4 | Byte 3 | Byte 2 | Byte 1|
+---------------------------------+
这可能与给定CPU类型的Endianess有关。当解释由几个字节组成的整数时,一些CPU系列将处理最左边的字节,具有较低内存地址的字节作为整数的最高有效字节 - 这种CPU称为大端字节。其他CPU将执行相反的操作,它们将处理整数内最右边的字节,具有最大内存地址的字节作为最重要的字节 - 小端CPU。所以你的函数将一个整数从一个endian转换为另一个。
int newbyte0 = (x >> 24) & 0xff;
这取上面描述的整数(4个字节),将它向右移24位,并屏蔽除了低8位之外的所有内容,newbyte0现在看起来像这样,其中字节4是{{的原始字节4 1}}和其他3个字节的所有位都设置为零。
x
Similarely
+---------------------------------+
| 0 | 0 | 0 | Byte 4 |
+---------------------------------+
将位向右移8位,并屏蔽除左侧2字节中的8位之外的所有内容。结果如下所示,只剩下原始值为 int newbyte1 = (x >> 8) & 0xff00;
x
最左边的2个字节的处理方式类似,只有+---------------------------------+
| 0 | 0 | Byte 3 | 0 |
+---------------------------------+
向左移动才能完成相同的操作。
最后你有
x
它结合了您在上面创建的所有整数,每个整数只剩下原始 newbyte0 | newbyte1 | newbyte2 | newbyte3;
的8位。做一点x
他们,你最终得到
or
答案 1 :(得分:1)
int newbyte0 = (x >> 24) & 0xff;
将数字24位向右移位,以便最左边的字节现在是最右边的字节。然后使用掩码(0xff
)将剩余的字节清零,这是多余的,因为移位无论如何都会将它们归零,因此掩码可以省略。
int newbyte1 = (x >> 8) & 0xff00;
向右移动8位,因此左边的第二个字节现在是右边的第二个字节,其余的字节用掩码清零。
int newbyte2 = (x << 8) & 0xff0000;
这次向左移动数字8位 - 基本上与最后一行相同,只是现在右边的第二个字节成为左边的第二个字节。
int newbyte3 = x << 24;
与第一行相同(这次省略冗余掩码) - 最右边的字节成为最左边的字节。
return newbyte0 | newbyte1 | newbyte2 | newbyte3;
最后你只需要OR
所有字节来完成逆转。
您可以在代码中逐步执行此过程,方法是使用printf("%x", newbyte)
打印每个字节 - %x
格式允许您以十六进制格式打印。
答案 2 :(得分:0)
假设32位系统已将0x12345678
传递给函数。
int newbyte0 = (x >> 24) & 0xff; //will be 0x00000012
int newbyte1 = (x >> 8) & 0xff00; //will be 0x00003400
int newbyte2 = (x << 8) & 0xff0000; //will be 0x00560000
int newbyte3 = x << 24; //will be 0x78000000
return newbyte0 | newbyte1 | newbyte2 | newbyte3; will be 0x78563412
答案 3 :(得分:0)
此函数只是将字节移位到整数中的右侧位置,而不是将它们全部移位到一起。 例如x是0xAABBCCDD: 对于第一个字节,我们将所有字节向右移,因此我们有0x00000000AA&amp; 0xFF,即0xAA。
对于第二个字节,我们有0x00AABBCC&amp; 0xFF00,即0x0000BB00
等等。 我们只是将位移位到正确位置并擦除所有其他位。
答案 4 :(得分:0)
是的,您正确理解代码,但当然它假定int为32位值。
int newbyte0 = (x >> 24) & 0xff; // Shift the bits 24~31 to 0~7
int newbyte1 = (x >> 8) & 0xff00; // Shift the bits 16~23 to 8~15
int newbyte2 = (x << 8) & 0xff0000; // Shifts bit bits 8~15 to 16~23
int newbyte3 = x << 24; // Shift bits 0~7 to 24~31
return newbyte0 | newbyte1 | newbyte2 | newbyte3; // Join all the bits