石也牧
華中師范大學(xué)人工智能教育學(xué)部 湖北 武漢 430079
C語言是最重要的編程語言之一,它同時具備高級和低級語言的特點[1]。C語言的目標(biāo)程序效率高,它被廣泛應(yīng)用于多個領(lǐng)域:Linux內(nèi)核使用的是C語言、Python是用C語言寫的、《數(shù)據(jù)結(jié)構(gòu)》課程一般也使用C語言來描述,等等。C語言自身有很多陷阱,編程者一不小心就會“掉進(jìn)坑里”[2]。了解C語言常見的陷阱和規(guī)避方法,可以更深刻地理解相關(guān)的知識點,使較難的學(xué)習(xí)過程變得相對輕松。
下面這段程序,是兩個整數(shù)的比較,顯然x比y大,預(yù)期的打印結(jié)果為x〉y:

實際的運(yùn)行結(jié)果為x〈=y。x是無符號整型,y是普通整型,當(dāng)把它們比較時,系統(tǒng)先將類型轉(zhuǎn)換一致,y被轉(zhuǎn)換為無符號整型。增加一條打印語句printf(“%u ”,y),可知,-1轉(zhuǎn)換為無符號整數(shù)之后為4294967295,所以,結(jié)果為x〈=y。
不同類型的變量,取值范圍不同,要盡量避免兩個不同類型數(shù)值的比較。當(dāng)然,可采取類型的強(qiáng)制轉(zhuǎn)換,但也改變不了變量的原本取值范圍。
直接判斷兩個浮點數(shù)是否相等合乎語法,但結(jié)果會出乎意料。例如:

打印結(jié)果為:b!=0.1。系統(tǒng)認(rèn)為b與0.1不相等,這是由浮點數(shù)的存儲方式導(dǎo)致的,計算機(jī)在存儲浮點數(shù)時是有誤差的。增加一條打印語句printf(“%.18f ”, b),得到結(jié)果是0.100000001490116120,看來b確實不是0.1。判斷兩個浮點數(shù)是否相等,應(yīng)該采用的方法是:判斷它們之差的絕對值是否小于某個預(yù)設(shè)的很小的正數(shù)。就是說,計算機(jī)上的兩個浮點數(shù)相等,是指在可接受的誤差范圍之內(nèi)相等。
在程序預(yù)處理階段,系統(tǒng)進(jìn)行宏替換,注意,只是簡單的字符串替換。宏定義不是普通的語句,結(jié)尾不需要加分號,如果加了可能會導(dǎo)致錯誤。例如:
#define MAX 10;
int a[MAX];
MAX被替換后,數(shù)組a變?yōu)閍[10;],這顯然是不對的。
宏比函數(shù)簡潔靈活,宏不是函數(shù)。例如,定義宏SUM,SUM與(a,b)之間有空格:
#define SUM (a,b) ((a)+(b))
引用SUM(1,2)不能得到1與2之和,因為SUM被替換為(a,b)((a)+(b)),而不是SUM(1,2)被替換為((1)+(2))。如果是函數(shù)定義,函數(shù)名后面有或者沒有空格,都不影響函數(shù)的功能。