曾經在 C 語言面試時遇過 Big-Endian/ Little-Endian 的題目, 紀錄一下相關的概念!
差異
位元組順序(Endianness) 指的是記憶體實際上放置資料時的順序, 不同 CPU 可能會有不同的順序, 在不同機器或者網路交換環境中須要意識到這個問題, 由於 Intel 與 Microsoft 的商業成功, 因此 Little-Endian 相比 Big-Endian 更為常見;
假設我們有一個 32 位元(bits)的整數資料為 0x12345678,
Little-Endian 為:
1 2 3 4 5
| 0x12345678 在記憶體中的儲存順序: 0x7fffbffafb10 : 0x78 0x7fffbffafb11 : 0x56 0x7fffbffafb12 : 0x34 0x7fffbffafb13 : 0x12
|
Big-Endian 為:
1 2 3 4 5
| 0x12345678 在記憶體中的儲存順序: 0x7fffbffafb10 : 0x12 0x7fffbffafb11 : 0x34 0x7fffbffafb12 : 0x56 0x7fffbffafb13 : 0x78
|
判斷程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <stdio.h>
typedef union { unsigned long l; unsigned char c[4]; } EndianTest;
int main() { EndianTest _et; _et.l = 0x12345678; printf("本系統位元組順序為:"); if (_et.c[0] == 0x78 && _et.c[1] == 0x56 && _et.c[2] == 0x34 && _et.c[3] == 0x12) { printf("Little Endiann"); } else if (_et.c[0] == 0x12 && _et.c[1] == 0x34 && _et.c[2] == 0x56 && _et.c[3] == 0x78) { printf("Big Endiann"); } else { printf("Unknown Endiann"); } printf("0x%lX 在記憶體中的放置順序:n", _et.l); for (int i = 0; i < 4; i++) { printf("%p : 0x%02Xn", &_et.c[i], _et.c[i]); } return 0; }
|
※語法結構上,union
與 struct
類似,都是使用者自定義的資料結構。但差別最大的地方,就在於 union
結構中的各變數是共用記憶體位置。
參考:Big-Endian 與 Little-Endian 的差異與判斷程式碼