【c++】類型轉換——隱式轉換、C風格顯式轉換、static_cast,const_cast,dynamic_cast和reinterpret_cast

更新中,

隱式轉換

在計算表達式時,

C風格強制轉換

強制轉換
強制類型轉換是通過類型轉換運算來實現的。其一般形式爲: (類型說明符) (表達式) 其功能是把表達式的運算結果強制轉換成類型說明符所表示的類型。
中文名 C語言類型強制轉換 外文名 C語言類型強制轉換 形式爲 (表達式) 通 過 類型轉換運算來實現的
目錄
1 基本介紹
2 注意事項
基本介紹編輯
強制類型轉換是通過類型轉換運算來實現的。其一般形式爲:(類型說明符)(表達式)其功能是把表達式的運算結果強制轉換成類型說明符所表示的類型。自動轉換是在源類型和目標類型兼容以及目標類型廣於源類型時發生一個類型到另一類的轉換。例如: (float) a 把a轉換爲浮點型,(int)(x+y) 把x+y的結果轉換爲整型。在使用強制轉換時應注意以下問題:
注意事項編輯
1.類型說明符和表達式都必須加括號(單個變量可以不加括號),如把(int)(x+y)寫成(int)x+y則成了把x轉換成int型之後再與y相加了。
2.無論是強制轉換或是自動轉換,都只是爲了本次運算的需要而對變量的數據長度進行的臨時性轉換,而不改變數據說明時對該變量定義的類型。
例1:
main()
{
float f=5.75;
printf(“f=%d,f=%f\n”,(int)f,f);
}
f=5,f=5.750000
將float f強制轉換成int f float f=5.75;printf("(int)f=%d,f=%f\n",(int)f,f); 本例表明,f雖強制轉爲int型,但只在運算中起作用, 是臨時的,而f本身的類型並不改變。因此,(int)f的值爲 5(刪去了小數)而f的值仍爲5.75。
例2:
比如我們可以(int)‘A’,這樣轉換後的結果爲A的ASCII碼數值,因爲那塊內存本來就存的那個數,只是換個形式使用而已。 知道上面的原則,我們可以對任何數據類型進行轉換,但是轉換的結果可能不是你想像的結果,舉例(int)'9’的結果爲多少?不是9而是57。來個高深點的printf("%d",‘12’);的輸出是什麼?正確答案是12594,因爲printf("%d",‘12’),打印的是存儲12的內存地址上的內容,即ASCII碼值2存儲在低位,1儲在高位地址,0x32就是2的ASCII碼,0x31就是1的ASCII碼,所以是0x3132,轉換成10進制就是12594!
● 字符型變量的值實質上是一個8位的整數值,因此取值範圍一般是-128~127,char型變量也可以加修飾符unsigned,則unsigned char 型變量的取值範圍是0~255(有些機器把char型當做unsighed char型對待, 取值範圍總是0~255)。
● 如果一個運算符兩邊的運算數類型不同,先要將其轉換爲相同的類型,即較低類型轉換爲較高類型,然後再參加運算,轉換規則如下圖所示。
double ←── float 高

long

unsigned

