整数中的每个字节如何存储在CPU /内存中?

Pyj*_*ong 6 c++ endianness memcpy

我试过这个

char c[4];
int i=89;
memcpy(&c[0],&i,4);
cout<<(int)c[0]<<endl;
cout<<(int)c[1]<<endl;
cout<<(int)c[2]<<endl;
cout<<(int)c[3]<<endl;
Run Code Online (Sandbox Code Playgroud)

输出如下:
89
0
0
0

哪个漂亮训练我的肚子因为我认为这个数字会被保存在内存中,如0x00000059所以为什么c [0]是89?我认为它应该在c [3] ...

Goz*_*Goz 32

因为您运行的处理器是little-endian.交换多字节基本类型的字节顺序.在大端机器上,它会像你期望的那样.

  • 大声笑.选择stupid_idiot作为您的屏幕名称意味着永远不必说"我很抱歉". (31认同)
  • 另请注意,您不能假设int长度为4个字节.始终使用sizeof(int).假设(在C中)我觉得可变的大小唯一的事情是sizeof(char)是1. (2认同)

Gre*_*osz 12

这是因为你在一个小端 cpu 上运行程序.参见ENDIANNESS 这里那里.

  • 提前退票:D (3认同)

Ala*_*lan 9

Goz指出,Endian-ness显然是答案.

但对于那些不清楚这意味着什么的人来说,理解示例中显示的字节顺序与原始int中的顺序相同也很重要.无论平台的edian类型如何,Memcpy都不会更改字节顺序.


Dig*_*oss 6

因为字节顺序是任意设计决定.一旦进入寄存器,就没有字节顺序1.

当我们处理像字节这样的较小单元时,会出现字节顺序.这是CPU设计者做出的一个基本上随意的决定:big-endian或little-endian.

它有助于简化情况并意识到它主要是与字节排序的外设的连接.是的,可以通过字节寻址发现它,如你所证明的那样,但通常标量值被加载并作为单元存储到寄存器中,在这种情况下,字节顺序不会改变任何东西.最重要的位在"左边",至少是我们通常写数字的方式.这就是为什么当根据语言标准使用时<<,>>运算符总是在big-endian和little-endian机器上产生完全相同的结果.

但是为了向外围设备读写数据流,您必须选择字节顺序.这是因为外设基本上是字节流设备.最低地址是最高有效位还是最低位?它完成了两种方式,并且过去的阵营相当均匀.

因为内存本身是字节寻址的,所以在没有外设的情况下导出不同的行为当然是可能的,但是如果没有像你那样刻意偷看,这通常不会发生.

想象一下,没有字节的CPU,只有32位字,寻址为0,1,2.C编译器生成char,int和long所有32位对象.(这是Cx9允许的.)哇,没有字节顺序问题!这两个都是!但是......当我们连接我们的第一个外设时会发生什么?


1. 好了,X86有一个较小的别名寄存器的寄存器,但这是另一个故事.