15.1 數(shù)組下標(biāo)應(yīng)從0開始
指定數(shù)組下標(biāo)時出現(xiàn)的失誤可能打亂整個數(shù)據(jù)集合。特別是編寫循環(huán)語句時丧裁,更要多加留意护桦。
15.2 置換字符串時必須使用括號
宏函數(shù)中的括號
15.3 文件必須有開就有關(guān)
程序打開相應(yīng)文件后沒有關(guān)閉,會造成“無法打開文件”錯誤煎娇。
15.4 不要無視編譯器的警告錯誤
如果程序本身有語法錯誤二庵,編譯器會在編譯過程種發(fā)現(xiàn)并提示其存在贪染。
- 致命錯誤(fatel error)
通常指如果不修復(fù)錯誤,程序就無法運(yùn)行 - 警告錯誤(warning error)
這種錯誤可能在程序運(yùn)行過程種并不會引起什么大問題催享,或者根本不會產(chǎn)生問題杭隙。修復(fù)這種問題意味著修復(fù)全部程序漏洞。
15.5 掌握并在編碼時防止運(yùn)行時錯誤
程序運(yùn)行過程種出現(xiàn)的錯誤稱為運(yùn)行時錯誤因妙,這種錯誤不同于編譯錯誤和邏輯錯誤痰憎。
編譯錯誤主要是語法問題引發(fā)的,邏輯錯誤主要是程序邏輯或算法的設(shè)計(jì)缺陷引發(fā)的攀涵,而運(yùn)行時錯誤則與運(yùn)行時環(huán)境緊密相關(guān)铣耘。
下面詳細(xì)降解其中兩個最具代表性的運(yùn)行時錯誤。這兩種錯誤非常常見以故,只要能夠避免二者的發(fā)生蜗细,就可以編寫相當(dāng)穩(wěn)定的程序。
15.5.1 棧溢出
計(jì)算機(jī)用棧這種數(shù)據(jù)結(jié)構(gòu)管理臨時存儲空間怒详。程序中使用的自動變量在被聲明的同時就被保存到棧炉媒,而一旦脫離自動變量使用范圍,就會被棧釋放昆烁。
變量在棧中隨時保存或釋放吊骤,所以沒有必要將棧設(shè)為無限大。各操作系統(tǒng)都對棧的大小進(jìn)行了限制静尼,雖然這種限制程度略有放寬白粉,甚至一部分操作系統(tǒng)允許用戶自主控制并調(diào)整棧大小,但處理大容量數(shù)據(jù)時仍可能發(fā)生棧溢出茅郎。
棧溢出常見于使用大數(shù)組或調(diào)用遞歸函數(shù)的情況蜗元。因此或渤,使用遞歸調(diào)用時系冗,一定要細(xì)致檢查出現(xiàn)棧溢出的可能性。特別是并未準(zhǔn)確限制遞歸調(diào)用的次數(shù)薪鹦,而遞歸只有在滿足某個條件時才會終止的情況下掌敬,這種檢查更為必要。
15.5.2 除以0
沒有程序員會故意用0除某值池磁,但在非常復(fù)雜的代碼中奔害,可能出現(xiàn)除數(shù)偶然為0的情況。
另一種情況常見于控制語句地熄。試想华临,在for或while語句中,用計(jì)算循環(huán)次數(shù)的變量(計(jì)數(shù)器)作為除數(shù)端考,與其他變量值做除法運(yùn)算雅潭。難道沒有計(jì)數(shù)器為0的情況嗎揭厚?倒序計(jì)數(shù)時又會怎樣呢?這種情況大多潛藏在復(fù)雜邏輯中扶供,很難把握筛圆。這就要求程序員清醒認(rèn)識到,除以0的情況隨時可能出現(xiàn)椿浓,并為防范這種情況的出現(xiàn)而細(xì)致檢查程序所有可能的運(yùn)行情況太援。
15.6 用靜態(tài)變量聲明大數(shù)組
C語言根據(jù)變量的生存周期、影響范圍和存儲位置的不同扳碍,將變量分為幾類提岔,如下表所示:
變量修飾符 | 變量名 | 存儲位置 |
---|---|---|
extern | 外部變量 | 存儲于堆 |
static | 靜態(tài)變量 | 存儲于堆 |
auto | 自動變量 | 存儲于棧 |
register | 寄存器變量 | 存儲于CPU的寄存器 |
自動變量存儲于以棧形態(tài)管理數(shù)據(jù)的內(nèi)存。嵌入式系統(tǒng)等部分常用操作系統(tǒng)中笋敞,規(guī)定的棧比較小唧垦。因此,如果一個程序用到的所有自動變量的總和超出棧的大小液样,就會觸發(fā)棧溢出振亮,進(jìn)而導(dǎo)致程序異常終止。
只要數(shù)組本身可鞥占據(jù)大量棻廾В空間坊秸,就最好將數(shù)組聲明為靜態(tài)變量。這樣可以保證有足夠的空間澎怒,將數(shù)組之外的其他變量聲明為自動變量并正常使用褒搔。
但管理靜態(tài)變量與模塊化原則相沖突,所以應(yīng)該慎重對待是否聲明靜態(tài)變量的問題喷面。
15.7 預(yù)留足夠大的存儲空間
15.8 注意信息交換引發(fā)的涌現(xiàn)效果
程序單元之間進(jìn)行信息交換的過程中星瘾,可能出現(xiàn)信息丟失,也可能新增冗余信息惧辈,這一點(diǎn)多少可以預(yù)見琳状,并成為廣為人知的安全問題。這種問題可以通過在各程序單元中檢查信息有效性得到解決盒齿,也就是用檢查輸入數(shù)據(jù)長度的方式校驗(yàn)念逞。
但即使如此,系統(tǒng)層面仍可能出現(xiàn)問題边翁。因?yàn)槌绦騿卧g進(jìn)行信息交換的過程中翎承,可能引發(fā)涌現(xiàn)性。涌現(xiàn)性指的是能夠引起意想不到的效果的性質(zhì)符匾,是復(fù)雜系統(tǒng)相關(guān)研究領(lǐng)域非常常見的詞匯叨咖。程序單元之間通過交換包括數(shù)據(jù)、文字消息在內(nèi)的信息形式聯(lián)系在一起,之后甸各,其組成的系統(tǒng)單元或上層系統(tǒng)都具有復(fù)雜系統(tǒng)相似的特性仰剿。
那么如何預(yù)防這種涌現(xiàn)性現(xiàn)象引起的問題呢?目前還沒有可行的對策痴晦,但存在一種沿用至今的解決方式南吮,即系統(tǒng)層面的綜合測試方法。例如誊酌,將包含10各相互聯(lián)系的程序單元稱為綜合系統(tǒng)部凑,首先在這一層級進(jìn)行綜合測試;然后將這種系統(tǒng)聚集為整個軟件系統(tǒng)碧浊,在該層級再次進(jìn)行綜合測試涂邀;之后將其應(yīng)用于實(shí)際業(yè)務(wù),在人工交互階段再次進(jìn)行嚴(yán)格的綜合測試箱锐。以這樣嚴(yán)格的綜合測試為基礎(chǔ)比勉,可以在一定程度上發(fā)現(xiàn)并預(yù)防涌現(xiàn)性現(xiàn)象,但這要求在測試過程中投入與軟件開發(fā)過程同樣多的資源驹止。