1. 程式人生 > >大小端位元組序的區別

大小端位元組序的區別

記憶體是以位元組為單位讀寫的,其最小的讀寫單位就是位元組。故如果在記憶體中寫入一個位元組,一個記憶體的儲存單元便可以將其容納了,只要訪問這一記憶體地址就能完整的取出這一位元組。但是一個位元組只能夠表示0~255(只考慮無符號數),超過這一範圍的數只好用多個位元組連在一起表示,因此,在我們32位程式中,定義的資料型別有很多,一位元組的資料型別只有char型,像int要佔四個位元組,double要佔八個位元組,那麼這麼多個位元組該以什麼順序存放呢。我們以0x1234為例,可以產生兩種排序:
(1)小端位元組序是數值的低位元組放在記憶體的低地址處,數值高的高位元組放在記憶體的高地址。
(2)大端位元組序是數值的低位元組放在記憶體的高地址處,數值高的高位元組放在記憶體的低地址。
我們可以寫一個程式判斷我們pc到底是哪一種位元組序:

#include<stdio.h>
int main()
{
    union
    {
        short value;
        char union_bytes[sizeof(short)];
    }test;
    test.value=0x0102;
    if((test.union_bytes[0]==1)&&(test.union_bytes[1]==2))
    {
        printf("big endian\n");
    }
    else if((test.union_bytes[0]==2)&&(test.union_bytes[1
]==1)) { printf("little endian\n"); } else { printf("unknown...\n"); } }

先看看這兩種位元組序的優勢:
(1)小端:因為低位在低位元組,強制轉換資料型別時不需要調整位元組了。
(2)大端:有符號位。其位元組最高位不僅表示數值本身,而且還起到了符號的作用。符號固定為第一位元組,也就是最高位佔據最低地址,符號可以取出來,容易判斷正負。
原理如下:
在做強制資料轉換時,如果轉換是由低精度到高精度,這數值本身沒什麼變換,如short兩個位元組,變成int為四個位元組,無非就是由0x1234到0x00001234,數值上不變,只是儲存形式變了。如果轉化是由高精度到低精度,丟棄的是高位元組,只保留低位元組,如0x12345678在轉化後變成0x5678。
對大端的優勢,符號判定更方便,因為符號儲存在低位元組,可以直接取到,不用在跨越幾個位元組,減少了時鐘週期。

常見CPU的位元組序如下:
(1)大端位元組序:IBM,Sun,PowerPC。
(2)小端位元組序:×86,DEC。
ARM體系的CPU大小端位元組序通吃,具體由硬體選擇。另外常說的網路位元組序就是大端位元組序,所以在×86架構上的程式傳送網路資料時,要轉換位元組序。轉換方法可在我的Linux伺服器程式設計欄目中可見。