本文發(fā)布于微信公眾號:三玹
上一篇文章,學習了C語言的6種基本數(shù)據(jù)類型。這篇文章就來聊一聊,基本數(shù)據(jù)類型之間的轉(zhuǎn)換。
什么是類型轉(zhuǎn)換?就是將數(shù)據(jù)(變量、數(shù)值、表達式結(jié)果等)從一種類型轉(zhuǎn)換到另一種類型。但這種改變并不是發(fā)生在原本數(shù)據(jù)上,一般都是創(chuàng)建一個新的類型變量來承載轉(zhuǎn)換類型的數(shù)據(jù)。為什么在程序中需要進行類型改變呢?來舉一個小小的栗子:
在現(xiàn)實生活中,我們現(xiàn)在有一群人的成績(數(shù)值為整數(shù)),我們需要計算他們的平均數(shù)。實際情況中,整數(shù)相除有可能是整數(shù),也有可能是小數(shù)。
但是在C語言當中,兩個整數(shù)相除,結(jié)果依然是整數(shù)。但如果實際結(jié)果是有小數(shù)部分的,那這樣的數(shù)據(jù)就失真了,因此就需要用到了類型轉(zhuǎn)換。#include<stdio.h>
int main(){
int a = 5;
int b = 2;
double c = a / b;
printf("%f", c);
return 0;
}
但實際上,這個運行結(jié)果并不是我們想要的。我們都知道 5 除以 2 是等于 2.5,為什么這里卻變成了2.000000呢?
這就是前面提到的,在C語言程序當中,兩個整數(shù)相除,結(jié)果還是整數(shù)。5 除以 2 雖然是等于 2.5,但是由于結(jié)果只能是整數(shù),所以丟棄了小數(shù)部分。但是為什么,還會有小數(shù)點呢?這里就涉及到了類型轉(zhuǎn)換的知識了。類型轉(zhuǎn)換,一共有兩種形式,一種是自動轉(zhuǎn)換,也叫作隱式轉(zhuǎn)換;另一種是強制轉(zhuǎn)換,也叫作顯式轉(zhuǎn)換。是編譯根據(jù)代碼上下文環(huán)境自行判斷的結(jié)果。
這種轉(zhuǎn)換方式,是系統(tǒng)自己默默地執(zhí)行,是暗地里的,所以也叫作隱式。就像老板讓你去訂一家飯館,但沒有告訴你細節(jié)問題。那能怎么辦?就只能根據(jù)以往的經(jīng)驗去訂魯菜館。但這種憑經(jīng)驗、憑理解,就會存在一個問題,誰知道老板今天請的客人會不會吃得慣這家飯館的菜呢?所以說,自動轉(zhuǎn)換是一種不安全的轉(zhuǎn)換方式,可能會存在數(shù)據(jù)失真、精度缺失等問題。就像我們上面的那一段計算代碼,就發(fā)生了數(shù)據(jù)失真的問題了。
那像這種情況應該要怎么解決呢?這就要提另一種轉(zhuǎn)換方式,強制轉(zhuǎn)換。
是程序員明確提出要進行的類型轉(zhuǎn)換,用特定的代碼格式去指定某一種類型的轉(zhuǎn)換。
同樣是老板讓你去訂飯店,但會跟你說今天請的這個客人他是四川人,從小在湖南長大,無辣不歡,去定一家川菜館或者湘菜館。這樣子目標就很明確了,就不會盲目地定一家魯菜館了。強制轉(zhuǎn)換是有特定的代碼格式來進行轉(zhuǎn)換的:typename variable = (typename) expression
typename 即數(shù)據(jù)的類型;variable 即變量;expression 可以是具體的值、某個變量、某個表達式等等。
在前面的那段計算代碼中加上對某個 int 類型進行強制轉(zhuǎn)換之后,再來看看結(jié)果是什么樣的:
#include<stdio.h>
int main(){
int a = 5;
int b = 2;
double c = (double)a/b;
printf("%f", c);
return 0;
}
運行結(jié)果:2.500000。
OK,符合預期的結(jié)果了!
看到這里,肯定有人又有疑惑了,為什么不直接把 a/b 括號起來然后進行轉(zhuǎn)換?為什么只轉(zhuǎn)換其中一個,結(jié)果就正確了呢?
首先第一個問題,這是因為如果括號起來,那么首先計算的是 a/b,仍舊是兩個整數(shù)相除,結(jié)果還是 2,然后經(jīng)過 double 轉(zhuǎn)換,運行的結(jié)果就和上面的一樣,都是2.000000。
第二個問題,為什么只轉(zhuǎn)換其中一個。這是因為在C語言中,不同類型的數(shù)據(jù)在進行操作的時候,首先會根據(jù)轉(zhuǎn)換規(guī)則將這兩種不同類型轉(zhuǎn)換為同一種類型。而轉(zhuǎn)換的規(guī)則,是由低級向高級轉(zhuǎn)換,具體如下圖所示:
注:unsigned 即 unsigned int。當然,你不嫌麻煩,也可以一個個進行強制轉(zhuǎn)后再進行運算。如果你老板不知道邀請的這位客人,因為吃辣的吃膩了,突然想要換個口味,吃個魯菜。那你都執(zhí)行下去了,結(jié)果很有可能就是項目黃了。
所以,強制轉(zhuǎn)換也不是絕對安全的。程序員在進行強制轉(zhuǎn)換的時候,一定要時刻保持警惕,要問自己進行轉(zhuǎn)換后數(shù)據(jù)會不會發(fā)生丟失,是否可能存在非方訪問,如果可以回答這兩個問題,并且能控制所有可能會發(fā)生的情況,就可以大膽嘗試去進行強制轉(zhuǎn)換。無論是自動轉(zhuǎn)換,還是強制轉(zhuǎn)換,目的都是為了本次運算而進行的一次臨時變換。轉(zhuǎn)換的結(jié)果是臨時保存在內(nèi)存中的,而并不會改變原本的值。#include<stdio.h>
int main(){
double a = 10.55;
int a_i = (int)a;
printf("a=%lf, a_i=%d", a, a_i);
return 0;
}
運行結(jié)果:a=10.550000,a_i=10
代碼中,double 類型的 a 變量通過強制轉(zhuǎn)換的方式將其轉(zhuǎn)換為 int 類型,并將值賦給了 a_i 變量,這種轉(zhuǎn)換并沒有影響到 a 變量本身的值或者類型。
如果 a 變量的值發(fā)生了改變,那么輸出的結(jié)果應該是 10.000000。
最后
關于基本數(shù)據(jù)類型之間的轉(zhuǎn)換內(nèi)容就講到了這里。文章中可能會存在一些缺漏的知識點,大家如果有什么想法或者疑惑可以在評論區(qū)留言,一起交流學習。最后,感謝大家的觀看!