3

我在这里阅读这个关于决定字节顺序的问题,第一个答案让我有些困惑。

用于决定大字节序的代码如下:

int is_big_endian(void)
{
    union {
        uint32_t i;
        char c[4];
    } bint = {0x01020304};

    return bint.c[0] == 1; 
} 

我的问题是这里的编译器如何决定该十六进制数字数组使用什么类型?因为从技术上讲,它同样适用于 thatuint32_t或 that char[4]

为什么不直接将其存储在 中char[4]并跳过union

这里有一些union我看不到的优势吗?我知道这被称为类型双关语,但在这里我看不到它的优势。

4

3 回答 3

6

我的问题是这里的编译器如何决定该十六进制数字数组使用什么类型?

与数组和聚合类一样,第一个初始化器初始化第一个成员;在这种情况下i。(当然,与那些事情不同,拥有多个初始化器是没有意义的)。

为什么不将它存储在 char[4] 中并跳过联合?这里有没有我看不到的工会优势?

这样做的目的是初始化 4 字节整数,然后使用char数组检查各个字节以确定内存顺序。如果最高有效字节(0x01)存储在第一个字节中,则系统为“大端”;否则它是“小端”(或者可能是更奇怪的东西)。

于 2013-08-22T14:18:51.983 回答
2

最初的 C 标准只允许为联合的第一个元素赋值。这意味着:0x1020304 分配给“i”,而不是“c”。

最新的 C 标准允许像这样分配给任何成员:

union { ... } bint = { .c = {1,2,3,4} };
union { ... } bint2 = { .i = 0x1020304 };

但是 - 如前所述 - 如果没有给出名称,则将该值分配给“i”。

于 2013-08-22T14:18:07.030 回答
0

因为您想存储 0x01020304为无符号 32 位整数uint32_t i,然后读取第一个字节char c[0]

于 2013-08-22T14:16:38.757 回答