官术网_书友最值得收藏!

2.6 類型轉換

類型轉換就是將一種數據類型轉換為另一種數據類型。在同一個算術表達式中,若出現了兩種以上的不同數據類型,就會先進行數據類型轉換,再計算表達式的值。例如:

cout<<34+21.45+'a'<<endl;

在此語句的算術表達式中,出現了3種數據類型:34是int類型,21.45是double類型,'a'是char類型。運算的過程如下:首先將34轉換成double類型的34.00,再完成34.00+21.45的運算,得到double類型的結果55.45,然后將char型的'a'轉換成double類型的97.00,再計算55.45+97.00,最后的結果是double類型的152.45。

類型轉換可分為隱式轉換和顯式轉換。在C++中,類型轉換經常發生在算術表達式計算、函數的參數傳遞、函數返回值及賦值語句中。

2.6.1 隱式類型轉換

C++定義了一套標準數據類型轉換的規則,如圖2-2所示。在必要時,C++會用這套轉換規則在程序員不參與的情況下自動進行數據類型的轉換,稱為隱式類型轉換。

圖2-2 C++隱式類型轉換方法

在以下4種典型情況下,都會發生隱式類型轉換。

① 在出現了多種數據類型的算術表達式中。轉換的總原則是窄數據類型(占用存儲空間少的類型)向寬數據類型轉換(占用存儲空間多的類型),具體情況如圖2-2所示。

前面介紹的“34+21.45+'a'”計算過程中的類型轉換就屬于這種情況。

② 將一種類型的數據賦值給另一種類型的變量,會發生隱式類型轉換,把賦值句右邊的表達式結果轉換成賦值句左邊變量的類型。例如:

int a=2;
float b=3.4;
double c=2.2;
b=a;       //將a的值2轉換成float型的2.0再賦給b
a=c;       //將c的值2.2轉換成int型的2賦給a

由于寬類型數據所占的存儲空間比窄類型多,因此窄類型向寬類型轉換不會有什么問題,而寬類型數據轉換成窄類型則常會發生精度損失,是不安全的。C++常采用截取方法進行寬類型向窄類型的轉換,即從寬類型中截取與窄類型大小相同的存儲區域作為轉換的結果,而寬類型中多出的字節就丟掉了。例如“a=c”,C++將截取c的整數部分并賦值給a,至于c的小數部分就丟掉了,所以a的最終結果是2。

③ 在函數調用中,若實參表達式與形式參數的類型不相符,則把實參的類型轉換成形參的類型;在函數返回時,若函數返回表達式的值與函數聲明中的返回類型不同,則把表達式結果轉換成函數返回類型。

float min(int a,int b) {
    return a<b?a:b;
}

return語句中的表達式結果為int,與min()函數返回類型float不同,因此會發生類型轉換,將“a<b?a:b”的結果轉換float類型后再返回給min()函數。

假設對上面的函數min(),存在如下函數調用:

int a=2;
float b=3.4;
int x=min(b,a+3.5);

由于min()的形式參數是int,所以在“min(b,a+3.5)”調用中,將把b的值3.4從float類型轉換成int類型的3,“a+3.5”的結果5.5也被轉換成int類型的5,再傳送給相應的形式參數。

2.6.2 顯式類型轉換

把一種數據類型強制轉換為另一種類型就稱為顯式轉換,也稱為強制轉換。形式如下:

(type) exp

或者

type (exp)

其中,type是目標類型,exp是要進行類型轉換的表達式,強制轉換把exp轉換成type型。第一種是C語言支持的類型轉換方式,它在C++語言中同樣可用;第二種是只有C++語言才允許使用的類型轉換方式,在C程序中不可用。例如:

int a=4;
float c=(float)a;  //C語言中使用的類型轉換方式,在C++中仍可用,結果為4.0
a=int(8.8);    //只能用于C++語言而不能用于C語言的類型轉換方式,結果為8

在C++標準中,還有4個強制類型轉換運算符:static_cast,dynamic_cast,const_cast和reinterpret_cast。其用法如下:

x_cast <type> (exp)

其中,x_cast代表強制類型,可以是static_cast、dynamic_cast、const_cast或reinterpret_cast之一,type是強制轉換后的類型,exp是要轉換類型的表達式。

static_cast是靜態強制轉換,能夠實現任何標準類型之間的轉換,如從整型到枚舉類型,從浮點型到整型之間的轉換等。事實上,凡是隱式轉換能夠實現的類型轉換,static_cast都能夠實現。例如:

char p='d';
int x=static_cast<int > (p);      //將p轉換成int,x=100
double y=static_cast <double> (54); //將54從int型轉換成double型

const_cast是常量強制轉換,用于強制轉換const或volatile(可變)的數據,它轉換前后的數據類型必須相同,主要用來在運算時暫時刪除數據的const限制。

例2-8】 利用const_cast轉換去掉引用的const限制。

//Eg2-8.cpp
#include<iostream.h>
void sqr(const &x) {
    const_cast<int &>(x)=x*x;  //L1 去掉了x的const限制,否則不能修改x
    //x=x*x;     //L2 錯誤,x為const,不能被修改
}
void main(){
    int a=5;
    const int b=5;
    sqr(a);       //L3 通過引用將a改為25
    cout<<a<<endl;    //L4 輸出25
    sqr(b);   //L5 由于b為const,sqr對其修改無效
    cout<<b<<endl;  //L6 輸出5
}

函數sqr()的參數x是常量引用,不能通過它修改實參的值,但是語句“const_cast<int &>(x);”在執行時暫時去掉了x的const限制,將其結果改為x*x,本語句執行后,x即恢復為const,因此語句L2是錯誤的。語句L5通過sqr()的形參x修改了實參b單元中的值為25,但b是const,在函數結束時,此修改即無效,b恢復原來的const值5。

reinterpret_cast是重解釋強制轉換,能夠完成互不相關的數據類型之間的轉換,如將整型轉換成指針,或把一個指針轉換成與之不相關的另一種類型的指針。

int i;
char *c="try fly";
i=reinterpret_cast<int >(c);

reinterpret_cast 其實是按強制轉換所指定的類型對要轉換數據對應的內存區域進行重新定義。在本例中,reinterpret_cast將c對應的內存區域(一個內存地址,因為c是指針)重新定義為一個整數,這種轉換在這里并沒有多大的意義。

dynamic_cast是動態強制轉換,主要用于基類和派生類對象之間的指針轉換,以實現多態。與其他幾個強制類型轉換運算符不同的是,dynamic_cast所完成的類型轉換是在程序運行時刻實現的,而其他類型的強制轉換在編譯時就完成了。

主站蜘蛛池模板: 化州市| 临江市| 台中市| 邮箱| 孟州市| 宿松县| 枣强县| 霍邱县| 罗甸县| 沈阳市| 修武县| 古蔺县| 绍兴县| 重庆市| 孝感市| 英吉沙县| 宁津县| 宜州市| 孝感市| 福清市| 罗源县| 昌图县| 大安市| 北安市| 阳山县| 梓潼县| 安化县| 古丈县| 东阿县| 达孜县| 留坝县| 吴川市| 祁门县| 介休市| 北碚区| 黄浦区| 剑河县| 青州市| 广南县| 永兴县| 宁蒗|