在 C 語言的表達(dá)式賦值時(shí),要小心背后默默的隱式類型轉(zhuǎn)換,它們會(huì)導(dǎo)致隱藏的 Bug。
C的整型算數(shù)運(yùn)算總是至少以缺省整型類型的精度來進(jìn)行的。為了獲得這個(gè)精度,表達(dá)式中的字符型和短整型操作數(shù)在使用之前被轉(zhuǎn)換為普通整型。
例:
char a,b,c ;
a = b+c ;
注意,根據(jù)整型提升規(guī)則,上面b和c的值被提升為普通整型,然后再執(zhí)行加法運(yùn)算。加法運(yùn)算的結(jié)果被截?cái)嘣俅鎯?chǔ)于a中。
在整數(shù)運(yùn)算時(shí),操作數(shù)是放到兩個(gè)寄存器中進(jìn)行的(32位計(jì)算機(jī)寄存器是32位 故字符型變量被提升為整型,計(jì)算的結(jié)果又被傳回到內(nèi)存中的字符型存儲(chǔ)位置中故被截?cái)啵?/p>
【所以,最好把字符型定義為int型,尤其是涉及運(yùn)算時(shí)】
例:
signed char a = 0xe0;
unsigned int b = a;
unsigned char c = a;
b的十六進(jìn)制表示:
a 是一個(gè) signed char,賦值給 unsigned int 的 b,并不是直接在前面若干個(gè)字節(jié)補(bǔ) 0。
而是,首先 signed char a 轉(zhuǎn)換為 int(0xffffffe0),然后 int 轉(zhuǎn)換成 unsigned int(0xffffffe0),所以最初是符號(hào)擴(kuò)展,然后一個(gè) int 賦值給了 unsigned int。
c的十六進(jìn)制表示為0xe0,但 a == c 為假。
雖然 a 和 c 的二進(jìn)制表示一模一樣,都是 0xe0,但a == c中,a和c都要先轉(zhuǎn)換成int型,再比較。a轉(zhuǎn)int型為負(fù)數(shù),b轉(zhuǎn)int型為正數(shù),故它倆不等。
在涉及數(shù)值運(yùn)算時(shí),還要注意溢出的情況。
例:
int a=5000 ;
int b=25 ;
long c=a*b ;
表達(dá)式a*b以整型進(jìn)行計(jì)算,若在16位的計(jì)算機(jī)上,這個(gè)乘法可能會(huì)產(chǎn)生溢出!
故應(yīng)該顯式轉(zhuǎn)換: long c =(long)a*b ;
【在進(jìn)行算術(shù)運(yùn)算時(shí)一定要警惕乘法加法的可能溢出,尤其注意賦值號(hào)兩邊的數(shù)據(jù)類型保持一致】
更多建議: