整型,長整型,無符號整型等 大端和小端(Big endian and Little endian)

1、大端和小端的問題網絡

對於整型、長整型、無符號整型等數據類型,Big endian 認爲第一個字節是最高位字節(按照從低地址到高地址的順序存放數據的高位字節到低位字節);而 Little endian 則相反,它認爲第一個字節是最低位字節(按照從低地址到高地址的順序存放據的低位字節到高位字節)。ui

例如,假設從內存地址 0x0000 開始有如下數據:  
0x0000         0x0001       0x0002       0x0003  
0x12            0x34           0xab           0xcd 
若是咱們去讀取一個地址爲 0x0000 的四個字節變量,若字節序爲big-endian,則讀出結果爲0x1234abcd;若字節序爲little-endian,則讀出結果爲0xcdab3412。spa

若是咱們將0x1234abcd 寫入到以 0x0000 開始的內存中,則Little endian 和 Big endian 模式的存放結果以下:  
地址           0x0000         0x0001        0x0002          0x0003 
big-endian   0x12           0x34            0xab            0xcd  
little-endian  0xcd           0xab            0x34            0x12操作系統

通常來講,x86 系列 CPU 都是 little-endian 的字節序,PowerPC 一般是 big-endian,網絡字節順序也是 big-endian還有的CPU 能經過跳線來設置 CPU 工做於 Little endian 仍是 Big endian 模式。code

對於0x12345678的存儲:blog

小端模式:(從低字節到高字節)
地位地址 0x78 0x56 0x34 0x12 高位地址內存

大端模式:(從高字節到低字節)
地位地址 0x12 0x34 0x56 0x78 高位地址it

2、大端小端轉換方法io

htonl() htons() 從主機字節順序轉換成網絡字節順序
ntohl() ntohs() 從網絡字節順序轉換爲主機字節順序class

Big-Endian轉換成Little-Endian

#define BigtoLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | (((uint16)(A) & 0x00ff) << 8))
#define BigtoLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | (((uint32)(A) & 0x00ff0000) >> 8) | \
             (((uint32)(A) & 0x0000ff00) << 8) | (((uint32)(A) & 0x000000ff) << 24))

3、大端小端檢測方法

如何檢查處理器是big-endian仍是little-endian?

C程序:

    int i = 1;   
    char *p = (char *)&i;   
    if(*p == 1)     
          printf("Little Endian"); 
    else
          printf("Big Endian");

 大小端存儲問題,若是小端方式中(i佔至少兩個字節的長度)則i所分配的內存最小地址那個字節中就存着1,其餘字節是0.大端的話則1在i的最高地址字節處存放,char是一個字節,因此強制將char型量p指向i則p指向的必定是i的最低地址,那麼就能夠判斷p中的值是否是1來肯定是否是小端。

  聯合體union的存放順序是全部成員都從低地址開始存放,利用該特性就能夠輕鬆地得到了CPU對內存採用Little-endian仍是Big-endian模式讀寫

/*return 1: little-endian, return 0: big-endian*/
int checkCPUendian()
{
  union
  {
    unsigned int a;
    unsigned char b; 
  }c;
  c.a = 1;
  return (c.b == 1); 
}

實現一樣的功能,來看看Linux 操做系統中相關的源代碼是怎麼作的:

static union { char c[4]; unsigned long mylong; } endian_test = {{ 'l', '?', '?', 'b' } };

#define ENDIANNESS ((char)endian_test.mylong)
相關文章
相關標籤/搜索