我试过这个
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;
输出如下:
89
0
0
0
这非常训练我的胃,因为我认为这个号码会被保存在记忆中 0x00000059那么c [0]怎么来89?我认为它应该在c [3] ......
答案 0 :(得分:32)
因为您运行的处理器是little-endian。交换多字节基本类型的字节顺序。在大端机器上,它会像你期望的那样。
答案 1 :(得分:12)
这是因为你在little endian cpu上运行程序。另请参见endianness here和there。
答案 2 :(得分:9)
Endian-ness显然是Goz指出的答案。
但是对于那些不清楚这意味着什么的人来说,理解示例中显示的字节顺序与原始int中的顺序相同也很重要。无论平台的edian类型如何,Memcpy都不会更改字节顺序。
答案 3 :(得分:6)
当我们处理像字节这样的较小单位时会出现字节顺序。这是CPU设计者做出的一个基本上随意的决定:big-endian或little-endian。
简化情况并了解主要是与字节排序的外围设备的连接是有用的。是的,可以通过字节寻址发现它,如你所证明的那样,但通常标量值被加载并作为单元存储到寄存器中,在这种情况下,字节顺序不会改变任何东西。最重要的位在“左边”,至少是我们通常写数字的方式。这就是为什么<<
和>>
运算符在根据语言标准使用时总是在big-endian和little-endian机器上产生完全相同的结果。
但是为了向外围设备读写数据流,您必须选择字节顺序。这是因为外设基本上是字节流设备。最低地址是最高有效位还是最低位?它完成了两种方式,并且过去的阵营相当均匀。
因为内存本身是字节寻址的,所以在没有外设的情况下导出不同的行为当然是可能的,但是如果没有像你那样刻意偷看,这通常不会发生。
想象一下没有字节的CPU,只有32位字,寻址为0,1,2。C编译器生成char,int和long所有32位对象。 (这是Cx9允许的。)哇,没有字节顺序问题!这两个都是!但是......当我们连接第一个外设时会发生什么?
1. 嗯,x86的寄存器是别名较小的寄存器,但这是另一个故事。
答案 4 :(得分:2)
不同的机器可以有不同的字节顺序,但是看看这段代码并考虑会发生什么,具体取决于字节的配置方式:
long x = 89;
short *p = (short*)&x;
short y = *p;
答案 5 :(得分:1)
如果您希望您的应用程序可移植或在团队中开发,您可能不希望遵循此逻辑,因为它会导致难以捕获错误并延长开发。