对于字节顺序(endianness)的概念,这里已经说的很清楚。
不过为了日后方便复习,我再重复一下:
一个w位的整数,有位表示[X(w-1), X(w-2), ..., X1, X0],其中X(w-1)是最高有效位,X0是最低有效位。如果w是8的倍数,则这些位可以分组成字节,其中最高有效字节包含位[X(w-1), X(w-2), ..., X(w-8)],最低有效字节包含位[X7, X6, ..., X1, X0]。
如果一种机器在存储器中按照从最高有效字节到最低有效字节的顺序存储,这种方式就叫做小端法(little endian); 另一些机器在存储器中则是按照从最低有效字节到最高有效字节的顺序存储,这种方式被称为大端法(big endian)。
那么,如何通过代码来判断机器的字节顺序呢?
网上搜索了一下,比较流行的方案是利用union的共用内存的特性来实现,有代码如下:
union
{
int a;
int b;
}endian;
endian.a = 1;
printf(endian.b == 1 ? "little endian" : "big endian");
不过个人感觉使用union不够直观和简洁,所以自己另外写了一个:
short endian = 0x00FF;
printf(*(char*)&endian ? "little endian" : "big endian");
首先单个字节不存在endian的问题,所以用一个2个字节(intel-x86-32)的short来模拟字节序列,上面代码中endian赋值后最高有效字节的二进制位全为0,而最低有效字节全为1。如果是在big endian的机器上,endian在内存中应该是这样存放的:
00000000 11111111
而在littel endian机器上又该是这样存放的:
11111111 00000000
如你所知,存储器按字节编址,(char*)&endian这行代码告诉编译器把endian当成字节序列来看待而不是short,这样(char*)&endian返回的结果就会是endian的最低有效字节的地址。这样,我们通过判断这个地址保存的值是否非0就可以知道机器的字节顺序。