小端格式和大端格式(Little-EndianBig-Endian)
小端格式和大端格式(Little-Endian&Big-Endian)
1 字節序
字節序,也就是字節的順序,指的是多字節的數據在內存中的存放順序。
在幾乎所有的機器上,多字節對象都被存儲為連續的字節序列。
例如:如果C/C++中的一個int型變量 a 的起始地址是&a = 0x100,那么 a 的四個字節將被存儲在存儲器的0x100, 0x101, 0x102, 0x103位置。
不同的CPU有不同的字節序類型,最常見的有兩種:
-
Little-Endian:將低序字節存儲在起始地址(低位編址)
-
Big-Endian:將高序字節存儲在起始地址(高位編址)
舉例說明如下圖
然后就牽涉出兩大CPU派系:
- Motorola 6800,PowerPC 970,SPARC(除V9外)等處理器采用Big-Endian方式存儲數據;
- x86系列,VAX,PDP-11等處理器采用Little0Endian方式存儲數據。
- 另外,還有一些處理器像ARM, DEC Alpha的字節序是可配置的。
2 LE(Little-Endian)
最符合人的思維的字節序
地址低位存儲值的低位,地址高位存儲值的高位。
因為從人的第一觀感來說,低位值小,就應該放在內存地址小的地方,也即內存地址低位。反之,高位值就應該放在內存地址大的地方,也即內存地址高位。所以說是最符合人的思維的字節序。
就好比我們從小學的計數法,個位代表的單位值最小,放在最低位,以此類推十位,百位。
優勢:長度為1,2,4字節的數,排列方式都是一樣的,數據類型轉換非常方便。
舉個例子:在內存中雙字0x01020304(DWORD)和0x1234abcd的存儲方式。
| LE | 04 | 03 | 02 | 01 |
| LE | 0xcd | 0xab | 0x34 | 0x12 |
注:每個地址存1個字節,每個字有4個字節。2位16進制數是1個字節(0xFF=11111111)。
3 BE(Big-Endian)
最直觀的字節序
地址低位存儲值的高位,地址高位存儲值的低位,
只需要把內存地址從左到右按照由低到高的順序寫出,也就是把值按照通常的高位到低位的順序寫出,一個字節一個字節的填充進去即可,直接閱讀從低到高的地址里面的數據即可。
舉個例子:在內存中雙字0x01020304(DWORD)和0x1234abcd的存儲方式。
| BE | 0x01 | 0x02 | 0x03 | 0x04 |
| BE | 0x12 | 0x23 | 0xab | 0xcd |
注:每個地址存1個字節,每個字有4個字節。2位16進制數是1個字節(0xFF=11111111)。
4 為什么要注意字節序
如果你寫的程序只在單機環境下面運行,并且不和別人的程序打交道,那么你完全可以忽略字節序的存在。
但是,如果你的程序要跟別人的程序產生交互呢? 比如,當一個 C/C++ 的程序要與一個 Java 程序交互時:
- C/C++語言編寫的程序里數據存儲順序是跟編譯平臺所在的CPU相關的,而現在比較普遍的 x86 處理器是 Little Endian
- JAVA編寫的程序則唯一采用 Big Endian 方式來存儲數據
試想,如果你的C/C++程序將變量 a = 0x12345678 的首地址傳遞給了Java程序,由于Java采取 Big Endian 方式存儲數據,很自然的它會將你的數據翻譯為 0x78563412。顯然,問題就出現了!!!
另外,網絡傳輸一般采用 Big Endian,也被稱之為網絡字節序,或網絡序。當兩臺采用不同字節序的主機通信時,在發送數據之前都必須經過字節序的轉換成為網絡字節序后再進行傳輸。
5 判斷機器的字節序
由于 C/C++ 存儲數據時的字節序依賴所在平臺的CPU,所以我們可以通過C/C++程序判定機器的端序:
void Endianness() {int a = 0x12345678;if( *((char*)&a) == 0x12)cout << "Big Endian" << endl;elsecout << "Little Endian" << endl; }參考文獻
小端格式和大端格式(Little-Endian&Big-Endian) - 清風行云 - 博客園
字節序:Big Endian 和 Little Endian | 神奕的博客
總結
以上是生活随笔為你收集整理的小端格式和大端格式(Little-EndianBig-Endian)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JSON格式转换成XML格式
- 下一篇: Abaqus液体中气液两相的气泡仿真