小端模式與強制數據類型轉換

 

1.先從一個問題說開去

C++數據類型轉換的問題

  1. #include <iostream.h>  
  2. void main()  
  3. {  
  4.     int i=0xb62;  
  5.     char c;  
  6.     c=i;  
  7.     cout<<c<<endl;  
  8. }  

這裏爲什麼輸出的是b?

2.先檢測一下我們所使用的電腦的CPU的字節序

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

版本二(根據 shineyan1991的留言修改後得到的,在此謝謝 shineyan1991的建議)


從上圖可知,CPU的字節序是小端模式。

知識點
小端模式(Little-Endian) 
       數據類型中的高位數據存放於高地址部分,低位數據存放於低地址部分。簡而言之:高位在後,低位在前。
大端模式(Big-Endian) 
       數據類型中的高位數據存放於低地址部分,低位數據存放於高地址部分。簡而言之:高位在前,低位在後。

3.初步分析

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

4.強制數據類型轉化

      強制類型轉換是通過類型轉換運算來實現的。其一般形式爲:(類型說明符)(表達式)其功能是把表達式的運算結果強制轉換成類型說明符所表示的類型。自動轉換是在源類型和目標類型兼容以及目標類型廣於源類型時發生一個類型到另一類的轉換。
        當操作數的類型不同,而且不屬於基本數據類型時,經常需要強制類型轉換,將操作數轉化爲所需要的類型。強制類型轉換具有兩種形式,稱爲顯式強制轉換和隱式強制類型轉換。

4.1.顯式強制類型轉換

         顯式強制類型轉換需要使用強制類型轉換運算符,格式如下:
  type(<expression>)
  或
(type)<expression>
其中,type爲類型描述符,如int,float等。<expression>爲表達式。經強制類型轉換運算符運算後,返回一個具有type類型的數值,這種強制類型轉換操作並不改變操作數本身,運算後操作數本身未改變,例如:
  1. int nVar=0xab65;  
  2. char cChar=char (nVar);  
上述強制類型轉換的結果是將整型值0xab65的高端兩個字節刪掉,將低端兩個字節的內容作爲char型數值賦值給變量cChar,而經過類型轉換後nVar的值並未改變。
4.2.隱式強制類型轉換
        隱式類型轉換髮生在賦值表達式和有返回值的函數調用表達式中。在賦值表達式中,如果賦值符左右兩側的操作數類型不同,則將賦值符右邊操作數強制轉換爲賦值符左側的類型數值後,賦值給賦值符左側的變量。在函數調用時,如果return後面表達式的類型與函數返回值類型不同,則在返回值時將return後面表達式的數值強制轉換爲函數返回值類型後,再將值返回,如:
  1. int nVar;  
  2. double dVar=3.88;  
  3. 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面言最初是爲了替代彙編語言而設計的,所以類型變換比較隨意。當然, 用強制類型轉換是一個好習慣,這樣,至少從程序上可以看出想幹什麼。

5.int ----->char類型轉化時的內存操作

        當我們把一個int型強制轉化爲byte時,由於byte只有1個字節,而int型是4個字節,這樣就會產生截斷,int把它最低的內存空間裏的值放到了byte所對應的內存空間裏。如圖所示:
   char                           int
**********                  **********
* 1 Byte * <-----------* 1 Byte * 低位
**********                  ********** |
                                 * 1 Byte *   高位
                                 ********** |


6.深入分析開始的問題

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

7.總結

小端模式 :強制轉換數據不需要調整字節內容,因爲1、2、4字節的存儲方式的字節的位置是一樣。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章