隱式轉換和顯式轉換
C/C++對於數據類型的轉換包括隱式轉換和顯式轉換(強制類型轉換)。
一般來說,隱式轉換包括以下幾種情形:
1. 低精度與高精度混合運算,低精度會隱式轉換成高精度類型。
int a = 10; double b = 1.2; double c = a + b;//此時a會隱式轉換成double類型進行運算。
bool、char、short、int、long、float、double依次向上會發生隱式轉換。bool類型向上轉換時,false轉換成0,true轉換成1。
【p.s.】有符號和無符號數之間的轉換。當signed類型能夠容納類型轉換前的數時,該類型向上轉換時轉換為signed類型,否則都轉換成unsigned類型。
有符號數和無符號數之間的轉換會發生符號反轉或數據截斷。
符號反轉是只無符號數與有符號數之間運算,會導致符號發生變化;
數據截斷則是指高精度數據用低精度類型保存數據時,發生的高位/低位數據被舍棄的現象。
int a = 300; char b = a;//發生數據截斷 b的ascii碼是44,實際對應的是, int c = b;//char隱式轉換成int 44 unsigned short d = 10; unsigned short e = 65535; short f = d + e;//65545,被截斷f=9 short aa = 10; short bb = 32767; short cc = aa + bb;//cc=-32759
2. 非布爾類型會轉換成布爾類型。
int a = 10; if (a)//這裏會將非0值認為是true { cout << "i am true." << endl; } else { cout << "i am false." << endl; }
3. 指針類型轉換。
數組名會轉換成指針。當數組作為函數形參時,本身是蛻化成指針的。
可以將NULL(0)賦值給指針類型。
4. 枚舉類型。
枚舉類型的取值可以與整形進行轉換。
C風格的強制轉換,在類型前加上(c_type)。如,將double類型強制轉換成int:
double pi = 3.1415926; int p = (int) pi;// p = 3
C++風格的強制轉換
static_cast<type>、const_cast<type>、dynamic_cast<type>、reinterpret_cast<cast>
通常編譯器支持的自動轉換,都可以在前面加上static_cast。高精度數據轉換成低精度數據時,編譯器通常會給出精度損失的告警,
使用static_cast強制轉換時,編譯器就會忽略這個告警。常用如下:
void *p; double *q = static_cast<double*> (p);//支持指針的強制轉換 double Pi= 3.1415926; int pi = static_cast<int> (Pi);//此處不會有warning
const_cast能夠將變量的const屬性去除。如一個函數的入參是 char*類型,當傳入一個const char*時,編譯會報錯。這時可以使用const_cast去除它的const屬性。
#include <iostream> using namespace std; void print(char* s) { cout << s << endl; } int main() { const char* s = "abc"; print(const_cast<char*> (s));//去除s的const屬性 return 0; }
dynamic_cast支持運行時識別指針或引用類型所指向的對象。
dynamic_cast使用時先去判斷轉換是否有效,有效才進行轉換。
轉換對象是指針時,若轉換失敗,則轉換的結果是NULL指針;若轉換對象是引用,若轉換失敗,則拋出一個bad_cast的異常。
reinterpret_cast通常是在位操作層次上進行的強制轉換。轉換後一定要記住原始類型,保證後續操作兼容原始類型,否則可能會造成一些奇怪的輸出結果。
int *ip; char *pc = reinterpret_cast<char*> (ip); //Coder一定要記住pc所指向的對象實際是int類型的。 string s(pc);//這裏s裏面的內容很奇怪。
隱式轉換和顯式轉換