将 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]
且值为 0x11223344
和 0x55667788
的数组存储为
44 33 22 11
和 88 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
转换是未定义的行为,因为它们违反了严格的指针别名,并且还可能导致未对齐。为了安全地在不同内存类型之间进行转换,您需要使用移位,memcpy
或 union
.
我很困惑,字节序如何在转换为 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]
且值为 0x11223344
和 0x55667788
的数组存储为
44 33 22 11
和 88 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
转换是未定义的行为,因为它们违反了严格的指针别名,并且还可能导致未对齐。为了安全地在不同内存类型之间进行转换,您需要使用移位,memcpy
或 union
.