1.先從一個問題說開去
C++數據類型轉換的問題
- #include <iostream.h>
- void main()
- {
- int i=0xb62;
- char c;
- c=i;
- cout<<c<<endl;
- }
這裏爲什麼輸出的是b?
2.先檢測一下我們所使用的電腦的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類型的數值,這種強制類型轉換操作並不改變操作數本身,運算後操作數本身未改變,例如:
- int nVar=0xab65;
- char cChar=char (nVar);
4.2.隱式強制類型轉換
隱式類型轉換髮生在賦值表達式和有返回值的函數調用表達式中。在賦值表達式中,如果賦值符左右兩側的操作數類型不同,則將賦值符右邊操作數強制轉換爲賦值符左側的類型數值後,賦值給賦值符左側的變量。在函數調用時,如果return後面表達式的類型與函數返回值類型不同,則在返回值時將return後面表達式的數值強制轉換爲函數返回值類型後,再將值返回,如:
- int nVar;
- double dVar=3.88;
- nVar=dVar;//執行本句後,nVar的值爲3,而dVar的值仍是3.88
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 * 高位
********** |