對于字節順序(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就可以知道機器的字節順序。