鉴于我的平台是小端,我假设一个四字节整数值1将表示为0x00
,0x00
,0x00
,0x01
表示为字节数组。有了这个,有人可以向我解释为什么下面的断言失败了......
int val{1};
auto bytes = reinterpret_cast<char*>(&val);
assert(bytes[sizeof(int) - 1] == 0x01);
...但以下断言成功......
assert(bytes[0] == 0x01);
转换为char*
后,字节似乎相反。我对字节序的假设是错误的吗?编译器(clang)或语言是否抽象出字节序?发生了什么事?
答案 0 :(得分:7)
你的假设是相反的。在little endian中,32位整数值1以十六进制表示为0x00000001
,但以字节表示为0x01 0x00 0x00 0x00
。
答案 1 :(得分:4)
你说,
鉴于我的平台是小端,我假设一个四字节整数值1将表示为
0x00
,0x00
,0x00
,0x01
表示为字节数组。
不正确的假设。这将是大端系统。请参阅http://en.wikipedia.org/wiki/Endianness#Big-endian。
答案 2 :(得分:4)
Little endian表示您首先编写或存储该数字的最低有效位。 Big endian意味着您首先编写或存储最重要的数字。
考虑我们通常在纸上写数字的方式。当在纸上写下基数10号码4823时,我们把它写成大端。第一个数字4是千位数。我们称之为最重要的数字,因为它对数量的影响最大。第二个数字8是百位数。第三个数字2是十位数。第四个(和最后一个)数字3是一个(或单位)数字。我们将那些数字称为最不重要的数字,因为它对数量的影响最小。
四字节(32位)整数作为基数256存储在存储器中。每个字节都是一位数字,但数字的范围是0到255而不是0到9。
小端平台首先存储最低有效字节,即数字。 256s数字是第二个字节。 65536s数字是第三个字节。 16777216s数字是第四位(和最后一位)。
因此在你的例子中,我们可以将数字写在纸上作为0x00000001(因为我们几乎总是在纸质大端上写数字),但在小端系统上,字节(基数256位)按顺序存储01 00 00 00
。
(注意,我们不能直接在大多数系统上寻址单个位。因此,在机器代码级别,没有办法告诉一个字节中的各个位是以little-endian还是big-endian存储,或者是否是甚至是硬件级别的一个有意义的概念。这就是为什么我说这个数字存储在256位而不是2位。)
答案 3 :(得分:-1)
Little endian首先表示最低有效数字,因此在内存中,0x00000001
为1
。请注意,“first”在这里意味着在右边,因为那是截断发生的地方。如果将该32位整数转换为8位整数,则会得到最右边的部分(即0x01
)。