C 型別轉換(2)

2021-07-11 00:14:30 字數 2432 閱讀 8249

型別轉換的本質

從本質上說,c++/c不會直接對兩個型別不同的運算元進行運算,如果運算元不同,編譯器就會試圖運用隱式型別轉換規則或者按照使用者要求進行強制型別轉換,型別轉換並不是改變原來變數的型別和值,而是生成了新的臨時變元,其型別為目標型別。

隱式型別轉換

所謂的隱式型別轉換,就是編譯器在背後幫程式設計師做的型別轉換工作,隱式型別轉換的安全隱患是由編譯器的責任。這裡的安全性主要包括兩個方面:記憶體單元訪問的安全性和轉換結果的安全性,主要表現為記憶體訪問範圍的擴充套件、記憶體的截斷、尾數的截斷、值得改變和溢位等。

基本資料型別的隱式轉換

基本資料型別轉換關係:char->int->long->float->double,乙個低階資料型別物件總是優先轉換為能夠容得下它的最大值的、占用記憶體最少的高階型別物件。

示例2-1的轉換是安全的,並不需要強制。編譯器首先隱式的將100提公升為double的乙個臨時變數,然後將這個臨時變數賦值給d1;同樣,i也會隱式的提公升為double(其值作為它的整數部分)的乙個臨時變數,然後再賦值給d2。當編譯器認為這些臨時變數不在需要時就銷毀它們。

示例2-1

double d1 = 100;

int i = 100;

double d2 = i;

複雜資料型別的隱式轉換由於派生類和基類之間的is-a關係,可以直接將派生類物件轉換為基本物件,這雖然會發生記憶體截斷,但是無論從記憶體訪問還是從轉換結果來說都是安全的。這是因為c++的乙個保證,派生類物件必須保證其基類子物件的完整性,即其中的基本子物件的記憶體映像必須和真正的基類物件的記憶體映像一致。

示例2-2

// 基類

class base

;// 派生類

class derived : public base

;// (1)派生類物件賦值給基類物件,發生記憶體截斷

derived d1;

base b = d1;

// (2)派生類物件指標賦值給基類指標,派生類指標和基類指標指向的起始位址一致

強制型別轉換強制型別轉換規則:(目標資料型別)源資料型別;

double d1 = 1.25e+20;

double d2 = 10.25;

int i1 = (int)d1;

int i2 = (int)d2;

按照從浮點型到整型數的轉換語義,結果應該是截去小數部分保留整數部分,因此i1 = 10;i1會發生溢位。這就造成了安全隱患。

從記憶體訪問角度來說,pint訪問指向的double變數d5是安全的(後面的4位元組被「截斷了」,可訪問記憶體範圍縮小),但是其值絕對不會是d5的整數部分。通過pd訪問int型別變數i4,得到的資料不一定是100,而且造成了可訪問記憶體的」擴充套件「如果向裡面寫資料會造成執行時錯誤。

基類和派生類之間指標強制轉換的安全性

存在問題:通過pd2訪問的記憶體訪問」擴張」了4位元組,如果訪問m_c將可能引發執行時錯誤,因為pd2指向了m_c的記憶體空間。

總結:

(1)不可以把基類物件直接賦值給派生類物件,無論是直接賦值還是強制轉換,因為這是不自然的。

(2)對於基本型別的強制轉換一定要區分值截斷和記憶體截斷。

(3)如果堅持要使用強制型別轉換,必須同時確保記憶體訪問的安全性和轉換結果的安全性。

mysql型別轉換c 型別轉換 C 型別轉換

一 簡介 型別轉換 把資料從一種型別轉換另一種型別 我們要求等號兩邊參與運算子必須型別一致,如果不一致,滿足下列條件會發生自動型別轉換或者隱式型別轉換。1.兩種型別相容 例如 int和double 相容 都是數字型別 2.目標型別大於源型別 double int 顯示型別轉換 1.兩種型別相相容 i...

C 筆記(2) 資料型別轉換

1 將一種型別的值賦值給另一種型別的變數,則自動轉化為接收型別的變數。2 表示式中包含不同型別時,對值進行轉換。在計算表示式時,c 將bool char unsigned char signed char和short值轉化為int,true轉化為1,false轉化為0,這些稱為整形提公升 integ...

C 入門2 型別轉換

型別轉換 c 有11種整型和3種浮點型別,當對不同的型別進行計算時,c 會自動執行型別的轉換。自動型別轉換 執 況 將一種算數型別賦給另一種算數型別時 表示式中包含不同的型別時 將引數傳遞給函式時 強制型別轉換 1 賦值時進行的轉換 值將被轉換成接受變數的型別。此時將乙個值賦給範圍更大的型別通常不會...