将 uint32_t 数组的两个元素转换为单个 uint64_t 时,字节序如何交换元素的顺序?

How endianness swaps the order of elements, when converting two elements of uint32_t array to a single uint64_t?

我很困惑,字节序如何在转换为 uint64_t 时交换 uint32_t 数组元素的顺序,反之亦然。

如果我正在处理存储在一个包含 8 个元素的 uint8_t 数组中的字节,如果我像这样使用指针转换和取消引用将其直接转换为 uint64_t

uint8_t array[8] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xb0, 0xa0};
uint64_t u = *(uint64_t *)array; 

在小端系统上,u 等于 0xa0b0ffeeddccbbaa

但是,如果我有一个像这样的 uint32_t 数组:

uint32_t arr[2] = {0xaabbccdd, 0xeeffb0a0} ;
uint64_t U = *(uint64_t *)arr;

在小端系统上,U 变为 0xeeffb0a0aabbccdd

我凭直觉理解前者的情况,但后者,跟uint32_t是一头雾水! 在转换过程中,在后一种情况下,我无法可视化内存布局...... 每一个帮助,将不胜感激!

Endianess 单独 应用于每个 16 位或更大的整数。也就是说,在小端机器上,一个 32 位整数 0xaabbccdd 存储为 dd cc bb aa.

所以一个包含两个 32 个整数 uint32_t [2] 且值为 0x112233440x55667788 的数组存储为
44 33 22 1188 77 66 55 分别。在数组中,项目保证连续存储,因此在这种情况下内存看起来像 44 33 22 11 88 77 66 55.

64 位整数 0x1122334455667788 然而存储为 88 77 66 55 44 33 22 11,因为字节顺序同样适用于每个整数。这就是为什么你不能在小端机器上将两个 32 位整数的内存布局重新解释为 64 位整数。

如果 CPU 是大端,则 uint32_t [2] 将存储为:
11 22 33 44 55 66 77 88 然后它恰好得到与 uint64_t 相同的表示,其值为 0x1122334455667788.


作为旁注,您代码中的 *(uint64_t *)array 转换是未定义的行为,因为它们违反了严格的指针别名,并且还可能导致未对齐。为了安全地在不同内存类型之间进行转换,您需要使用移位,memcpyunion.