天天看點

《C++程式設計教程(第3版)》——第2章,第5節類型轉換

本節書摘來自華章出版社《c++程式設計教程(第3版)》一書中的第2章,第2.5節類型轉換,作者張志航,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視

2.5 類型轉換

2.5.1 指派時的自動類型轉換

如果指派運算符兩側的類型不一緻,則遵循以下幾條原則進行類型轉換後指派。

1.實型量賦給整型變量

實型量賦給整型變量時,簡單舍棄小數部分,将實型量的整數部分賦給整型變量,不進行四舍五入。如“int i=3.96;”,則i被指派為3。

2.整型量賦給實型變量

整型量賦給實型變量時,數值不變,有效數字位數增加。例如,若有“float f=23;”,則f獲得的值為23.0,以單精度浮點格式存儲,具有6~7位有效數字;若有“double d=23;”,則d獲得的值為23.0,以雙精度浮點格式存儲,具有15~16位有效數字。

3.整型量之間互相指派

整型量有8種,它們分别是[signed] char、unsigned char、[signed] short、unsigned short、[signed] int、unsigned int、[signed] long、unsigned long。此處将char型量看作1位元組長度的整型量。各種類型的整型量占用的位元組數是不同的,按照其二進制位數的多少,區分為“長的”整型量和“短的”整型量。所謂“長的”整型量是指該整型量的二進制位數較多,所謂“短的”整型量是指該整型量的二進制位數較少。整型量之間互相指派,系統處理為它們記憶體資料之間的指派,分兩種情況。

(1)“長的”整型量賦給“短的”整型量

将“長的”整型量賦給“短的”整型量時,方法是“低位截斷”,将“長的”整型量的高位去掉,截取其與“短的”整型量相同位數的低位二進制位,然後進行指派。例如,“char c=250;”将int型常量250賦給字元型變量c。250為int整型常量,在記憶體中的存儲形式是32位二進制數 0000 0000 0000 0000 0000 0000 1111 1010。變量c是8位有符号二進制整型量,指派原則是取250記憶體資料的低8位賦給c,此時c中的值是1111 1010。c++中整型量是以補碼形式存放的,是以,變量c的真值是-6。

又如,“short int a=65 536;”将常量65 536指派給變量a。常量65 536是int型量(其值是216),在記憶體中的存儲形式是:0000 0000 0000 0001 0000 0000 0000 0000。短整型變量a在記憶體占16個二進制位,指派時截取65 536記憶體中的低16位賦給a,此時a的16個二進制位全為0,則a的值是0,這稱為指派溢出。因為65 536超過了短整型量的數值範圍(-32 768~32 767),無法直接指派給短整型量。

(2)“短的”整型量賦給“長的”整型量

“短的”整型量賦給“長的”整型量又分成兩種情況。

1)将“短的”無符号整型量賦給“長的”整型變量,方法是在“短”的無符号整型量前補0,使其長度達到“長的”整型量的位數。例如:

unsigned char c = -4;

int i;

i = c;

此例中涉及兩次指派,指派過程中各常量、變量的記憶體形式如下。首先将“長的”整型量-4賦給“短的”整型變量c,c擷取的值是-4的記憶體表示形式的低8位;再将“短的”c變量的值賦給“長的”整型變量i。因為c是無符号整型量,占8位,而i是32位,此時在c的記憶體内容前補0使其擴充到32位後,指派給變量i。

-4:1111 1111 1111 1111 1111 1111 1111 1100

c: 1111 1100

i:0000 0000 0000 0000 0000 0000 1111 1100

結果:變量i的值是252。

2)将“短的”有符号整型量賦給“長的”整型量。此種情況隻需做符号位擴充,即在“短的”整型量前補符号位,使其長度達到“長的”整型量的長度,然後指派。例如:

char c = -4;

int i = c;

指派過程中各常量、變量的記憶體表示形式如下:

i:1111 1111 1111 1111 1111 1111 1111 1100(擴充負号)

結果:變量i的值是-4。又如:

char c = 4;

4:0000 0000 0000 0000 0000 0000 0000 0100

c: 0000 0100

i:0000 0000 0000 0000 0000 0000 0000 0100(擴充正号)

結果:變量i的值是4。

2.5.2 各種類型運算量混合運算時的自動類型轉換

c++語言中各種類型的常量和變量之間可以混合運算。例如,已知“int a=1; double b=2;”,則可進行a+b運算。兩個不同類型的量運算時,計算機内部首先将它們轉換成相同資料類型的量,然後進行運算。例如,上述a+b運算,計算機首先将a的值轉換為double型表示,然後與double型的b的值相加。這種轉換是c++内部自動完成的,程式設計者必須掌握轉換規則,否則程式設計會出問題。轉換規則如圖2-4所示。圖2-4中橫向向左的箭頭表示必定轉換。例如,已知“char c1, c2;”,在做c1+c2運算時,首先将c1和c2的值均轉換成int型表示,再将兩個int型量相加。圖2-4中縱向箭頭表示不同資料類型混合運算時的轉換方向,規則是由低類型向高類型轉換,例如,上述a+b運算将低類型int值轉換成高類型double值,然後運算。所謂低類型是指占用存儲位元組少、資料範圍小的類型,所謂高類型是指占用存儲位元組多、資料範圍大的類型。

例如,已知“int i; float f; double d;”,則表達式10+'a'+i * f - d / i的運算順序和類型轉換過程如圖2-5所示。首先計算第①步,結果是int型量,再依次計算第②~⑤步,最終整個表達式的結果的類型是double型。

《C++程式設計教程(第3版)》——第2章,第5節類型轉換
《C++程式設計教程(第3版)》——第2章,第5節類型轉換

掌握了混合運算時資料類型的轉換規則後,讀者應該能了解5/2的結果為2,5.0/2的結果為2.5的道理了,參見2.4.2節。

2.5.3 強制類型轉換

前面介紹了不同類型量互相指派時以及混合運算時的自動類型轉換,但有時為了強調類型的概念或者為了滿足運算符對資料類型的要求,可以顯式地寫出類型轉換,稱為強制類型轉換。格式是:

<類型名> (<表達式>) 或 (<類型名>) <表達式>

例如:

`int i, a;

float x, y;

double z;

i = int(x+y); 或 i = (int)(x+y);

z = double(a); 或 z = (double)a;

a = int(z) % i; 或 a = (int)z % i;`

例如,i=int (x+y)的意義是将表達式x+y的值轉換為int型量,指派給變量i。類型轉換運算符的優先級較高,表達式int (z) % i中運算符int優先級較高,是以首先計算int (z),即将z的值取整,再進行%運算。注意,%運算符要求運算量為整型量,必須首先将z的值強制轉換為整型量,才能計算%運算符。

注意:類型強制轉換的對象是表達式的值,表達式double (a)的意義是将a的值(即表達式的值)轉換成double型,而變量a自身仍然是int型變量。

繼續閱讀