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

问题描述 投票:-2回答:2

我有一个带有int和char的联合,如下所示:

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
c int endianness bit-shift unions
2个回答
0
投票

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

00000000 00000000 00000000 00000001

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


1
投票

关键是,你以相反的顺序打印字节,所以你打算将0x01020304打印为4 3 2 1,这会导致你的困惑。 Endian不影响数组的存储方式,即没有人“反向存储”数组。

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

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

这正是零。

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

© www.soinside.com 2019 - 2024. All rights reserved.