1:大小端名字的由來及發展
(1)在喬納森·斯威夫特的著名諷刺**《格列夫遊記》中,小人國內部**成big-endian和little-endian兩派,區別在於一派要求從雞蛋的大頭把雞蛋打破,另一派要求從雞蛋的小頭把雞蛋打破。斯威夫特藉以諷刺英國的政黨之爭,在計算機工業中指資料儲存順序的分歧。
(2)後來計算機通訊發展起來後,遇到乙個問題就是:在串列埠等序列通訊中,一次只能傳送1個位元組。這時候我要傳送乙個int型別的數就遇到乙個問題。int型別有4個位元組,我是按照:byte0 byte1 byte2 byte3這樣的順序傳送,還是按照byte3 byte2 byte1 byte0這樣的順序傳送。規則就是傳送方和接收方必須按照同樣的位元組順序來通訊,否則就會出現錯誤。這就叫通訊系統中的大小端模式。這是大小端這個詞和計算機掛鉤的最早問題。
(3)現在我們講的這個大小端模式,更多是指計算機儲存系統的大小端。在計算機記憶體/硬碟/nnad中。因為儲存系統是32位的,但是資料仍然是按照位元組為單位的。於是乎乙個32位的二進位制在記憶體中儲存時有2種分布方式:
高位元組對應高位址(大端模式)、高位元組對應低位址(小端模式)
(4)現實的情況就是:有些cpu公司用大端(譬如c51微控制器);有些cpu用小端(譬如arm)。(大部分是用小端模式,大端模式的不算多)。於是乎我們寫**時,當不知道當前環境是用大端模式還是小端模式時就需要用**來檢測當前系統的大小端。
2:測試機器大小端模式的測試**
2.1:使用union來測試機器的大小端 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include
union
myunion
;
int
little_or_big(
void
)
int
main(
void
)
else
return
0;
}
分析:首先共用體元素a和b在訪問時候都是從低位址開始訪問的,u1.a = 1在記憶體中的存放有兩種可能(記憶體位址從左到右遞減),小端模式為 00 00 00 01;大端模式為: 01 00 00 00 ,而共用體u1中的b是char類似,所以我們用u1.b去訪問時只能讀取到最低位址的值(按char去解析時只會讀取乙個位元組),所以,如果讀出u1.b的值為1則說明當前機器是小端模式,讀出u1.b的值為0,則說明當前機器是大端模式(這種測試方法要記住,面試時候經常考)
2.2:指標方式來測試大小端 1
2
3
4
5
6
int
little_or_big2(
void
)
分析:首選定義變數a= 1,然後將a的指標強制型別轉換成char *接著去解應用這個指標,並賦值給b,然後根據b的返回值來確定大小端。其實分析可以發現其本質都是一樣的,都是先給乙個記憶體裡面存乙個char 型別的1,然後使得另乙個char 型別的變數b去讀取這個記憶體的值,然後根據讀取的值來判斷大小端。
3:看似可行但實際不行的大小端測試方法
注:測試方法將測試**分別放在kile4.0(大端)和gcc(小端)下面去執行,看執行後的結果。
3.1:位運算
理論分析:
現在將0x1(0001)和0xf(1111)相與假設機器是大端模式,那麼相與之後得到的結果是0001;假設機器是小端模式那麼相與之後得到的結果是1000,
實際測試:
理論可行但實際上不行的,原因是位與運算是編譯器提供的運算,這個運算是高於記憶體層次的(或者說&運算在二進位制層次具有可移植性,也就是說&的時候一定是高位元組&高位元組,低位元組&低位元組,和二進位制儲存無關)
3.2:移位
理論分析:
同上假設的大端模式,那麼儲存的方式是0001,右移1位則把 1 移出去了,所以得到的結果就是0x0;假設是小端模式,那麼儲存方式是1000,右移1位,則結果是0100
實際測試:
實際不行,原因同上因為c語言對運算子的級別是高於二進位制層次的。右移運算永遠是將低位元組移除,而和二進位制儲存時這個低位元組在高位還是低位無關的。
3.3:強制型別轉換
這裡就不再次分析, 實際測試時不行的,原因同上
C語言之大小端詳解
什麼是大小端呢?如果學完c語言你還不知道這個東西那就說明基礎太差了。假設我們有下面這個例子 int main 那麼這個a在記憶體中是怎麼儲存的呢?編譯器給出的結果是 看到這個結果是不是有點懵逼,a這個變數值是1 在記憶體中儲存應該是0x 00 00 00 01才對啊,為什麼編譯器給出的卻是0x 01...
C語言大小端問題
一 概念 大端儲存 乙個數的低位位元組序的內容存放到高位址處,高位位元組序的內容存放在低位址處。小端儲存 乙個數的低位位元組序的內容存放到低位址處,高位位元組序的內容存放在高位址處。舉個例子 include include include intmain printf s n isbigendian...
c語言之大數基本運算
今天我想給大家介紹有關大數運算的方法,大數這裡可以算是乙個難點同樣也是重點,以下的 只針對非負數,大家在看之前可以自己思考一下。考慮到整型變數的範圍有限,所以我們用字元陣列來定義輸入的兩個大數,首先要使它們相應的位對齊,位數少的在前補0,然後各個位數的相加要考慮到進製,這裡我定義為s。下面是全部 i...