int ←── char,short 低
● 圖中橫向箭頭表示必須的轉換,如兩個float型數參加運算,雖然它們類型相同,但仍要先轉成double型再進行運算,結果亦爲double型。 縱向箭頭表示當運算符兩邊的運算數爲不同類型時的轉換,如一個long 型數據與一個int型數據一起運算,需要先將int型數據轉換爲long型, 然後兩者再進行運算,結果爲long型。所有這些轉換都是由系統自動進行的, 使用時你只需從中瞭解結果的類型即可。這些轉換可以說是自動的,當然,C語言也提供了以顯式的形式強制轉換類型的機制。
● 當較低類型的數據轉換爲較高類型時,一般只是形式上有所改變, 而不影響數據的實質內容, 而較高類型的數據轉換爲較低類型時則可能有些數據丟失。
賦值中的類型轉換
當賦值運算符兩邊的運算對象類型不同時,將要發生類型轉換, 轉換的規則是:把賦值運算符右側表達式的類型轉換爲左側變量的類型。具體的轉換如下:
(1) 浮點型與整型
● 將浮點數(單雙精度)轉換爲整數時,將捨棄浮點數的小數部分, 只保留整數部分。將整型值賦給浮點型變量,數值不變,只將形式改爲浮點形式, 即小數點後帶若干個0。注意:賦值時的類型轉換實際上是強制的。
(2) 單、雙精度浮點型
● 由於C語言中的浮點值總是用雙精度表示的,所以float 型數據只是在尾部加0延長爲double型數據參加運算,然後直接賦值。double型數據轉換爲float型時,通過截尾數來實現,截斷前要進行四捨五入操作。
(3) char型與int型
● int型數值賦給char型變量時,只保留其最低8位,高位部分捨棄。
● char型數值賦給int型變量時, 一些編譯程序不管其值大小都作正數處理,而另一些編譯程序在轉換時,若char型數據值大於127,就作爲負數處理。對於使用者來講,如果原來char型數據取正值,轉換後仍爲正值;如果原來char型值可正可負,則轉換後也仍然保持原值, 只是數據的內部表示形式有所不同。
(4) int型與long型
● long型數據賦給int型變量時,將低16位值送給int型變量,而將高16 位截斷捨棄。(這裏假定int型佔兩個字節)。 將int型數據送給long型變量時,其外部值保持不變,而內部形式有所改變。
(5) 無符號整數
● 將一個unsigned型數據賦給一個佔據同樣長度存儲單元的整型變量時(如:unsigned int→int、unsigned long→long,unsigned short→short) ,原值照賦,內部的存儲方式不變,但外部值卻可能改變。
● 將一個非unsigned整型數據賦給長度相同的unsigned型變量時, 內部存儲形式不變,但外部表示時總是無符號的。
/*例:賦值運算符舉例 */
1
2
3
4
5
6
7
8
9
10
11
main()
{
unsigned a,b;
int i,j;
a=65535;
i=-1;
j=a;
b=i;
printf("(unsigned)%u→(int)%d\n",a,j);
printf("(int)%d→(unsigned)%u\n",i,b);
}
運行結果爲:(unsigned)65535→(int)-1(int)-1→(unsigned)65535
● 計算機中數據用補碼錶示,int型量最高位是符號位,爲1時表示負值,爲0時表示正值。如果一個無符號數的值小於32768則最高位爲0,賦給 int型變量後、得到正值。如果無符號數大於等於32768,則最高位爲1, 賦給整型變量後就得到一個負整數值。反之,當一個負整數賦給unsigned 型變量時,得到的無符號值是一個大於32768的值。
● C語言這種賦值時的類型轉換形式可能會使人感到不精密和不嚴格,因爲不管表達式的值怎樣,系統都自動將其轉爲賦值運算符左部變量的類型。
● 而轉變後數據可能有所不同,在不加註意時就可能帶來錯誤。 這確實是個缺點,也遭到許多人們批評。但不應忘記的是:c語言最初是爲了替代彙編語言而設計的,所以類型變換比較隨意。當然, 用強制類型轉換是一個好習慣,這樣,至少從程序上可以看出想幹什麼。

static_cast

該運算符把expression轉換爲type-id類型,但沒有運行時類型檢查來保證轉換的安全性。它主要有如下幾種用法:
①用於類層次結構中基類(父類)和派生類(子類)之間指針或引用的轉換。
進行上行轉換(把派生類的指針或引用轉換成基類表示)是安全的;
進行下行轉換(把基類指針或引用轉換成派生類表示)時,由於沒有動態類型檢查,所以是不安全的。
②用於基本數據類型之間的轉換,如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。
③把空指針轉換成目標類型的空指針。
④把任何類型的表達式轉換成void類型。
注意: static_cast不能轉換掉expression的const、volatile、或者__unaligned屬性。

const_cast

dynamic_cast

reinterpert_cast

C++中static_cast和reinterpret_cast的區別

C++primer第四版第五章裏寫了編譯器隱式執行任何類型轉換都可由static_cast顯示完成;reinterpret_cast通常爲操作數的位模式提供較低層的重新解釋
1、C++中的static_cast執行非多態的轉換,用於代替C中通常的轉換操作。因此,被做爲顯式類型轉換使用。比如:

int i;
float f = 166.71;
i = static_cast<int>(f);

此時結果,i的值爲166。
2、C++中的reinterpret_cast主要是將數據從一種類型的轉換爲另一種類型。所謂“通常爲操作數的位模式提供較低層的重新解釋”也就是說將數據以二進制存在形式的重新解釋。比如:

int i;
char *p = "Thisisanexample.";
i = reinterpret_cast<int>(p);

此時結果,i與p的值是完全相同的。reinterpret_cast的作用是說將指針p的值以二進制(位模式)的方式被解釋爲整型,並賦給i,//i 爲整型;一個明顯的現象是在轉換前後沒有數位損失。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章