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