工会中的char字节是否被反转?

时间:2017-11-25 08:21:23

标签: c int endianness bit-shift unions

我有一个int和一个像这样的字符的联合:

union {
    int     i;
    char    c[4];
} num;

当我将int设置为1并打印每个char时,我得到了这个结果:

1 0 0 0

...让我得出结论,我的机器是小端。 但是,当我向左移位24时,我得到以下结果:

0 0 0 1

通过自定义函数交换字节顺序(通过右侧交换最左边的字节,中间两个字节相同),我最终得到:

0 0 0 1

左移24,结果为:

0 0 0 0

这使我得出结论,我的联盟中的char [4]是从右到左表示的,在这种情况下,endianness实际上与所表示的相反。但根据我的理解,char数组通常从左到右解释,无论平台如何。 我工会中的char字节是否颠倒了?

完整代码:

#include <stdio.h>
#include <stdlib.h>

void    endian_switch32(int *n)
{
    int ret[4];

    ret[0] = *n >> 24;
    ret[1] = (*n >> 8) & (255 << 8);
    ret[2] = (*n << 8) & (255 << 16);
    ret[3] = *n << 24;
    *n = ret[0] | ret[1] | ret[2] | ret[3];
}

int main (void) {

    union {
        int     i;
        char    c[4];
    } num;

    num.i = 1;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    num.i <<= 24;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    num.i = 1;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    endian_switch32(&num.i);
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

    num.i <<= 24;
    printf("%d %d %d %d\n", num.c[0], num.c[1], num.c[2], num.c[3]);

}

结果:

1 0 0 0
0 0 0 1
1 0 0 0
0 0 0 1
0 0 0 0

2 个答案:

答案 0 :(得分:1)

重点是,您以相反的顺序打印字节,因此您打算将0x01020304打印为4 3 2 1,导致你的困惑。 Endian 影响数组的存储方式,即没有人反向存储&#34;一个数组。

当你将1向右移动24时,你得到零。没关系:

 00000000 00000000 00000000  00000001
 ->
(00000000 00000000 00000000) 00000000 00000000 00000000 00000001
 ->
 00000000 00000000 00000000 00000000

正好为零。

当您将0x01000000右移24时,您得到1.结论(来自char[4]的打印输出)是您的平台是小端的。

答案 1 :(得分:0)

左右移位基于int的值,而不是基于二进制表示。无论字节如何存储在内存中,具有值int的32位1在逻辑上被视为0x00000001或二进制

00000000 00000000 00000000 00000001

无论你的字节顺序如何,位移结果都适用于这种表示,因此位移不是检测字节序的好方法。你的机器可能是小端的(由于这些结果和基本速率,因为大多数计算机都是小端)。