little endian和big endian的概念解釋,斷定與用途

轉貼地址:http://www.chinaunix.net/jh/23/823662.htmlphp

#######################
html

//聲明: 1  本帖做者是:converse ,至此感謝!編程

              2  紅色背景字體爲本人添加內容!
網絡

              3  黃色背景爲我的閱讀重點!
字體

#######################
ui


little endian和big endian的概念解釋,斷定與用途

       little endian和big endian是表示計算機字節順序的兩種格式,所謂的字節順序指的是長度跨越多個字節的數據的存放形式. 
spa

        假設從地址0x00000000開始的一個字中保存有數據0x1234abcd,那麼在兩種不一樣的內存順序的機器上從字節的角度去看的話分別表示爲: 
       1)little endian:在內存中的存放順序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12 
       2)big  endian:在內存中的存放順序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd 
       須要特別說明的是,以上假設機器是每一個內存單元以8位即一個字節爲單位的. 

       簡單的說,little endian把低字節存放在內存的低位;而big endian將低字節存放在內存的高位.  
.net

                      字節                         little endian                           big endian                內存                       

     低         0x0000000                        cd                                         12                       12          高位        
unix

      |            0x0000001                        ab                                         34                       34            |            
code

     ∨          0x0000002                        34                                         ab                        ab           ∨         

     高          0x0000003                        12                                         cd                        cd         低位        

       如今主流的CPU,intel系列的是採用的little endian的格式存放數據,而motorola系列的CPU採用的是big endian. 

        
       如下是判斷字節存儲順序的可移植的C語言代碼: 
 /******************************************************************** created: 2006-9-5 filename:  test.cpp author: 李創 purpose: 可移植的用於判斷存儲格式是                 little endian仍是big ednian的C代碼                 取自<<C: A Reference Manual>> *********************************************************************/ #include <stdio.h> union { long Long; char Char[sizeof(long)]; }u; int main() { u.Long = 1; if (u.Char[0] == 1) { printf("Little Endian!\n"); } else if (u.Char[sizeof(long) - 1] == 1) { printf("Big Endian!\n"); } else { printf("Unknown Addressing!\n"); }     printf("Now, Let's look at every byte in the memory!\n");     for (int i = 0; i < sizeof(long); ++i)     {         printf("[%x] = %x\n", &u.Char, u.Char);     } return 0; }


 不少人認爲掌握這個知識是沒必要要,其實否則.在網絡編程中,TCP/IP統一採用big endian方式傳送數據,也就是說,假設如今是在一個字節順序是little endian的機器上傳送數據,要求傳送的數據是0XCEFABOBO,那麼你就要以0XBOBOFACE的順序在unsigned int中存放這個數據,只有這樣才能保證存放的順序知足TCP/IP的字節順序要求.不少時候,須要本身編寫應用層的協議,字節順序的概念在這個時候就顯得及其的重要了. 
       下面給出的是在big endian和little endian中相互轉換的代碼,C語言強大的位操做的能力在這裏顯示了出來: 

/********************************************************************

	created:	2006-9-5

	filename: 	get32put32.cpp

	author:		李創

	

	purpose:	在little endian和big ednian之間相互轉化數據的演示代碼



*********************************************************************/





#include <stdio.h>



const unsigned char SIZE_OF_UNSIGNEDINT  = sizeof(unsigned int);

const unsigned char SIZE_OF_UNSIGNEDCHAR = sizeof(unsigned char);



void put_32(unsigned char *cmd, unsigned int data)

{

    int i;

    for (i = SIZE_OF_UNSIGNEDINT - 1; i >= 0; --i)

    {

        cmd = data % 256;

        // 或者能夠:

        //cmd = data & 0xFF;

        data = data >> 8;

    }

}



unsigned int get_32(unsigned char *cmd)

{

    unsigned int  ret;

    int i;



    for (ret = 0, i = SIZE_OF_UNSIGNEDINT - 1; i >= 0; --i)

    {

        ret  = ret << 8;

        ret |= cmd;        

    }

	

    return ret;

}



int main(void)

{

    unsigned char cmd[SIZE_OF_UNSIGNEDINT];

    unsigned int data, ret;

    unsigned char *p;

    int i;



    data = 0x12345678;

    printf("data = %x\n", data);

    // 以字節爲單位打印出數據

    p = (unsigned char*)(&data);

    for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i)

    {

        printf("%x", *p++);

    }

    printf("\n");



    // 以相反的順序存放到cmd之中

    put_32(cmd, data);

    for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i)

    {

        printf("cmd[%d] = %x\n", i, cmd);

    }



    // 再以相反的順序保存數據到ret中

    // 保存以後的ret數值應該與data相同

    ret = get_32(cmd);

    printf("ret = %x\n", ret);

    p = (unsigned char*)(&ret);

    for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i)

    {

        printf("%x", *p++);

    }

    printf("\n");



    return 0;

}
相關文章
相關標籤/搜索