大小端的問題在很多面試筆試中都會遇到,最直接的考察是,筆試的時候,讓你寫一個代碼,如何確定當前系統是大端還是小端的。
什麼是大端和小端呢?
大端: 高位字節排放在內存的低地址端,低位字節排放在內存的高地址端。(CPU對操作數的存放方式是從高字節到低字節)
小端: 低位字節排放在內存的低地址端,高位字節排放在內存的高地址端。(CPU對操作數的存放方式是從低字節到高字節)
假設我們的內存是這樣的
我們要存一個數據 0x44332211到這塊內存裏面去如果系統是小端模式的話,存儲方式如下圖
如果系統是大端模式的話,存儲方式如下圖
好了,我們既然知道了大端和小端的存儲方式不同,那就可以寫代碼來判斷當前系統的存儲模式了。
其實做爲一個學習者,有一個學習的氛圍跟一個交流圈子特別重要這裏我推薦一個C語言C++交流羣1075673198,不管你是小白還是轉行人士歡迎入駐,大家一起交流成長。
方法一
#include <cstdio>int main(){int i = 1; (*(char *)&i == 1) ? printf("Little-endian\n") : printf("Big-endian\n"); return 0;}
指針類型轉換,最後取 char * 指針的值,也就是判斷 int 低地址的數據是否爲1。
方法二
#include <cstdio>union System{char a;int b;};int main(){ union System s;s.b = 1;printf("0x%x\n",&s.a);printf("0x%x\n",&s.b);if(s.a == 1){printf("Little-endian\n");}else{printf("Big-endian\n");} return 0;}
共用體的特點是,使用類型最大的那個類型作爲共用體的大小,所以,char a 使用的是 int b的空間大小,判斷 a的值,也就是判斷低地址的數據值。
方法三
#include<stdio.h>static union{ char a[4]; int ul;}endian = {{'L', '?', '?', 'B'}};#define ENDIAN ((char)endian.ul)int main(){ printf("%cENDIAN\n", ENDIAN); return 0;}
宏和字符數組
其實做爲一個學習者,有一個學習的氛圍跟一個交流圈子特別重要這裏我推薦一個C語言C++交流羣1075673198,不管你是小白還是轉行人士歡迎入駐,大家一起交流成長。
方法四
#include<stdio.h>int main(){int a = 0x44332211;char *b = (char *)&a;(*b == 0x11)?printf("Little-endian\n") : printf("Big-endian\n"); return 0;}
直接指針操作,原理也是取 int 低地址判斷裏面的數據。
總結
所有的判斷依據都是按照上面的理論來驗證的,讀者們如果對代碼有什麼疑惑或者問題的請給我留言,我也不敢保證自己寫的代碼一定是正確的,幾個方法也是參考網上的寫法,我最喜歡還是用union來實現。如果在面試中突然不知道怎麼寫,我建議還是畫個圖出來先理解一下,這樣更有利於寫代碼。