7

我试过这个

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] 中...

4

6 回答 6

33

因为您运行的处理器是little-endian。多字节基本类型的字节顺序被交换。在大端机器上,它会如您所料。

于 2009-12-03T19:10:47.607 回答
12

这是因为您在一个小端cpu 上运行该程序。另请参阅此处此处的字节序。

于 2009-12-03T19:11:35.720 回答
9

正如 Goz 所指出的,Endian-ness 显然是答案。

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

于 2009-12-03T19:15:20.240 回答
6

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

当我们处理像字节这样的较小单位时,就会出现字节顺序。这基本上是 CPU 设计人员做出的任意决定:大端或小端。

简化情况并认识到主要是与外围设备的连接是按字节排序的,这很有用。是的,正如您已经证明的那样,它可以通过字节寻址发现,但通常标量值作为单位加载并存储到寄存器中,在这种情况下字节顺序不会改变任何东西。最重要的位在“左边”,至少,我们通常写数字的方式。这就是为什么<<and>>运算符在根据语言标准使用时,在大端和小端机器上总是产生完全相同的结果。

但是为了向外围设备读写数据流,你不得不选择一个字节顺序。这是因为外围设备本质上是字节流设备。最低地址是最高有效位还是最低?它是双向进行的,阵营过去是相当平均的。

因为内存本身是字节寻址的,所以当然可以在没有外围设备的情况下派生出不同的行为,但这通常不会像您那样在没有刻意窥视的情况下发生。

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


1.嗯,x86 有一些寄存器,它们为较小的寄存器起别名,但那是另一回事了。

于 2009-12-04T05:21:32.613 回答
2

不同的机器可以有不同的字节顺序,但是看看这段代码并考虑会发生什么,这取决于字节的布局方式:

long x = 89;
short *p = (short*)&x;
short y = *p;
于 2009-12-03T19:16:27.593 回答
1

If you want your application to be portable or developed within a team, you probably don't want to follow this logic as it would cause hard to catch bugs and prolong development.

于 2009-12-03T20:34:27.833 回答