1. 程式人生 > >隱式轉換和顯式轉換

隱式轉換和顯式轉換

string 運算 依次 col 指向 pri ast 現象 style

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裏面的內容很奇怪。

隱式轉換和顯式轉換