有關位元組序的問題,最早**於jonathan swift書寫的《格列佛遊記》一書,這本書根據將雞蛋敲開的方法不同將所有的人分為兩類,從圓頭開始將雞蛋敲開的人被歸為big endian,從尖頭開始將雞蛋敲開的人被歸為littile endian。小人國的內戰就源於吃雞蛋時是究竟從大頭(big-endian)敲開還是從小頭(little-endian)敲開。
有關具體的大小端描述,想必資料網上都有,下面簡要給出結果:
大端:高位存在低位址,低位存在高位址;
小端:高位存在高位址,低位存在低位址;(intel的x86,arm普遍都是屬於小端)
比如數值 0x123456
大端模式:
低位址 -------------> 高位址
0x12 | 0x34 | 0x56
小端模式:
低位址 ------------> 高位址
0x56 | 0x34 | 0x12
下面針對幾個問題:(1)字串有大小端問題嗎?(2)位元組內的順序問題?(3)位域的情況又是如何?進行**。
(1)字串沒有大小端問題。
理由:大小端問題是針對計算機中某種型別(內建)的儲存順序。因為計算機以位元組為儲存單位,像乙個char型別的只佔乙個位元組,固然不需要考慮順序問題;但是像int型別,一般佔4個位元組,這就存在順序問題了。既可以從高到低,也可以從低到高。所以,才有大小端問題的出現。對於字串,
是由字元組成的(可以看成字元陣列),儲存的單個物件就是字元,所以不需要大小端。
(2)位元組內的順序問題:除位域外,不需要關心位元組內的順序,它是正常的順序。
(3)位域的情況比較複雜,看下面的例子:
①乙個位域必須儲存在同乙個位元組中,不能跨兩個位元組。如:
structbs
②由於位域不允許跨兩個位元組,因此
位域的長度不能大於乙個位元組的長度。
③位域可以無位網域名稱
,這時它只用來作填充或調整位置。無名的位域是不能使用的。例如:
structk;
④位域內的變數儲存與大小端有關,若是小端格式,則成員變數儲存的順序是以其在
結構體內定義順序相反。例如:
1 #include 2 #include 3問輸出的結果。using
namespace
std;
4structa5
;9int main(void)10
分析:低位址 ----------------------------------> 高位址
00110000|00110001|
00110011|
00110100
『0』 『1』 『3』 『4』
根據④ d.a和d.b各佔5位和3位,正好前乙個位元組,即
00110000。所以d.a為10000(機器內:
11111111111111111111111111110000
),d.b為001(機器內:
00000000000000000000000000000001
)皆為補碼。所以最後結果:-16
1
⑤位域的對齊
如果結構體中含有位域(bit-field),那麼vc中準則是:
1) 如果相鄰位域字段的型別相同,且其位寬之和小於型別的sizeof大小,則後面的字段將緊鄰前乙個字段儲存,直到不能容納為止;
2) 如果相鄰位域字段的型別相同,但其位寬之和大於型別的sizeof大小,則後面的字段將從新的儲存單元開始,其偏移量為其型別大小的整數倍;
3) 如果相鄰的位域字段的型別不同,則各編譯器的具體實現有差異,vc6.0採取不壓縮方式(不同位域字段存放在不同的位域型別位元組中),dev-c++和gcc都採取壓縮方式;系統會先為結構體成員按照對齊方式分配空間和填塞(padding),然後對變數進行位域操作。
大小端,位元組序問題
總結 1 80x86使用小端法,網路位元組序使用大端法。2 二進位制的網路程式設計中,傳送資料,最好以unsigned char,unsigned short,unsigned int 來處理,unsigned short unsigned short 以網路位元組序處理後再拷貝到傳送的buffer...
大小端位元組序問題
大端模式 big endian 資料的高位元組儲存在記憶體低位址中,而資料的低位元組則存放在記憶體高位址中。與思維習慣不一致,但與實際資料的表達方式一致。如powerpc的unix系統 小端模式 little endian 資料的高位元組儲存在記憶體高位址中,而資料的低位元組則存放在記憶體低位址中 ...
大小端 位元組序問題
大小端 位元組序問題 大小端解析 端模式出自jonathan swift書寫的 格列佛遊記 一書,這本書根據將雞蛋敲開的方法不同將所有的人分為兩類,從圓頭開始將雞蛋敲開的人被歸為big endian,從尖頭開始將雞蛋敲開的人被歸為littile endian。小人國的內戰就源於吃雞蛋時是究竟從大頭 ...