位元組(byte)作為計算機世界的計量單位,和大家手中的人民幣多少多少「元」乙個意思。反正,到了計算機的世界,說位元組就對了,使用人家的基本計量單位,這是入鄉隨俗。
比如,乙個電影是1g個位元組(1gb),一首歌是10m個位元組(10mb),一張是1k個位元組(1kb)。
一元錢可以幹嘛?啥也幹不了,公交都不夠坐的。乙個位元組可以幹嘛?至少可以存乙個字元。
當資料太大,乙個位元組存不下的時候,我們就得使用多個位元組了。比如,我有兩個分別需要4個位元組儲存的整數,為了方便說明,使用16進製表示這兩個數,即0x12345678和0x11223344。有的人採用以下方式儲存這個兩個數字:
這個方案看起來不錯,但是,又有人採用了以下方式:
矇圈了吧,到底該用哪一種方式來存!兩種方案雖有不同,但也有共識,即依次儲存每乙個數字,即先存0x12345678,再存0x11223344。大家的分歧在於,對於某乙個要表示的值,因為只能乙個位元組乙個位元組的存嘛,我是把值的低位存到低位址,還是把值的高位存到低位址。前者使用的是「小端(little endian)」位元組序,即先存低位的那一端(兩個數字的最低位分別是0x78、0x44),如上圖中的第乙個圖;後者使用的是「大端(big endian)」位元組序,即先存高位的那一端(兩個數字的最高位分別是0x12、0x11),如上圖中的第二個圖。
由此也引發了計算機界的大端與小端之爭,不同的cpu廠商並沒有達成一致:
大端也好,小端也罷,就權當是個人愛好吧,只要你不影響別人就行,對不?
前面的大端和小端都是在說計算機自己,也被稱作主機位元組序。其實,只要自己能夠自圓其說是沒啥問題的。問題是,網路的出現使得計算機可以通訊了。通訊,就意味著相處,相處必須得有共同語言啊,得說普通話,要不然就容易會錯意,下了乙個小時的小電影發現打不開,理解錯誤了!
但是每個計算機都有自己的主機位元組序啊,還都不依不饒,堅持做自己,怎麼辦?
tcp/ip協議隆重出場,rfc1700規定使用「大端」位元組序為網路位元組序,其他不使用大端的計算機要注意了,傳送資料的時候必須要將自己的主機位元組序轉換為網路位元組序(即「大端」位元組序),接收到的資料再轉換為自己的主機位元組序。這樣就與cpu、作業系統無關了,實現了網路通訊的標準化。突然覺得,tcp/ip協議好任性啊有木有!
為了程式的相容,你會看到,程式設計師們每次傳送和接受資料都要進行轉換,這樣做的目的是保證**在任何計算機上執行時都能達到預期的效果。
這麼常用的操作,bsd socket提供了封裝好的轉換介面,方便程式設計師使用。包括從主機位元組序到網路位元組序的轉換函式:htons、htonl;從網路位元組序到主機位元組序的轉換函式:ntohs、ntohl。當然,有了上面的理論基礎,也可以編寫自己的轉換函式。
下面的一段**可以用來判斷計算機是大端的還是小端的,判斷的思路是確定乙個多位元組的值(下面使用的是4位元組的整數),將其寫入記憶體(即賦值給乙個變數),然後用指標取其首位址所對應的位元組(即低位址的乙個位元組),判斷該位元組存放的是高位還是低位,高位說明是big endian,低位說明是little endian。
#include int main ()
else
return 0;
}
字元編碼方式utf-16、utf-32同樣面臨位元組序的問題,因為他們分別使用2個位元組和4個位元組編碼unicode字元,一旦某個值用多個位元組表示,就必須要考慮儲存的順序了。於是,採用了最簡單粗暴的方式,給檔案頭部寫幾個字元,用來表示是大端呢還是小端:
頭部的字元 編碼 位元組序 ff fe utf-16/ucs-2 little endian fe ff utf-16/ucs-2 big endian ff fe 00 00 utf-32/ucs-4 little endian 00 00 fe ff utf-32/ucs-4 big-endian
這裡不得不提一下utf-8啊,明明人家是單個位元組的,不存在什麼位元組序的問題。微軟為了統一utf-x,硬生生給他的頭部也加了幾個字元!是的,這幾個字元就是bom(byte order mark),這就是windows下的utf-8。
相信很多人都被utf-8的bom給坑過,多了這個bom的utf-8檔案,會導致很多問題啊。比如,寫的shell指令碼,內容為#!/usr/bin/env bash,在utf-8有bom和utf-8無bom的編碼下,對應的16進製為:
所以,有bom的話,shell直譯器就報錯啦。原因在於,直譯器希望遇到#!/usr/bin/env bash,而使用utf-8有bom進行編碼的內容會多了3個位元組的ef bb bf。
對於utf-8和utf-8無bom兩種編碼格式,我們更多的使用utf-8無bom。
大小端位元組序
1.大端和小端問題 大小端位元組序與硬體有關 intel x86 都是小端位元組序 總結 大端是 按照正常我們書寫的順序來儲存的 小端是 按照我們書寫順序相反的 實現 include int main putchar n printf x n a return 0 檢視輸出結果,判斷大小端位元組序 ...
位元組序 大小端
計算機的基本儲存單元是8位單位元組。多位元組資料,如4位元組的整型資料如何儲存的呢?是高位在記憶體高位元組?還是低位在記憶體高位元組?即位元組是按如何順序存放的?也就是所謂的位元組序,按照存放順序分為大端序 big endian 和小端序 little endian 記憶體位址訪問是由低位址到高位址...
大小端位元組序
計算機硬體有兩種儲存資料的方式 大端位元組序 big endian 和小端位元組序 little endian 比如十六進製制數0x0102,十六進製制每個數字佔4bit,四個數字16bit,也就是2byte,2個位元組儲存。0x0102高位位元組是0x01,低位位元組是0x02。l大端位元組序 高...