【问题标题】:C++ byte order when casting int to byte array将 int 转换为字节数组时的 C++ 字节顺序
【发布时间】:2015-01-17 07:35:14
【问题描述】:

鉴于我的平台是小端序,我假设一个四字节整数值 1 将表示为0x000x000x000x01,当表示为字节数组时。有了这个,有人可以向我解释为什么以下断言失败...

int val{1};
auto bytes = reinterpret_cast<char*>(&val);
assert(bytes[sizeof(int) - 1] == 0x01);

...但是下面的断言成功了...

assert(bytes[0] == 0x01);

在转换为char* 之后,字节似乎被颠倒了。我对字节顺序的假设是错误的吗?是编译器(clang)还是语言抽象了字节序?怎么回事?

【问题讨论】:

  • Little endian - 第一个字节是最小的 - 即。 1
  • 小端的意思是“小端优先”,“小端”=“最不重要”,内存中的“第一”

标签: c++ casting endianness


【解决方案1】:

你的假设是相反的。在 little endian 中,32 位整数值 1 以十六进制表示为 0x00000001,但以字节表示为 0x01 0x00 0x00 0x00

【讨论】:

    【解决方案2】:

    Little endian 意味着您首先写入或存储数字的最低有效位。 Big endian 意味着您首先写入或存储最重要的数字。

    考虑一下我们通常在纸上写数字的方式。在纸上写以 10 为底的数字 4823 时,我们将其写成 big-endian。第一个数字 4 是千位数字。我们称它为最高有效数字,因为它对数字大小的影响最大。第二个数字 8 是百位数字。第三个数字 2 是十位数字。第四个(也是最后一个)数字 3 是个位(或个位)数字。我们称个位数为最不重要的数字,因为它对数字大小的影响最小。

    四字节(32 位)整数作为基数 256 数字存储在内存中。每个字节是一个数字,但数字的范围是从 0 到 255,而不是从 0 到 9。

    little endian 平台首先存储最低有效字节,即个位。 256s 数字是第二个字节。 65536s 数字是第三个字节。 16777216s 是第四位(也是最后一位)。

    因此,在您的示例中,我们可以将数字在纸上写为 0x00000001(因为我们几乎总是在纸上大端写数字),但在小端系统中,字节(以 256 位为基数)按顺序存储01 00 00 00.

    (请注意,我们无法在大多数系统上直接寻址单个位。因此,在机器代码级别无法判断字节中的各个位是存储小端还是大端,或者是否是甚至是硬件级别的一个有意义的概念。这就是为什么我说这个数字是以 256 为基数存储的,而不是以 2 为基数的。)

    【讨论】:

      【解决方案3】:

      你说,

      鉴于我的平台是小端序,我假设一个四字节整数值 1 在表示为字节数组时将表示为 0x000x000x000x01

      不正确的假设。那将是大端系统。见http://en.wikipedia.org/wiki/Endianness#Big-endian

      【讨论】:

        【解决方案4】:

        Little endian 表示最低有效位在前,因此在内存中,1 将具有 0x00000001。请注意,这里的“第一个”是指右边,因为那是发生截断的地方。如果将 32 位整数转换为 8 位整数,您将得到最右边的部分(即0x01)。

        【讨论】:

        • 从基地址开始的逐字节图片可能会更清晰。在内存中,01 00 00 00 用于小端,00 00 00 01 用于大端。而且我看不出“截断”与OP的代码有什么关系,而且无论如何都是不正确的。从 32 位 int 转换为 8 位 int。将通过价值表示来完成;不是内存布局。不管你是在大端还是小端机器上,static_cast&lt;char&gt;(int(1)) 会产生一个char,其值为0x01
        猜你喜欢
        • 2011-09-04
        • 1970-01-01
        • 2011-04-16
        • 1970-01-01
        • 2010-10-22
        • 1970-01-01
        • 2023-03-03
        相关资源
        最近更新 更多