2007年2月8日 星期四

寫C程式,請勿硬幹

人之力有其窮也。
所以不要想所有的東西都自己生,能夠找工具就先用工具吧!當然,如果用工具比不用還麻煩的話,自然也要爽快地放棄,自己生。不過,面對的問題已經複雜到這種程度的話,恐怕也不是一個人能夠應付的程度,你需要的是一個團隊。
不過這邊說的是,可以輔助開發小程式或是製作原型的工具。首先編譯器本身的建議不妨一聽,所以像是用gcc的話就可以用-Wall參數,聽聽他的忠告,其實常常可以避免你做一些笨事情。更進階地,使用lint工具(例如Splint)給你更多的建議,但是有時候他會囉唆一些多餘的事情,如果你確定你就是要做這個罕見的操作,那麼那些多餘的建議聽聽就好,不用凡事依著他。然後程式要記得維持清晰明瞭的排版,這部分你最好花點心思自己維護,雖然不會影響程式的執行結果,可是每當你要改版或除錯的時候,你就會感激自己當時多花的這點心力。也是有幫助排版的工具啦,例如有名的indent,不過這些工具時零時不靈,有時候他工作的很好,這時候你就謝天謝地,但有時候他反而會把程式碼弄得更糟糕,反而更難閱讀。不過,通常發生indent搞砸的時候,原本寫code的人也要負一半的責任,因為導致indent誤判的原因常出自於原本的程式碼太過於畸形。
程式難免遇上意外,遇到意外要記得處理,起不要把鍋子蓋起來就以為沒事,晚點湯汁連鍋蓋一起炸飛,整個廚房就毀了。所以,請記得檢查每個function的傳回值,除非你本來就是設計目的就是要忽略其結果。除了傳回值之外,很多function還會在發生錯誤的時候設定全域變數errno,請參考每個function的手冊和errno.h對於各種意外做出處理。另外,自己定義的function也要跟隨著標準函式庫的風格,傳回適當的傳回值,並依據情形適時地設定與回存errno。然後,雖然這年頭「結構化程式設計」已經成為金科玉律,換句話說就是叫你不要用goto,但是凡規則必有例外,規矩之外還要懂得變通,例如上面說的針對每種errno做出處理,如果在乘上所呼叫的function各數,將導致錯誤處理用的code大幅倍增,導致錯誤處理比真正做事的code還多,這時候可以運用goto簡化相同類型錯誤的處理。不過這邊goto的用法,不是讓你把程式便成像義大利面那樣糾結在一起,而是要做成類似 C++ or Java 中那種 try { ... } catch { ... } final {...} 哪種效果。
(待續....)

沒有留言: