小議大小端模式對C語言的共用體結構的影響

2021-06-02 16:57:34 字數 3095 閱讀 1544

c++資料型別轉換的問題

view plain

#include 

void main()    

這裡為什麼輸出的是b?

版本一(有問題,結果無論如何都是34,不能說明34是高位址的還是低位址的)

版本二(根據

shineyan1991shineyan1991的建議)

從上圖可知,cpu的位元組序是小端模式。

知識點

小端模式(little-endian) 

資料型別中的高位資料存放於高位址部分,低位資料存放於低位址部分。簡而言之:高位在後,低位在前。

大端模式(big-endian) 

資料型別中的高位資料存放於低位址部分,低位資料存放於高位址部分。簡而言之:高位在前,低位在後。

0xb62是十六進製制,因為char是乙個位元組的,所以我們只取低8位(丟棄了高位元組,而保留了低位元組),這是和語言有關,和cpu的架構無關,乙個十六進製制位轉換為4個二進位制位,所以,低8位就是62轉換的,就是01100010,傳遞給char後,char的值就是98,根據ascii,就會輸出b。

強制型別轉換是通過型別轉換運算來實現的。其一般形式為:(型別說明符)(表示式)其功能是把表示式的運算結果強制轉換成型別說明符所表示的型別。自動轉換是在源型別和目標型別相容以及目標型別廣於源型別時發生乙個型別到另一類的轉換。

當運算元的型別不同,而且不屬於基本資料型別時,經常需要強制型別轉換,將運算元轉化為所需要的型別。強制型別轉換具有兩種形式,稱為顯式強制轉換和隱式強制型別轉換。

4.1.顯式強制型別轉換

顯式強制型別轉換需要使用強制型別轉換運算子,格式如下:

type()

或(type)

其中,type為型別描述符,如int,float等。為表示式。經強制型別轉換運算子運算後,返回乙個具有type型別的數值,這種強制型別轉換操作並不改變運算元本身,運算後運算元本身未改變,例如:

view plain

int nvar=0xab65;  

char cchar=char (nvar);  

上述強制型別轉換的結果是將整型值0xab65的高階兩個位元組刪掉,將低端兩個位元組的內容作為char型數值賦值給變數cchar,而經過型別轉換後nvar的值並未改變。

4.2.隱式強制型別轉換

隱式型別轉換發生在賦值表示式和有返回值的函式呼叫表示式中。在賦值表示式中,如果賦值符左右兩側的運算元型別不同,則將賦值符右邊運算元強制轉換為賦值符左側的型別數值後,賦值給賦值符左側的變數。在函式呼叫時,如果return後面表示式的型別與函式返回值型別不同,則在返回值時將return後面表示式的數值強制轉換為函式返回值型別後,再將值返回,如:

view plain

int nvar;  

double dvar=3.88;  

nvar=dvar;//執行本句後,nvar的值為3,而dvar的值仍是3.88   

4.3.在使用強制轉換時應注意以下問題:

1.型別說明符和表示式都必須加括號(單個變數可以不加括號),如把(int)(x+y)寫成(int)x+y則成了把x轉換成int型之後再與y相加了。

2.無論是強制轉換或是自動轉換,都只是為了本次運算的需要而對變數的資料長度進行的臨時性轉換,而不改變資料說明時對該變數定義的型別。

3.如果乙個運算子兩邊的運算數型別不同,先要將其轉換為相同的型別,即較低型別轉換為較高型別,然後再參加運算,轉換規則如下圖所示。

double ←── float 高 ↑

long ↑

unsigned ↑

int ←── char,short 低

圖中橫向箭頭表示必須的轉換,如兩個float型數參加運算,雖然它們型別相同,但仍要先轉成double型再進行運算,結果亦為double型。 縱向箭頭表示當運算子兩邊的運算數為不同型別時的轉換,如乙個long 型資料與乙個int型資料一起運算,需要先將int型資料轉換為long型, 然後兩者再進行運算,結果為long型。所有這些轉換都是由系統自動進行的, 使用時你只需從中了解結果的型別即可。這些轉換可以說是自動的,但然,c語言也提供了以顯式的形式強制轉換型別的機制。

4.當較低型別的資料轉換為較高型別時,一般只是形式上有所改變, 而不影響資料的實質內容, 而較高型別的資料轉換為較低型別時則可能有些資料丟失。

5.當賦值運算子兩邊的運算物件型別不同時,將要發生型別轉換, 轉換的規則是:把賦值運算子右側表示式的型別轉換為左側變數的型別。 c語言賦值時的型別轉換形式可能會使人感到不精密和不嚴格,因為不管表示式的值怎樣,系統都自動將其轉為賦值運算子左部變數的型別。而轉變後資料可能有所不同,在不加注意時就可能帶來錯誤。 這確實是個缺點,也遭到許多人們批評。但不應忘記的是:c面言最初是為了替代組合語言而設計的,所以型別變換比較隨意。當然, 用強制型別轉換是乙個好習慣,這樣,至少從程式上可以看出想幹什麼。

當我們把乙個int型強制轉化為byte時,由於byte只有1個位元組,而int型是4個位元組,這樣就會產生截斷,int把它最低的記憶體空間裡的值放到了byte所對應的記憶體空間裡。如圖所示:

char                           int

**********                  **********

* 1 byte *

**********                  ********** |

* 1 byte *   高位

********** |

記憶體位址是由上到下有從左至右依次遞增的,小端位元組序指低位元組位資料存放在記憶體低位址處, 高位元組位資料存放在記憶體高位址處; 大端位元組序是高位元組資料存放在低位址處,低位元組資料存放在高位址處。x86的cpu體系結構中,就是使用小端位元組序,即低位元組資料存放在低位址處,高位元組資料存放在高位址處。將int型的資料轉化成char型的資料時,我們只取低8位;如果我們的cpu是小端模式,則我們在進行強制型別轉換時不需要調整位元組內容,非常的方便;如果我們的cpu是大端模式,則我們,需要將高位元組位址的資料存入低位元組位址,也就是需要調整位元組內容。

小端模式 :強制轉換資料不需要調整位元組內容,因為1、2、4位元組的儲存方式的位元組的位置是一樣。

C語言共用體 大小端 列舉

1.共用體和結構體的相同和不同 1 相同點就是操作語法幾乎相同。2 不同點是本質上的不同。struct是多個獨立元素 記憶體空間 打包在一起 union是乙個元素 記憶體空間 的多種不同解析方式。include 對同一位址資料的不同解析方法 union myunion struct mystruct...

C語言知識點(一) 共用體和大小端模式

當乙個共用體被宣告時,編譯程式自動地產生乙個變數,其長度為聯合中型別位元組數最多的變數的型別長度的整數倍。以上例而言,最大長度是double資料型別,所以foo的記憶體空間就是double型的長度。12 345union foo 在這個union中,foo的記憶體空間的長度為12,是int型的3倍,...

c語言學習筆記 共用體,大小端,和列舉

共用體 共用體是c中的一種資料結構,他的定義方法和使用方法與結構體相同,只需要在定義型別時將struct換為union即可 與結構體不同的是,聯合體中的記憶體空間是所有成員共用的,公用體的大小取決於共用體中最大的成員大小,共有體沒有對齊機制,即使當聯合體最大成員大小不足4位元組的倍數,編譯器也不會自...