简体   繁体   English

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

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

I am confused as to how, endianness swaps the ordering of elements of a uint32_t array when converted to a uint64_t and vice-versa.我对字节顺序如何在转换为uint64_t时交换uint32_t数组元素的顺序感到困惑,反之亦然。

If I'm dealing with bytes stored in a uint8_t array of 8 elements, if I directly convert it to a uint64_t using pointer casting and dereference like this:如果我正在处理存储在 8 个元素的 uint8_t 数组中的字节,如果我直接使用指针转换和取消引用将其转换为uint64_t ,如下所示:

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

On a little endian system, u would be equal to 0xa0b0ffeeddccbbaa在小端系统上, u等于0xa0b0ffeeddccbbaa

But, if I have a uint32_t array like this:但是,如果我有一个这样的uint32_t数组:

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

On a little endian system, U becomes 0xeeffb0a0aabbccdd在小端系统上, U变为0xeeffb0a0aabbccdd

I intuitively understand the former case, but the latter, with the uint32_t is confusing, I have trouble visualizing the memory layout, during conversion.我直观地理解前一种情况,但后一种情况,由于uint32_t令人困惑,我在转换过程中无法可视化 memory 布局。 in the latter case.., Every help, will be greatly appreciated!在后一种情况下..,每一个帮助,将不胜感激!

Endianess applies individually on every integer of 16 bits or larger. Endianess单独适用于 16 位或更大的每个 integer。 That is, on a little endian machine, a 32 bit integer 0xaabbccdd is stored as dd cc bb aa .也就是说,在小端机器上,32 位 integer 0xaabbccdd存储为dd cc bb aa

So an array of two 32 integers uint32_t [2] with the values 0x11223344 and 0x55667788 are stored as因此,两个 32 整数uint32_t [2]的数组,其值为0x112233440x55667788被存储为
44 33 22 11 and 88 77 66 55 respectively.分别为44 33 22 1188 77 66 55 In an array, items are guaranteed to get stored contiguously, so in this case the memory will look like 44 33 22 11 88 77 66 55 .在数组中,项目保证连续存储,因此在这种情况下 memory 看起来像44 33 22 11 88 77 66 55

A 64 bit integer 0x1122334455667788 is however stored as 88 77 66 55 44 33 22 11 , because again, endianess applies individually to each integer.然而,一个 64 位 integer 0x1122334455667788被存储为88 77 66 55 44 33 22 11 ,因为再次,字节序分别适用于每个 Z157DB7DF530023575515ZD366C9B672E。 This is why you can't re-interpret the memory layout of two 32 bit integers as a 64 bit integer on little endian machines.这就是为什么您不能在小端机器上将两个 32 位整数的 memory 布局重新解释为 64 位 integer 的原因。

If the CPU had been big endian however, the uint32_t [2] would have been stored as:但是,如果 CPU 是大端,则uint32_t [2]将存储为:
11 22 33 44 55 66 77 88 and then it happens to get the same representation as a uint64_t with the value 0x1122334455667788 . 11 22 33 44 55 66 77 88然后它恰好得到与uint64_t相同的表示,值为0x1122334455667788


As a sidenote, the *(uint64_t *)array conversions in your code are undefined behavior because they violate strict pointer aliasing and could possibly also give misalignment.作为旁注,代码中的*(uint64_t *)array转换是未定义的行为,因为它们违反了严格的指针别名,并且还可能导致不对齐。 To convert between different memory types safely, you need to use bit shifts, memcpy or union .要安全地在不同的 memory 类型之间进行转换,您需要使用位移、 memcpyunion

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM