在一个特定的硬件平台上,多字节数据是以怎样的顺序存放的呢?
譬如有一个32位的整数0x12345678(占4个字节),假设这个数存放其实地址为0x04000000的内存中,那么,从0x04000000到0x04000003这4个字节内存的情况究竟是:
内存地址 数值
0x04000003 0x12
0x04000002 0x34
0x04000001 0x56
0x04000000 0x78
还是:
内存地址 数值
0x04000003 0x78
0x04000002 0x56
0x04000001 0x34
0x04000000 0x12
区别很明显:前者是数据的低字节部分放在低地址内存,后者刚好相反——数据的高字节部分存放在低地址内存。
在现实中有两种情况都有。CPU架构在这个问题上可以分为两大类,分别称为“little—endian”和“big—endian”。仅仅从名字我们就能够看出它们的差别。我们身边最常见的pc是基于IA-32微处理器的,而IA-32属于little-endian类;某些RISC架构的CPU,例如SPARC,PowerPC等,则属于big-endian类。
可是这与C语言有什么关系呢?
——别忘了,C语言是用来编写系统程序的“中级语言”,很多时候我们用它直接对硬件进行操作。稍不留神就会出现移植问题。
看看下边的代码:
#include <stdio.h>
int main(void)
{
int i = 0x00000041;
char *p = (char*)&i;
printf("%s\n",p);
return 0;
}
如果在IA-32平台上编译执行,输出结果是大写字母“A”(字母“A”的ASCII码是0x41,即65):
p
0x41 | 0x00 | 0x00 | 0x00 |
低地址内存 高地址内存
而在big-endian平台上的编译执行,则什么都不会输出:
p
0x00 | 0x00 | 0x00 | 0x41 |
低地址内存 高地址内存