1、什么是數(shù)據(jù)類型?
計(jì)算機(jī)編程語言是用來控制計(jì)算機(jī)的行為及操作,協(xié)助人們解決現(xiàn)實(shí)中的問題,其能表達(dá)的數(shù)據(jù)類型也是從實(shí)際中提取并抽象出來形成的數(shù)據(jù)結(jié)構(gòu)描述。
例如:數(shù)學(xué)中數(shù)的基礎(chǔ)分類有正整數(shù)、負(fù)整數(shù)、小數(shù)等類別,數(shù)學(xué)中所有關(guān)于數(shù)的運(yùn)算都是在基礎(chǔ)分類上進(jìn)行的。計(jì)算機(jī)出現(xiàn)之前,數(shù)學(xué)家們用稿紙進(jìn)行大量的數(shù)學(xué)運(yùn)算以求證數(shù)學(xué)問題和科學(xué)計(jì)算,這耗費(fèi)了數(shù)學(xué)家們太多的精力。隨著計(jì)算機(jī)科技的發(fā)展,大量復(fù)雜的數(shù)學(xué)運(yùn)算交給計(jì)算機(jī)來執(zhí)行,極大提高了計(jì)算效率,也讓數(shù)學(xué)家們從復(fù)雜的數(shù)學(xué)運(yùn)算中擺脫出來。
數(shù)學(xué)運(yùn)算包含大量的計(jì)算表達(dá)式,計(jì)算機(jī)程序需要有連續(xù)處理算式和計(jì)算數(shù)據(jù)的能力,下面是一個(gè)簡單的四則運(yùn)算算式:
15.8+20*31.5-30
計(jì)算機(jī)程序要處理上述算式,就需要具備存儲小數(shù)、整數(shù)、運(yùn)算符的能力。C語言提供了存儲小數(shù)、整數(shù)、運(yùn)算符的基本數(shù)據(jù)類型。下圖是算式中數(shù)據(jù)類型到C數(shù)據(jù)類型的映射圖。
圖 2-1數(shù)學(xué)算式數(shù)據(jù)類型到C語言數(shù)據(jù)類型的映射
2、變量與數(shù)據(jù)類型
使用變量可以將數(shù)學(xué)算式中的數(shù)存儲起來,下面討論如何聲明或定義一個(gè)變量。在C語言中聲明一個(gè)變量和定義一個(gè)變量存在區(qū)別:聲明變量是通知編譯器變量的類型和名字,編譯解析聲明變量時(shí),不會(huì)為該變量分配存儲空間,直至該變量被賦值時(shí),才會(huì)為變量分配存儲空間;定義變量是在聲明變量的同時(shí),為變量賦一個(gè)初始化值,編譯器解析定義變量時(shí),將為該變量分配存儲空間。
聲明一個(gè)變量
語法規(guī)則: 數(shù)據(jù)類型 變量名;
其中,數(shù)據(jù)類型可以是C語言支持的任何數(shù)據(jù)類型;變量名為聲明的變量名稱。
示例:聲明整型變量
int number;
示例:聲明字符型變量
char op;
定義一個(gè)變量
聲明變量的同時(shí)并對變量直接賦值,稱為定義一個(gè)變量。如果在聲明變量時(shí)沒有對變量進(jìn)行賦值,則應(yīng)在后面的程序語句中為變量賦值。
示例:定義整型變量
int number= 30;
示例:為已聲明的變量賦值
op=’+’;
下面簡要說明一個(gè)解析數(shù)學(xué)算式并存儲運(yùn)算符和運(yùn)算數(shù)的示例,為說明問題起見,給出一個(gè)簡單數(shù)學(xué)算式:8.25+30。
聲明三個(gè)變量用來存儲運(yùn)算數(shù)和運(yùn)算符
float floatNum;
int intNum;
char op;
程序在計(jì)算上述數(shù)學(xué)算式時(shí),首先從左到右掃描數(shù)學(xué)算式。假設(shè)本次掃描不考慮優(yōu)先級運(yùn)算,只是完成提取運(yùn)算數(shù)和運(yùn)算符的功能。掃描過程如下:如果是運(yùn)算數(shù),判斷是整數(shù)還是小數(shù),整數(shù)賦值給intNum,如果是小數(shù)賦值給floatNum,如果是運(yùn)算符賦值給op。下圖是掃描完成后,變量在內(nèi)存儲器的存儲情況。
圖 2-2 不同數(shù)據(jù)類型的變量在存儲器的存儲情況
從圖2-2可以看出,不同數(shù)據(jù)類型的變量在存儲器占用的空間也不相同。數(shù)據(jù)類型為字符型的變量在存儲器占用一個(gè)字節(jié)的空間。C語言對整數(shù)類型并沒有嚴(yán)格規(guī)定其長度(占用存儲空間的字節(jié)數(shù)),只做了寬泛的限制。圖2-4整數(shù)類型占用4個(gè)字節(jié)的存儲空間,是指在32位操作系統(tǒng)下,整數(shù)類型占用4個(gè)字節(jié)的存儲空間。
3、基礎(chǔ)數(shù)據(jù)類型
C語言基本數(shù)據(jù)類型見圖2-3。
圖 2-3 C語言基本數(shù)據(jù)類型
C語言基本數(shù)據(jù)類型包括數(shù)值、非數(shù)值兩種類型。數(shù)值類型又分為整數(shù)類型和非整數(shù)類型,整數(shù)類型包括整型、短整型和長整型,非整數(shù)類型包括單精度浮點(diǎn)和雙精度浮點(diǎn)。非數(shù)值包括字符類型。
4、整數(shù)類型
C語言的整數(shù)類型可以說是復(fù)雜多樣,根據(jù)存儲空間和數(shù)值范圍可分short(短整型,占用2個(gè)字節(jié))、int(整型,機(jī)器字長)、long(長整型,32位環(huán)境占用4個(gè)字節(jié),64位環(huán)境占用8個(gè)字節(jié))、long long(加長整型,占用8個(gè)字節(jié)),根據(jù)整數(shù)分類又可分為有符號整數(shù)和無符號整數(shù)。
對整數(shù)而言,C語言為什么要定義這么多不同的類型呢?
在發(fā)明C語言的年代,計(jì)算機(jī)的存儲資源是非常珍貴的,程序員設(shè)計(jì)和編寫程序?qū)Υ鎯Y源要精打細(xì)算,否則存儲資源就不夠用了。在存儲資源緊張的情況下,程序員優(yōu)先選用占用存儲空間小且能夠滿足數(shù)據(jù)處理要求的整數(shù)類型。即使在當(dāng)前存儲資源較為寬松的環(huán)境下,程序員在編寫代碼時(shí),通常能預(yù)想到需要使用到的數(shù)據(jù)范圍的大小,這樣在處理一個(gè)數(shù)據(jù)時(shí),可以從語言所提供的類型中選用最合適的類型來存儲數(shù)據(jù)。
實(shí)際上,C語言對short、int、long 并沒有嚴(yán)格規(guī)定其長度(占用存儲空間的字節(jié)數(shù)),只做了寬泛的限制:short 至少占用 2 個(gè)字節(jié);int 建議為一個(gè)機(jī)器字長。32 位環(huán)境下機(jī)器字長為 4 字節(jié),64 位環(huán)境下機(jī)器字長為 8 字節(jié);short 的長度不能大于 int,long 的長度不能小于 int。
由此可見,short 并不一定真的”短“,long 也并不一定真的”長“,它們有可能和 int 占用相同的字節(jié)數(shù)。在 16 位系統(tǒng)下,short 的長度為 2 個(gè)字節(jié),int 也為 2 個(gè)字節(jié),long 為 4 個(gè)字節(jié)。在32位和64位操作系統(tǒng)下,short 的長度為 2 個(gè)字節(jié),int 為 4 個(gè)字節(jié),long 也為 4 個(gè)字節(jié),long long類型為8個(gè)字節(jié)。
那么問題來了,在實(shí)際編程中如何確定一個(gè)整型占用的存儲空間大小呢?
C語言提供了sizeof運(yùn)算符來獲取數(shù)據(jù)類型占用的字節(jié)數(shù),sizeof運(yùn)算符傳入的參數(shù)可以是數(shù)據(jù)類型,也可以是變量名稱。例如下面的代碼分別輸出了不同數(shù)據(jù)類型的字節(jié)數(shù):
#include
void main()
{
char ch = 'a';
printf("short:%d字節(jié)n",sizeof(short));
printf("int:%d字節(jié)n",sizeof(int));
printf("long:%d字節(jié)n",sizeof(long));
printf("long:%d字節(jié)n",sizeof(long long));
printf("ch:%d字節(jié)n",sizeof(ch));
}
執(zhí)行上述代碼,輸出結(jié)果為:
整數(shù)類型有正整數(shù)和負(fù)整數(shù)之分,在C語言中,規(guī)定整型的最高位為符號位,最高位為“0”表示正數(shù),最高位為“1”表示負(fù)數(shù),其它位表示數(shù)值。因此整型類型的數(shù)據(jù)能夠表示的最小值為:-2n-1 —2n-1-1(n為該類型所占存儲空間的二進(jìn)制位數(shù))。
一個(gè)數(shù)在計(jì)算機(jī)中的二進(jìn)制表示形式, 叫做這個(gè)數(shù)的機(jī)器數(shù)。例如:十進(jìn)制數(shù)+3,使用8個(gè)二進(jìn)制位表示,轉(zhuǎn)換成二進(jìn)制就是00000011。如果是 -3 ,就是10000011 。00000011和10000011就是機(jī)器數(shù)。
因?yàn)樽罡呶皇欠栁?,因此機(jī)器數(shù)的形式值不一定等于真正的數(shù)值。例如上面的有符號數(shù) 10000011,其最高位1代表負(fù),其真正數(shù)值是 -3 而不是形式值131(10000011轉(zhuǎn)換成十進(jìn)制等于131)。為區(qū)別起見,后面的內(nèi)容將帶符號位的機(jī)器數(shù)對應(yīng)的真正數(shù)值稱為機(jī)器數(shù)的真值。
下面我們編寫一個(gè)簡單的程序,分別輸出+3和-3的機(jī)器數(shù),查看機(jī)器數(shù)的形式值是否為機(jī)器數(shù)的真值。
#include
void printf_binary(char n);
void main()
{
char positive = 3;
char negative = -3;
printf_binary(positive);
printf_binary(negative);
}
// 輸出二進(jìn)制數(shù)
void printf_binary(unsigned char n)
{
char i=0;
for(i=0; i< 8; i++ ){
if(n&(0x80 >?>i)){
printf("1");
}else{
printf("0");
}
}
printf("n");
}
char為字符類型,占用一個(gè)字節(jié)的存儲空間,值范圍為-128~127。printf_binary(unsigned char n)函數(shù)將十進(jìn)制數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)輸出,函數(shù)及函數(shù)內(nèi)的語句同學(xué)們先不要急于了解,后面的課程都會(huì)講到,重點(diǎn)關(guān)注程序的輸出結(jié)果
從輸出結(jié)果可以看出,+3的機(jī)器數(shù)為0000011,其形式值為3,機(jī)器數(shù)的形式值和真值相同。-3的機(jī)器數(shù)為11111101,其形式值為253,真值為-3,機(jī)器數(shù)的形式值和真值不相同,若把+3和-3的機(jī)器數(shù)相加,結(jié)果為0,運(yùn)算結(jié)果正確。實(shí)際上,計(jì)算機(jī)是以補(bǔ)碼的方式來存儲數(shù)值的。
計(jì)算機(jī)為什么以補(bǔ)碼方式來存儲數(shù)值呢?對于一個(gè)數(shù),計(jì)算機(jī)要使用一定的編碼方式進(jìn)行存儲,原碼、反碼、補(bǔ)碼是機(jī)器存儲一個(gè)具體數(shù)字的編碼方式。
原碼就是符號位加上真值的絕對值,即最高位是符號位,其余位用來表示值。例如1個(gè)8位的二進(jìn)制數(shù):
[+3] 原碼:0000 0011
[-3] 原碼:1000 0011
原碼比較容易理解,但不利于計(jì)算機(jī)的加減計(jì)算,因?yàn)樵a帶符號位,若對兩個(gè)原碼表示的機(jī)器數(shù)直接進(jìn)行加減運(yùn)算,運(yùn)算結(jié)果并不正確。若讓計(jì)算機(jī)能夠識別符號位,計(jì)算機(jī)的運(yùn)算電路設(shè)計(jì)就會(huì)非常復(fù)雜。因此計(jì)算機(jī)一般不采用原碼的方式來存儲數(shù)值。
既要讓符號位參與運(yùn)算,又要讓運(yùn)算電路設(shè)計(jì)簡單,使用補(bǔ)碼存儲數(shù)值就會(huì)解決這個(gè)問題。
補(bǔ)碼應(yīng)用了數(shù)學(xué)中同余的概念,同余的兩個(gè)數(shù)具有互補(bǔ)關(guān)系。給定一個(gè)正整數(shù)m,如果兩個(gè)整數(shù)a和b滿足a-b能夠被m整除,即(a-b)/m得到一個(gè)整數(shù),那么就稱整數(shù)a與b對模m同余,a和b具有互補(bǔ)關(guān)系。
回到整數(shù)類型, 補(bǔ)碼的計(jì)算規(guī)則為最高位是符號位,0表示正數(shù),1表示負(fù)數(shù),正數(shù)的補(bǔ)碼等于本身,負(fù)數(shù)的補(bǔ)碼等于反碼(正數(shù)的反碼等于本身,負(fù)數(shù)的反碼除符號位外,各位取反)+1。
例如:
[-3] 原碼:1000 0011 反碼:1111 1100 補(bǔ)碼:1111 1101
前面討論的都是有符號整數(shù),可以表示正負(fù)數(shù)。若只需要處理正整數(shù),可以在上述類型關(guān)鍵字前面添加unsigned關(guān)鍵字表示無符號整數(shù),兩個(gè)關(guān)鍵字用空格隔開,因?yàn)椴恍枰栁唬虼藷o符號整數(shù)表示的范圍為:0 —2n-1。下表列出了符號整數(shù)的類型。
整型變量可按如下方式聲明:
int pageNumber;
long int size;
short age;
unsigned short readCount;
在一條語句中,可以聲明多個(gè)同一類型的整型變量,每個(gè)變量之間用逗號分隔:
int pageNumber, likeNumber,readCount;
整型變量可按如下方式定義:
int pageNumber=230;
short age = 21;
unsigned short readCount=1260;
在定義變量或?yàn)樽兞抠x值時(shí),常常會(huì)用到一些數(shù)值,這些值通常稱為字面值。字面值有三種不同的表示形式:十進(jìn)制、八進(jìn)制和十六進(jìn)制。
八進(jìn)制表示:在八進(jìn)制數(shù)值前面加前綴數(shù)字0,其數(shù)碼取值為0—7,例如:023、0457、01329等;
十六進(jìn)制表示:前綴為“0X”或“0x”,數(shù)碼取值0—9、A—F、或a—f。例如:0X2A、0XA0、0Xffff等;
十進(jìn)制表示:既無前綴也無后綴。例如:236、56、7890等。
在字面值后面可以添加u或U(unsigned)、l或L(long)、u/U與l/L的組合(如:ul、lu、Lu等),表示該字面值的類型。例:100u; 123u; 0x123L;
5、浮點(diǎn)類型
浮點(diǎn)類型用來存儲實(shí)數(shù),為什么在C中把實(shí)數(shù)稱為浮點(diǎn)數(shù)呢?在C語言中實(shí)數(shù)是以指數(shù)形式存放在存儲單元中,類似于科學(xué)計(jì)數(shù)法形式,如:2.1E5、3.7e-2等,其中e或E之前必須有數(shù)字,且e或E后面的指數(shù)必須為整數(shù)。
一個(gè)大于0的實(shí)數(shù)可以用下面指數(shù)的方式來表示:
a * 10n (1<=a<10,n為整數(shù))
其中,a是該數(shù)值的有效位數(shù),有效位數(shù)從左邊第一個(gè)不是0的數(shù)起,到末尾數(shù)字為止,所有的數(shù)字(包括0,科學(xué)計(jì)數(shù)法不計(jì)10的n次方),稱為有效數(shù)字。例如:光速是3E8,其有效數(shù)字是1位,值是3;世界人口數(shù)大約是6.1E9,其有效數(shù)字是2位,值是6.1。
n是該數(shù)值的整數(shù)部分減1的正整數(shù)。
一個(gè)小于0的實(shí)數(shù)可以用下面指數(shù)的方式來表示:
a * 10-n (1<=a<10,n為整數(shù))
a的取值同上面相同,n的取值為原數(shù)中左邊第一個(gè)不為0的數(shù)字前面所有的0的個(gè)數(shù)(包括小數(shù)點(diǎn)前面的0)。
一個(gè)實(shí)數(shù)表示為指數(shù)形式,通過移動(dòng)小數(shù)點(diǎn)可以有多種表示方法。例如:實(shí)數(shù)3.14159可以表示為以下的指數(shù)形式:
3.14159E0
0.314159E1
314.159E-2
上面的指數(shù)形式因?yàn)樾?shù)點(diǎn)所在位置不同,指數(shù)也不同,但實(shí)際表示的數(shù)值都是3.14159。因此只要在小數(shù)點(diǎn)位置浮動(dòng)的同時(shí)改變指數(shù)的值,就可以保證它的值不會(huì)改變。由于小數(shù)點(diǎn)位置可以浮動(dòng),所以實(shí)數(shù)的指數(shù)形式稱為浮點(diǎn)數(shù)。
在C語言中,浮點(diǎn)類型有float和double兩種,分別表示單精度浮點(diǎn)數(shù)和雙精度浮點(diǎn)數(shù)。精度是指描述一個(gè)數(shù)值的準(zhǔn)確程度,在數(shù)學(xué)運(yùn)算中,經(jīng)常會(huì)用到近似數(shù),近似數(shù)與原數(shù)值非常相近,但又不完全符合原數(shù)值,只能說在某種程度上近似。精度與近似數(shù)相似,也是用一個(gè)與原數(shù)值非常相近的數(shù)代替原來的數(shù)值。
前面說過存儲一個(gè)數(shù)值所用的字節(jié)越多,其精度越高,數(shù)值范圍也越大。由此看來,精度與存儲字節(jié)數(shù)密切相關(guān),float類型的存儲空間是4個(gè)字節(jié),其表示的值范圍約為10-38到1038,double類型的存儲空間是8個(gè)字節(jié),其表示的值范圍約為10-308到10308,float存儲數(shù)值的精度和范圍要小于double存儲數(shù)值的精度和范圍。因此,float是單精度數(shù)值,double是雙精度數(shù)值。
圖 2-4浮點(diǎn)型變量占用的存儲空間
實(shí)數(shù)的指數(shù)形式有多種表示方法,計(jì)算機(jī)在存儲實(shí)數(shù)時(shí),一般采用標(biāo)準(zhǔn)化的指數(shù)形式,即小數(shù)點(diǎn)前的數(shù)字為0,小數(shù)點(diǎn)后第1為數(shù)字不為0。例如:0.314159E1就是3.14159的標(biāo)準(zhǔn)化的指數(shù)形式。
float類型的變量占用4個(gè)字節(jié)的存儲空間,系統(tǒng)存儲float類型的實(shí)數(shù)時(shí),將實(shí)數(shù)分為小數(shù)部分和指數(shù)部分。最高位為符號位,小數(shù)部分占23位,剩余的8位存儲實(shí)數(shù)的指數(shù)部分(包括指數(shù)的符號)。由于用二進(jìn)制形式表示一個(gè)實(shí)數(shù)以及存儲單元的長度是有限的,因此不可能得到完全精確的值,只能存儲成有限的近似值。小數(shù)部分占的位數(shù)愈多,數(shù)的有效數(shù)字愈多,精度也就愈高。指數(shù)部分占的位數(shù)愈多,則能表示的數(shù)值范圍越大。
double類型的變量占用8個(gè)字節(jié)的存儲空間,最高位為符號位,小數(shù)部分占52位,剩余的11位存儲實(shí)數(shù)的指數(shù)部分(包括指數(shù)的符號)。
float變量可按如下方式定義:
float price = 12.35f;
float average = 89.2f;
double變量可按如下方式定義:
double pi = 3.14159265;
public double average = 89.2987017;
字面值賦值給float變量時(shí),數(shù)值尾部要加上小寫“f”或大寫“F”聲明為float類型的數(shù)值,不然編譯器會(huì)給出從“double”到“float”截?cái)嗟木妗R驗(yàn)樵贑語言中,帶小數(shù)的字面值默認(rèn)為是double類型,double類型轉(zhuǎn)換為float類型,自然要損失精度,位數(shù)被截?cái)嗔恕?/p>
C語言還提供了long double類型,表示長雙精度浮點(diǎn)數(shù),但C語言并沒有l(wèi)ong double的確切精度,對于不同系統(tǒng)平臺可能有不同的實(shí)現(xiàn),有的是8字節(jié),有的是10字節(jié),有的是12字節(jié)或16字節(jié),C語言函數(shù)sizeof(long double)可以輸出當(dāng)前系統(tǒng)平臺下long double占用的字節(jié)數(shù)。
浮點(diǎn)類型字面值的后綴有:f或F(單精度浮點(diǎn)數(shù))、l或L(長雙精度浮點(diǎn)數(shù)),因?yàn)楦↑c(diǎn)型常數(shù)總是有符號的,所以沒有u或U后綴。例:1.23e5f; 1.23L; -123.45f。
6、字符類型
在編寫程序時(shí),我們還經(jīng)常會(huì)遇到需要存儲并操縱字符型數(shù)據(jù)的情況。例如:計(jì)算數(shù)學(xué)算式時(shí),需要存儲運(yùn)算符,這時(shí)就需要一種可以存儲單個(gè)字符數(shù)據(jù)(字符包括字母、數(shù)字、運(yùn)算符號、標(biāo)點(diǎn)符號和其他符號,以及一些功能性符號)的數(shù)據(jù)類型。C語言提供了一種char數(shù)據(jù)類型,可以滿足存儲單個(gè)字符的需要。
計(jì)算機(jī)中的字符一般采用ASCII碼表示,ASCII碼是一種標(biāo)準(zhǔn)的字符編碼方式,規(guī)定每個(gè)字符對應(yīng)一個(gè)數(shù),例如:十進(jìn)制數(shù)65對應(yīng)大寫字母A,97對應(yīng)小寫字母a。ASCII編碼最后一次更新是在1986年,到目前為止共定義了128個(gè)字符。
ASCII字符與編碼映射范圍表:
標(biāo)準(zhǔn)ASCII碼使用7位二進(jìn)制數(shù)來表示所有的大寫和小寫字母,數(shù)字0 到9、標(biāo)點(diǎn)符號,以及在美式英語中使用的特殊控制字符。char數(shù)據(jù)類型占用一個(gè)字節(jié)的存儲空間,可以表示8位二進(jìn)制數(shù),完全可以存儲ASCII碼。
char變量可按如下方式定義:
char code=’a’, op=’*’,digit=’0’;
任意單個(gè)字符,加單引號。
char code =97
可以直接把ASCII碼十進(jìn)制數(shù)97賦值給char型變量code。
上面例句中的‘a(chǎn)’, ’*’, ‘0’為字符字面值,字符字面值需要使用一對單引號括起來,括號內(nèi)只能包含一個(gè)字符。除了字符常量可以賦值給char型變量外,0~255的整數(shù)常量也可以賦值給char型變量。char型變量通常用來存儲字符,若存儲的數(shù)值超過ASCII碼范圍,變量的值沒有實(shí)際意義。
標(biāo)準(zhǔn)C語言沒有提供byte數(shù)據(jù)類型,byte占1個(gè)字節(jié)的存儲空間,表示的數(shù)值范圍是0~255。若需要使用byte數(shù)據(jù)類型,可以使用unsinged char來表示byte數(shù)據(jù)類型。
7、類型轉(zhuǎn)換
C語言是強(qiáng)類型語言,變量的數(shù)據(jù)類型被指定后,會(huì)一直保持該數(shù)據(jù)類型。同時(shí)C語言對參與賦值運(yùn)算和算術(shù)運(yùn)算的操作數(shù)數(shù)據(jù)類型要求必須一致,當(dāng)參與運(yùn)算的操作數(shù)數(shù)據(jù)類型不一致時(shí),就需要對操作數(shù)的數(shù)據(jù)類型進(jìn)行類型轉(zhuǎn)換,把參與運(yùn)算的操作數(shù)轉(zhuǎn)換為同一數(shù)據(jù)類型后,再進(jìn)行運(yùn)算。
隱式類型轉(zhuǎn)換
例如:
double PI = 3.14;
int radius = 5;
double s;
s = PI * PI * radius;
在上面的例句中,表達(dá)式PI * PI * radius有二個(gè)操作數(shù),PI是double類型,radius是整數(shù)類型。因?yàn)椴僮鲾?shù)的數(shù)據(jù)類型不一致,C語言編譯器會(huì)對數(shù)據(jù)類型做強(qiáng)制轉(zhuǎn)換,將radius的整數(shù)類型強(qiáng)制轉(zhuǎn)換為double類型。
這種轉(zhuǎn)換是C編譯器自動(dòng)進(jìn)行的,開發(fā)者不需要進(jìn)行任何操作,由C編譯器自動(dòng)完成,這種類型的轉(zhuǎn)換也稱為隱式轉(zhuǎn)換。
由于不同的數(shù)據(jù)類型存儲空間和表示的數(shù)值精度是不同的,因此在數(shù)據(jù)類型的轉(zhuǎn)換過程中,就會(huì)存在數(shù)值精度丟失和數(shù)值溢出的問題。例如:double類型轉(zhuǎn)換為float類型,數(shù)值精度就會(huì)丟失;long類型轉(zhuǎn)換為int類型時(shí),如果long類型變量存儲的數(shù)值超過了int類型能夠存儲的數(shù)值范圍,就會(huì)發(fā)生數(shù)值溢出。
為了避免在轉(zhuǎn)換過程中發(fā)生數(shù)值精度丟失和溢出的問題,隱式轉(zhuǎn)換都會(huì)遵循從低級數(shù)據(jù)類型到高級類型的轉(zhuǎn)換規(guī)則,也可以說是從數(shù)值存儲精度小的類型到存儲數(shù)值精度高的類型轉(zhuǎn)換。這些數(shù)據(jù)類型按數(shù)值存儲范圍大小依次為:
short->int->long->float->double
下表列出了數(shù)據(jù)類型隱式轉(zhuǎn)換的一般規(guī)則。
【例】類型的隱式轉(zhuǎn)換練習(xí)
程序清單 sample.c
#include
int main()
{
// 聲明char類型的變量
char chTemp = 65;
// 聲明int類型的變量
int nTemp = 34;
// 聲明float類型的變量
float fTemp = 29.6f;
// 聲明double類型的變量
double dTemp = 86.69;
printf("char類型的數(shù)據(jù)與float類型的進(jìn)行相加運(yùn)算,運(yùn)算結(jié)果為:%.2fn",(chTemp+fTemp));
printf("float類型的數(shù)據(jù)與double類型的進(jìn)行相加運(yùn)算,運(yùn)算結(jié)果為:%.2fn",(fTemp+dTemp));
printf("char類型的數(shù)據(jù)與int類型的進(jìn)行相加運(yùn)算,運(yùn)算結(jié)果為:%dn",(chTemp+nTemp));
}
7、顯示類型轉(zhuǎn)換
顯示類型轉(zhuǎn)換是相對隱式轉(zhuǎn)換來說的,隱式轉(zhuǎn)換由C編譯器自動(dòng)進(jìn)行,不需要開發(fā)者做任何操作。顯示類型轉(zhuǎn)換需要開發(fā)者在代碼中對數(shù)據(jù)類型進(jìn)行顯示類型轉(zhuǎn)換。
當(dāng)進(jìn)行數(shù)據(jù)類型的顯示轉(zhuǎn)換時(shí),程序員需要自身判斷類型轉(zhuǎn)換過程中是否會(huì)發(fā)生數(shù)值溢出或精度丟失,當(dāng)由精度高的類型轉(zhuǎn)換為精度低的類型時(shí),會(huì)發(fā)生精度丟失。
顯示轉(zhuǎn)換的一般形式為:
(類型名)要轉(zhuǎn)換的變量或常量
例如:
// 將數(shù)值36.9強(qiáng)制轉(zhuǎn)換為int,精度丟失
int nTemp = (int)36.9;
// 聲明double類型的變量
double dTemp = 12.15;
// 將double類型強(qiáng)制轉(zhuǎn)換為int,精度丟失
int nV = (int)dTemp;
在上面的例句中,36.9是數(shù)值常量,默認(rèn)為double類型,顯示轉(zhuǎn)換為int類型并賦值給nTemp,此時(shí)nTemp的值為36,精度丟失。
dTemp是double類型的變量,將dTemp的值賦值給int變量時(shí),需要進(jìn)行顯示轉(zhuǎn)換,int變量只存儲double變量的整數(shù)部分,小數(shù)部分丟失。
評論
查看更多