blavince's BLOG

Giving is a reward in itself.

0%

Big-Endian 與 Little-Endian 的差異與判斷程式碼

曾經在 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;
}

語法結構上,unionstruct 類似,都是使用者自定義的資料結構。但差別最大的地方,就在於 union 結構中的各變數是共用記憶體位置。

參考:Big-Endian 與 Little-Endian 的差異與判斷程式碼