这个reverseBytes方法如何工作?

时间:2015-02-12 07:42:04

标签: c byte bit bit-shift

我在线看这个功能,我想知道它是如何工作的:

   /*
    * 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;
    }

以下是我认为我理解的内容:

    二进制文件中的
  • 0xff0xff000xff0000分别为1111 11111111 1111 0000 00001111 1111 0000 0000 0000 0000
  • 该方法使用掩码(0xff等)创建四个新字节,然后使用|运算符将它们的值相加

我真的不明白这是如何扭转字节的。我将非常感谢您的详细解释。谢谢!

5 个答案:

答案 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;

的字节3
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