什麼是大小端模式?
大小端儲存由 CPU架構 決定。
大端模式( big endian ):低地址存在高位資料,高地址存在低位資料;
小端模式( Little Endian ):低地址存在低位資料;高地址高位資料;
例如:
使用大端模式的有:Mac OS、PowerPC、IBM、Sun、 TCP/IP網路資料流;
使用小端模式的有:x86、Linux;
而ARM可以是大端模式,也可以是小端模式;
我們都知道在計算機記憶體中有大端和小端之分。。。
大端模式地址由小向大增加,而資料從高位往低位放;小端模式資料的高位元組在高地址中,低位元組在低地址中。
為什麼會有大小端模式之分呢?
下面用這張圖回答!
那麼,知道了大小端的原理,該如何判斷一臺機器是大端模式還是小端模式呢??
下面我介紹兩種判斷大小端的方法:
1.透過不同指標型別所指不同記憶體大小來判定
定義一個變數 int i = 0;
假設i在記憶體中這樣儲存:
將i的地址取出來並強制型別轉換成(char*)型,這樣p所能指向的物件即整型 i 的第一個位元組,這樣在對p進行解引用,根據*p的值判斷大小端:
若 *p == 0; 說明 i 在記憶體中確實如上圖儲存,高位在低地址,低位在高地址,為大端模式。。。
若 *p == 1;則說明 i 在記憶體中是將低位存在低地址,高位存在高地址,為小端模式。。。
程式碼:
int check_sys(){ int i = 1; char* p = (char*)&i; return *p == 1 ? 1 : 0;}
2.利用聯合體進行判斷
聯合體的特性:
聯合體所有成員變數共享記憶體,相對於聯合體首地址偏移量都為 0同一時間只能儲存1個被選擇的變數,對其他成員變數賦值會覆蓋原變數思路:由於聯合體的所有成員引用的都是記憶體中的相同地址,
舉個例子:
宣告一個聯合體
union n{ int a; char b;};
定義一個聯合體 :union n s;
很明顯,在32位平臺下此結構體總大小為4個位元組。
假設在 1 在記憶體中如下儲存:低位存在高地址,高位存在低地址,我們給s這個聯合體中a賦值1,即s.a = 1。即s.a 在記憶體中如下儲存。。
並且由於聯合體的覆蓋特性,我們從此聯合體中取s.b,由於s.b是一個字元型,在取時只能取一個位元組;
聯合體union的存放順序是所有成員都從低地址開始存放;必然也是從低地址開始讀取:
因此:
若 s.b = 0;即說明高位存在低地址,上面假設正確,為大端模式。。
若 s.b = 1;編譯器將低位存放在了低地址,說明上面假設不成立為小端模式。。
測試程式碼:
typedef union n{ int a; char b;}n;int main(){ n s; s.a = 1; if (s.b == 1) { printf("Little\n"); //小端 } else { printf("Big\n"); //大端 } system("pause"); return 0;}
<注:以上資料儲存為32位計算機。>