如:
int val;
val = 3.14 + 3; //val = 6
上面稱為 隱式類型轉換。
1、發(fā)生隱式轉換
-
混合表達式中,操作數(shù)被轉化為相同類型
int iv; double dv; iv += dv; //iv會被轉換為double -
作為條件表達式轉換為bool
int val; if(val) //int to bool while(cin) //cin to bool -
用表達式初始化某變量,該表達式結果被轉換為該變量的類型
int iv = 3.14; //3.14 to int
2、算術轉換
signed 與 unsigned 類型間的轉換
如果包含 short 和 int 類型的表達式,short 轉換為int。如果 int 足夠表示所有 unsigned short ,則將 unsigned short 轉換為 int。
long 和 unsigned int 轉換也一樣,如果 long 足夠表示所有 unsigned int ,則將 unsigned int 轉換為 long。
在32機器中,long和int通常使用一個字長表示,因此包含 unsigned int 和 long 類型的表達式,都應該轉換為 unsigned long
- signed 和 unsigned int,signed轉換成 unsigned int。
舉例
bool bv;
char cv;
short siv;
unsigned short usiv;
int iv;
unsigned int uiv;
long lv;
unsigned long ulv;
float fv;
double dv;
3.14L + 'a'; //'a' 先轉換成 int,再轉換成double
dv + iv; //iv to double
dv + fv; //fv to double
iv = dv; //dv to(截斷) int
bv = dv; //if dv=0, bv = false, else bv = true
cv + fv; //cv to int, then, int to float
siv + cv; //siv and cv to int
cv + lv; //cv to long
iv + ulv; //iv to unsigned long
usiv + iv; //依賴于 unsigned short 和 int 的大小
uiv + lv; //依賴于 unsigned int 和 long 的大小
3、其他隱式轉換
指針轉換
使用數(shù)組時,大多數(shù)情況下數(shù)組都會自動轉化為指向第一個元素的指針
int ia[10]; //數(shù)組
int *ip = ia; //轉化成指向第一個元素的指針
還有另外兩種指針轉換:
- 指向任意數(shù)據(jù)類型的指針都能夠轉化成 void*類型;
- 整型字面常量值 0 可以轉換為任意指針類型;
轉換為bool類型
算術值和指針紙都可以轉為bool類型。如果指針或算術值為0,則其bool值為false,其他則為true:
if (cp) /*...*/ //true if not zero
while(*cp) /*...*/ //convert char to bool
while 語句對 cp 解引用,如果結果為 null ,則轉化成false,否則轉化成true
算術類型與bool類型的轉換
可將算術類型轉換成bool型,也可將bool型轉換成int型。算術類型轉bool時,0轉換成false,其他轉換成true;bool轉int時,true轉成1,false轉成0。
bool b = true;
int ival = b; //ival == 1
double pi = 3.14;
bool b2 = pi; //b2 is true
pi = false; //pi == 0
轉化與枚舉
//p3 = 3; p4 = 4
enum points {p1 = 2, p3, p3 = 3, p4};
轉化為const類型
使用非const對象初始化const對象的引用時,系統(tǒng)將非const對象轉化成const對象。
int i;
const int ci = 0;
const int &j = i; //ok: 將非const對象轉化成const對象
const int *p = &ci; //ok: 將非const對象的地址轉化為指向const類型的指針
由標準庫類型定義的轉換
典型的例子就是
string s;
while(cin >> s)
該表達式 cin>>s 的結果 cin 對象,為istream對象,所以此時會將其轉化成bool類型。
4、顯式轉換
顯式轉換也稱為強制類型轉換(cast),有以下操作符:static_cast, dynamic_cast, const_cast, reinterpret_cast。
何時需要強制轉換
例如
double dval;
int ival;
ival *= dval;
上述程序首先會將 ival 轉換為 double 型,乘法操作后又將double型的結果轉成int型。為了避免不必要的轉換,可以如下操作
ival *= static_cast<int>(dval);
命名的強制類型轉換
形式如下
cast-name<type>(expression);
cast-name的選擇有
- static_cast: 編譯器隱式執(zhí)行的任何類型轉換都可以通過 static_cast 顯式完成
double d = 1.5;
char ch = static_cast<char>(d);
void *p = &d;
double *dp = static_cast<double*>(p); //可以找回存在void*中的值
- dynamic_cast: 支持運行時識別指針或引用所指的對象。
- const_cast: 去掉表達式的const性質
const char *ccp;
char *cp = string_copy(const_cast<char*>(ccp));
//使string_copy接受const char*類型的參數(shù)
- reinterpret_cast: 通常為操作數(shù)的位模式提供較低層次的重新解釋
int *ip;
char *cp = reinterpret_cast<char*>(ip);
cp 所指的真實對象時 int 類型,所以不能用來初始化 string 對象。
type表示目標類型,expression表示被轉換的表達式。
避免使用強制類型轉換
舊式的強制轉換
char *cp = (char*) ip;
這種方式不容易錯誤跟蹤,可視性差。
C++仍舊支持舊式強制轉換,但不推薦這樣做。除非在C語言下,或舊式編譯器上才使用。
END.