什麼是大小端?
大端:高位數據存放在低地址,低位數據存放在高地址。
小端:高位數據存放在高地址,低位數據存放在低地址。
舉個例子,一個 short 類型的數,用十六進制表示出來是 0x1234,那麼,0x12就是高位了,0x34就是低位了。然後我們看看數組的地址,一個 byte 數組 buf[2],其中,buf[0] 是地地址,buf[1]是高地址。那麼,大端的數據是這樣放的 :
buf[0] | 0x12 | 低地址 | 高位數據 |
buf[1] | 0x34 | 高地址 | 低位數據 |
這樣子比較符合日常的閱讀,類似於讀字符串那樣子。那麼小端的則搞好相反:
buf[0] | 0x34 | 低地址 | 低位數據 |
buf[1] | 0x12 | 高地址 | 高位數據 |
這樣子感覺上是將 12 34 倒着存起來。
爲啥會有大下端之分呢
這就像雞蛋應該從小頭打碎還是大頭打碎一樣,沒有對錯,只是方式不同。
一般情況下,x86架構都是使用的小端模式,而且只支持小端。ARM默認小端模式,但是可以切換爲大端。
編譯器也會有大小端之分,C語言默認是小端,java是大端。
網絡上傳輸的數據普遍是大端的。
怎麼判斷機器是大端還是小端呢
在 windows下,使用C#,可以這樣判斷:
int i = 1;
//將int 轉換到數組中,然後根據數組的地址進行判斷
byte[] buf = BitConverter.GetBytes(i);
if(buf[0] == 1)
{
Console.WriteLine("小端");
}else{
Console.WriteLine("大端");
}
使用C語言其實更容易判斷,通過指針和取址運算:
int i = 1;
//將 int 類型轉換爲 char*,然後拿到第一個字節的數據進行判斷
char c = *(char *)&i;
if (c == 1)
{
printf("小端");
}
else
{
printf("大端");
}