【揭秘】C語(yǔ)言類(lèi)型轉(zhuǎn)換時(shí)發(fā)生了什么?

在C語(yǔ)言中,數(shù)據(jù)類(lèi)型指的是用于聲明不同類(lèi)型的變量或函數(shù)的一個(gè)廣泛的系統(tǒng),我們常用的算術(shù)類(lèi)型包括兩種類(lèi)型:整數(shù)類(lèi)型和浮點(diǎn)類(lèi)型。那么相互之間具體是怎么轉(zhuǎn)化的呢?

了解一下類(lèi)型轉(zhuǎn)換

不同數(shù)據(jù)類(lèi)型的存儲(chǔ)大小和值范圍是不一樣的,程序在初始化的時(shí)候就已經(jīng)設(shè)定了,例如:

int?a?=?9;

floatb?=?8.5;

a,b占的字節(jié)大小不一樣,這個(gè)我們應(yīng)該都知道,在C語(yǔ)言中一個(gè)表達(dá)式允許不同類(lèi)型的數(shù)據(jù)進(jìn)行運(yùn)算,例如:

int?a?=?9;

floatb?=?8.5,c;

c?=?a?+?b;

因?yàn)橛?jì)算機(jī)硬件在進(jìn)行算術(shù)操作時(shí),要求各操作數(shù)的類(lèi)型具有相同的存儲(chǔ)位數(shù)以及一樣的存儲(chǔ)方式,所以就出現(xiàn)了類(lèi)型轉(zhuǎn)換。

對(duì)于某些類(lèi)型的轉(zhuǎn)換,編譯器可以隱式地自動(dòng)進(jìn)行,這種轉(zhuǎn)換稱(chēng)為自動(dòng)類(lèi)型轉(zhuǎn)換

而有些類(lèi)型轉(zhuǎn)換需要程序員顯式指明,那么通常把這種轉(zhuǎn)換稱(chēng)為強(qiáng)制類(lèi)型轉(zhuǎn)換

自動(dòng)類(lèi)型轉(zhuǎn)換

自動(dòng)轉(zhuǎn)換是在源類(lèi)型和目標(biāo)類(lèi)型兼容以及目標(biāo)類(lèi)型廣于源類(lèi)型時(shí)發(fā)生一個(gè)類(lèi)型到另一類(lèi)的轉(zhuǎn)換。我們先來(lái)看一段代碼

#include?<stdio.h>

intmain()

{

//定義一個(gè)整型指針變量pPoint

int*?pPoint;

//定義基本的數(shù)據(jù)的類(lèi)型

char?c;

short?s;

int?i;

long?l;

floatf;

double?d;

//將整型浮點(diǎn)型數(shù)據(jù)賦值給指針類(lèi)型

pPoint?=?c;

pPoint?=?s;

pPoint?=?i;

pPoint?=?l;

pPoint?=?f;

pPoint?=?d;

return0;

}

由于指針變量和整型、浮點(diǎn)這些數(shù)據(jù)型的類(lèi)型是不能相互賦值的,編譯報(bào)錯(cuò)輸出:

那么我們把同類(lèi)型數(shù)據(jù)類(lèi)型進(jìn)行運(yùn)算后賦值呢?

#include?<stdio.h>

intmain()

{

//定義一個(gè)整型指針變量pPoint

int*?pPoint;

//定義基本的數(shù)據(jù)的類(lèi)型

char?c;

short?s;

int?i;

long?l;

floatf;

double?d;

//將整型浮點(diǎn)型數(shù)據(jù)運(yùn)算之后賦值給指針類(lèi)型

pPoint?=?c?+?c;

pPoint?=?s?+?s;

pPoint?=?i?+?i;

pPoint?=?l?+?l;

pPoint?=?f?+?f;

pPoint?=?d?+?d;

return0;

}

char同類(lèi)型運(yùn)算,結(jié)果是一個(gè)int類(lèi)型。

short同類(lèi)型運(yùn)算,結(jié)果是一個(gè)int類(lèi)型。

int同類(lèi)型運(yùn)算,結(jié)果是一個(gè)int類(lèi)型。

long同類(lèi)型運(yùn)算,結(jié)果是一個(gè)long類(lèi)型。

float同類(lèi)型運(yùn)算,結(jié)果是一個(gè)float類(lèi)型。

double同類(lèi)型運(yùn)算,結(jié)果是一個(gè)double類(lèi)型。

如下圖所示:

同類(lèi)型運(yùn)算中:

整型:比int小的,都會(huì)轉(zhuǎn)換成int,比int大的不變。

浮點(diǎn):不變。

那么我們把不同類(lèi)型數(shù)據(jù)類(lèi)型進(jìn)行運(yùn)算后賦值呢?

#include?<stdio.h>

intmain()

{

//定義一個(gè)整型指針變量pPoint

int*?pPoint;

//定義基本的數(shù)據(jù)的類(lèi)型

char?c;

short?s;

int?i;

long?l;

floatf;

double?d;

//將整型浮點(diǎn)型數(shù)據(jù)混合運(yùn)算賦值給指針類(lèi)型

pPoint?=?c?+?s;??//?char?+?short?=?int

pPoint?=?c?+?i;??//?char?+?int?=?int

pPoint?=?c?+?l;??//?char?+?long?=?int

pPoint?=?c?+?f;??//?char?+float=?long

pPoint?=?c?+?d;??//?char?+?double?=float

return0;

}

