【问题标题】:Unexpected results when casting dword to byte [4] (endianity swap?)将 dword 转换为字节 [4] 时出现意外结果(字节顺序交换?)
【发布时间】:2013-08-23 21:19:41
【问题描述】:

我试图将 dword 转换为 4 个字节的数组。 当我这样做时,字节似乎会翻转(改变字节顺序)

据我了解,在小端系统上等于 0x11223344 的双字将如下所示:
0000_1011___0001_0110___0010_0001____0010_1100

但是当我这样做时:

typedef unsigned long dword;
typedef unsigned char byte;
int main(void)
{
    dword a = 0x11223344;
    byte b[4];
    memcpy(b, &a, 4);
    printf("%x %x %x %x\n", b[0], b[1], b[2], b[3]);
}

我得到 44 33 22 11
我预计会是 11 22 33 44

当我使用 reinterpret_cast 或

时也会发生同样的事情
union
{
dword a;
byte b[4];
} foo;

我猜我错了,而不是编译器/处理器,但我在这里缺少什么? 另外这在大端系统上看起来如何?

编辑: 所以我想我对小端系统的理解是错误的。 另一个问题:哪个会更快,同时仍然是可移植的:使用移位来获取单个字节值或使用 memcpy/reinterpret_cast 然后使用 htonl()/ntohl()?

【问题讨论】:

  • 在 little-endian 系统上,数字从小端(最低有效端)开始存储。
  • 你甚至没有读过en.wikipedia.org/wiki/Endianness,对吗?除此之外,在转换为二进制时,您将十六进制数视为按字节十进制...
  • 简短回答:不要这样做。要么使用适当的移位从原始字节自己组装值,要么使用像 ntols() 这样的运行时函数(注意:不提供标准库)。
  • 哪个更快,使用 ntols() 转换或 memcpy/reinterpret_cast;

标签: c++ casting endianness dword


【解决方案1】:

不,您对 little-endian 的理解不正确。 Little endian 表示最低有效字节位于最低内存地址。

还有:

据我了解,在小端系统上等于 0x11223344 的 dword 将如下所示:

0000 1011 0001 0110 0010 0001 0010 1100

该位模式与0x11223344 根本没有任何关系,无论是小端还是大端。在小端架构上,它会读取

0100 0100 0011 0011 0010 0010 0001 0001

然而,在大端系统上,同样的情况

0001 0001 0010 0010 0011 0011 0100 0100

【讨论】:

  • 哎呀,我意外地将它们从十进制 11 22 33 44 转换为二进制。但这现在确实有意义。我一直认为little endian是相反的。大端是更“正常”的风格,就像我们写数字一样,对吧?
  • @user2712404 两者都完全正常。
  • 想想对数字的实际解释可能会有所帮助。 IE。如果我有 0x0001 美元。根据字节顺序,我可能正在吃面条,或者我可能正在吃 256.00 美元的 surf n turf。
  • @user2712404 - 当您加减数字时,小端是更“正常”的样式。用铅笔和纸计算6174 + 5597
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多