完美程式设计指南

完美程式设计指南

ID:12618842

大小:113.50 KB

页数:35页

时间:2018-07-18

完美程式设计指南_第1页
完美程式设计指南_第2页
完美程式设计指南_第3页
完美程式设计指南_第4页
完美程式设计指南_第5页
资源描述:

《完美程式设计指南》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、完美程式設計指南用編譯器來自動抓蟲是很棒的事,但是我打賭,如果你檢查過程式專案中抓到的那些臭蟲,你會發現編譯器只抓到了其中一小部份。我打賭,如果你將臭蟲隔離開來,你會發現程式現在大概會執行得很正常。還記得下面這個第一章中的程式片段嗎?strCopy=memcpy(malloc(length),str,length);這程式在任何狀態下都會正常運作,除非malloc配置記憶體失敗。當記憶體配置失敗時,malloc會傳給memcpy一個NULL指標,而memcpy沒辦法處理這種狀況。如果你夠幸運,在你推出這個產品之前,你就會看到這個系統當掉;否則,你的顧客也會碰到程

2、式當掉的災難。1編譯器抓不到像這樣的錯誤,也沒有編譯器能夠幫你抓到演算法中的錯誤,檢驗你的假設,或在資料傳遞時進行一般性的查核工作。找尋這種錯誤是困難的事情,需要一名有技巧的程式員或測試人員整個把它們挖出來。不過要自動找到這類錯誤是容易的事情,如果你知道怎麼做的話。兩個版本的故事讓我們更進一步,看看你該怎麼抓到像上頭那個memcpy敘述中的錯誤。最簡單的解決辦法就是讓memcpy檢查NULL指標是不是被當成了參數使用,如果是,就丟個錯誤訊息出來,並中止程式執行。底下就是我們自己改良過的新版memcpy:/*複製一段非重疊的記憶體。*/void*memcpy(vo

3、id*pvTo,void*pvFrom,size_tsize){byte*pbTo=(byte*)pvTo;byte*pbFrom=(byte*)pvFrom;if(pvTo==NULL

4、

5、pvFrom==NULL){fprintf(stderr,"Badargsinmemcpy");abort();}while(size->0)*pbTo++=*pbFrom++;return(pvTo);}使用這個函式,沒人會漏掉將NULL指標傳給memcpy函式的錯誤。剩下來的問題只是這種測試方式把程式變大而且變慢了些。如果你覺得這是另一個有醫比沒醫更糟糕的狀況,我想你

6、是對的;這種測試方式並不實用。這時C語言前置處理器就派上用場了。如果你有兩個版本的程式,結果會怎樣?一個發行版本又快又好,另一個包含額外檢查碼的版本則又胖又慢。你可以在同一份原始碼中維護兩個版本的程式,只要使用C語言的前置處理器來條件性的加入或移除檢查程式碼就好了。2舉例來說,你可以讓NULL指標的測試只有在DEBUG符號被定義時才會被編譯到:void*memcpy(void*pvTo,void*pvFrom,size_tsize){byte*pbTo=(bytea)pvTo;byte*pbFrom=(bytea)pvFrom;#ifdefDEBUGif(pvT

7、o==NULL

8、

9、pvFrom==NULL){fprintf(stderr,"Badargsinmemcpy");abort();}#endifwhile(size->0)*pbTo++=*pbFrom++;return(pvTo);}這裡的構想是同時維護你程式的除錯跟非除錯版(就是用來公開發行的版本)。在寫程式時,你編譯出除錯版的程式,在加入新功能時用它來自動除錯。之後,當你準備推出產品時,重新編譯一個公開發行版,把它打包好,就可以送去給經銷商了。當然,你不會真的想等到推出產品的最後一刻才執行你的程式-那太糟糕了。在開發過程中,你就應該讓程式的除錯版本能跑

10、得動了,主要的理由在於,如我們將在本章跟下一章中看到的,執行除錯版本的程式能大幅降低發展程式所需要的時間。如果每個函式都有著最低限度的錯誤檢查跟測試不應該發生的狀況,想像一下你的程式將會多麼穩固啊。技巧,當然就是確保除錯碼是最後產品中完全不必要的額外程式碼。你也許明白了,不過稍後我還會在提一下。同時維護你程式的發行跟除錯版本。除錯檢查巨集ASSERT的說明3坦白說,,我在memcpy裡頭放的除錯碼看來很差而且佔據了整個函式的空間。我知道不多程式員忍受得了這種東西,即使這麼做的理由很好。所以有些精明的程式員就把這些除錯碼全用個巨集隱藏起來,把它稱作assert除錯

11、檢查巨集,全定義在ANSI的assert.h表頭檔裡頭。assert只是我們之前看到那些#ifdef程式碼的重新包裝版而已,不過當你使用巨集時,它只需要用到一行原始碼的空間而已:assert只是個除錯專用的巨集,會在參數為false時中止程式的執行。在上頭的程式中,如果兩個指標之中有一個是NULL,assert就會發生效用。assert並不是一個匆匆拼湊而成的巨集;你必須小心定義它,避免在除錯版跟發行版的程式中出現重大差異。assert不應該干擾到記憶體內容,不應該初始化原先未初始化的記憶體,也不應該產生任何副作用,程式在除錯時產生的結果得跟發行版的一模一樣。所

12、以assert才被寫成巨

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。