char類(lèi)型與short類(lèi)型運(yùn)算,結(jié)果是一個(gè)int類(lèi)型。

char類(lèi)型與int類(lèi)型運(yùn)算,結(jié)果是一個(gè)int類(lèi)型。

char類(lèi)型與long類(lèi)型運(yùn)算,結(jié)果是一個(gè)long類(lèi)型。

char類(lèi)型與float類(lèi)型運(yùn)算,結(jié)果是一個(gè)float類(lèi)型。

char類(lèi)型與double類(lèi)型運(yùn)算,結(jié)果是一個(gè)double類(lèi)型。

結(jié)果如下圖所示:

可以得出在不同類(lèi)型運(yùn)算中:

如果兩邊均比int小或等于int,那么結(jié)果為int。

如果兩邊有比int大的,那么結(jié)果為比int大的類(lèi)型。

我們得到結(jié)論如圖:

整型類(lèi)型級(jí)別從低到高依次為:

int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long

浮點(diǎn)型級(jí)別從低到高依次為:

float -> double

自動(dòng)轉(zhuǎn)換規(guī)則:

圖中橫向箭頭表示必須的轉(zhuǎn)換,如兩個(gè)float型數(shù)參加運(yùn)算,雖然它們類(lèi)型相同,但仍要先轉(zhuǎn)成double型再進(jìn)行運(yùn)算,結(jié)果亦為double型。

圖中縱向箭頭表示當(dāng)運(yùn)算符兩邊的運(yùn)算數(shù)為不同類(lèi)型時(shí)的轉(zhuǎn)換,如一個(gè)long 型數(shù)據(jù)與一個(gè)int型數(shù)據(jù)一起運(yùn)算,需要先將int型數(shù)據(jù)轉(zhuǎn)換為long型, 然后兩者再進(jìn)行運(yùn)算,結(jié)果為long型。

當(dāng)較高類(lèi)型的數(shù)據(jù)轉(zhuǎn)換為較低類(lèi)型時(shí),則可能有些數(shù)據(jù)丟失。

當(dāng)較低類(lèi)型的數(shù)據(jù)轉(zhuǎn)換為較高類(lèi)型時(shí),一般只是形式上有所改變, 而不影響數(shù)據(jù)的實(shí)質(zhì)內(nèi)容。

所有這些轉(zhuǎn)換都是由系統(tǒng)自動(dòng)進(jìn)行的,使用時(shí)你只需從中了解結(jié)果的類(lèi)型即可。

強(qiáng)制類(lèi)型轉(zhuǎn)換

強(qiáng)制類(lèi)型轉(zhuǎn)換是通過(guò)類(lèi)型轉(zhuǎn)換運(yùn)算來(lái)實(shí)現(xiàn)的。其一般形式為:

(類(lèi)型說(shuō)明符)?(表達(dá)式)

其作用就是把表達(dá)式的運(yùn)算結(jié)果強(qiáng)制轉(zhuǎn)換成類(lèi)型說(shuō)明符所表示的類(lèi)型的值。

#include<stdio.h>

#include<string.h>

intmain()

{

floatf,x=1.3,y=1.4;

int?i?=?4,a,b;

a?=?x?+?y;

b?=?(int)(x+y);

f?=?10/i;

printf("a=%d,b=%d,f=%f,x=%f,y=%f\n",a,b,f,x,y);

}

運(yùn)行結(jié)果如下:


我們從中可以看到,雖然x,y變強(qiáng)制轉(zhuǎn)換int型,但是最后輸出的值不變,強(qiáng)制類(lèi)型轉(zhuǎn)換沒(méi)有影響x和y變量原本的類(lèi)型。而上圖警告已經(jīng)說(shuō)明了一切。

注意:在C語(yǔ)言中,對(duì)一個(gè)變量賦值的時(shí)候,這個(gè)變量初始定義的類(lèi)型包含了兩層含義:

這個(gè)數(shù)據(jù)類(lèi)型表示的內(nèi)存空間的大小。

編譯器把設(shè)定的數(shù)值放到這個(gè)內(nèi)存空間,是數(shù)據(jù)類(lèi)型的存儲(chǔ)方式解析后存進(jìn)去的。

總結(jié)強(qiáng)調(diào)一點(diǎn)

進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換后,內(nèi)存空間里面的內(nèi)容是不會(huì)發(fā)生改變的,改變的是運(yùn)算時(shí)的臨時(shí)數(shù)據(jù)對(duì)象的類(lèi)型,是你去讀取這個(gè)內(nèi)存空間時(shí)的解析方法。所以,一定要對(duì)這個(gè)數(shù)據(jù)類(lèi)型的內(nèi)存空間和解析方式有一個(gè)清晰的認(rèn)知。

C/C++學(xué)-習(xí)-交-流-裙 ?10+830+20+561

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容