高質量C與C指南林銳博士_第1頁
高質量C與C指南林銳博士_第2頁
高質量C與C指南林銳博士_第3頁
高質量C與C指南林銳博士_第4頁
高質量C與C指南林銳博士_第5頁
已閱讀5頁,還剩84頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、-. z. Back to man.ChinaUni*.net 高質量C+/C編程指南文件狀態 草稿文件 正式文件 更改正式文件文件標識:當前版本:1.0 林銳博士完成日期:2001年7月24日版本歷史版本/狀態作者參與者起止日期備注V 0.9草稿文件林銳2001-7-1至2001-7-18林銳起草V 1.0正式文件林銳2001-7-18至2001-7-24朱洪海審查V 0.9,林銳修正草稿中的錯誤目錄 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633987 前言6 HYPERLINK man.chinauni*.net

2、/develop/c&c+/c/c.htm l _Toc520633988 第1章文件構造11 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633989 1.1 和版本的聲明11 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633990 1.2 頭文件的構造12 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633991 1.3 定義文件的構造13 HYPERLINK man.chi

3、nauni*.net/develop/c&c+/c/c.htm l _Toc520633992 1.4 頭文件的作用13 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633993 1.5 目錄構造14 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633994 第2章程序的版式15 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633995 2.1 空行15 HYPERLINK man

4、.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633996 2.2 代碼行16 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633997 2.3 代碼行的空格17 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633998 2.4 對齊18 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520633999 2.5 長行拆分19 HYPERLINK

5、man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634000 2.6 修飾符的位置19 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634001 2.7 注釋20 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634002 2.8 類的版式21 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634003 第3章命名規則22 HYPERLI

6、NK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634004 3.1 共性規則22 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634005 3.2 簡單的Windows應用程序命名規則23 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634006 3.3 簡單的Uni*應用程序命名規則25 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _To

7、c520634007 第4章表達式和根本語句26 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634008 4.1 運算符的優先級26 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634009 4.2 復合表達式27 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634010 4.3 if 語句27 HYPERLINK man.chinauni*.net/develop/c&c+/c

8、/c.htm l _Toc520634011 4.4 循環語句的效率29 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634012 4.5 for 語句的循環控制變量30 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634013 4.6 switch語句30 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634014 4.7 goto語句31 HYPERLINK man.chinau

9、ni*.net/develop/c&c+/c/c.htm l _Toc520634015 第5章常量33 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634016 5.1 為什么需要常量33 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634017 5.2 const 與 #define的比擬33 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634018 5.3 常量定義規則33

10、HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634019 5.4 類中的常量34 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634020 第6章函數設計36 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634021 6.1 參數的規則36 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634022 6.2 返回

11、值的規則37 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634023 6.3 函數部實現的規則39 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634024 6.4 其它建議40 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634025 6.5 使用斷言41 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634

12、026 6.6 引用與指針的比擬42 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634027 第7章存管理44 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634028 7.1存分配方式44 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634029 7.2常見的存錯誤及其對策44 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l

13、 _Toc520634030 7.3指針與數組的比照45HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634031 7.4指針參數是如何傳遞存的?47 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634032 7.5 free和delete把指針怎么啦?50 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634033 7.6 動態存會被自動釋放嗎?50 HYPERLINK man.ch

14、inauni*.net/develop/c&c+/c/c.htm l _Toc520634034 7.7 杜絕野指針51 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634035 7.8 有了malloc/free為什么還要new/delete ?52 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634036 7.9 存耗盡怎么辦?53 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520

15、634037 7.10 malloc/free 的使用要點54 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634038 7.11 new/delete 的使用要點55 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634039 7.12 一些心得體會56 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634040 第8章 C+函數的高級特性57 HYPERLINK man.china

16、uni*.net/develop/c&c+/c/c.htm l _Toc520634041 8.1 函數重載的概念57 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634042 8.2 成員函數的重載、覆蓋與隱藏60 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634043 8.3 參數的缺省值63 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634044 8.4 運算符重載64

17、HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634045 8.5 函數聯65 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634046 8.6 一些心得體會68 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634047 第9章類的構造函數、析構函數與賦值函數69 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc52063

18、4048 9.1 構造函數與析構函數的起源69 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634049 9.2 構造函數的初始化表70 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634050 9.3 構造和析構的次序72 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634051 9.4 例如:類String的構造函數與析構函數72 HYPERLINK man.chinauni*

19、.net/develop/c&c+/c/c.htm l _Toc520634052 9.5 不要輕視拷貝構造函數與賦值函數73 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634053 9.6 例如:類String的拷貝構造函數與賦值函數73 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634054 9.7 偷懶的方法處理拷貝構造函數與賦值函數75 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _

20、Toc520634055 9.8 如何在派生類中實現類的根本函數75 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634056 9.9 一些心得體會77 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634057 第10章類的繼承與組合78 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634058 10.1 繼承78 HYPERLINK man.chinauni*.net/devel

21、op/c&c+/c/c.htm l _Toc520634059 10.2 組合80 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634060 第11章其它編程經歷82 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634061 11.1 使用const提高函數的強健性82 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634062 11.2 提高程序的效率84 HYPERLINK ma

22、n.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634063 11.3 一些有益的建議85 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634064 參考文獻87 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634065 附錄A :C+/C代碼審查表88 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634066 附錄B :C+/C試題93

23、 HYPERLINK man.chinauni*.net/develop/c&c+/c/c.htm l _Toc520634067 附錄C :C+/C試題的答案與評分標準97前言軟件質量是被大多數程序員掛在嘴上而不是放在心上的東西!除了完全外行和真正的編程高手外,初讀本書,你最先的感受將是驚慌:哇!我以前捏造的C+/C程序怎么會有則多的毛病?別難過,作者只不過比你早幾年、多幾次驚慌而已。請花一兩個小時認真閱讀這本百頁經書,你將會獲益匪淺,這是前面N-1個讀者的建議。一、編程老手與高手的誤區自從計算機問世以來,程序設計就成了令人羨慕的職業,程序員在受人寵愛之后容易開展成為毛病特多卻常能自我臭美的

24、群體。如今在Internet上流傳的真正的程序員據說是這樣的:(1)真正的程序員沒有進度表,只有討好領導的馬屁精才有進度表,真正的程序員會讓領導提心吊膽。(2)真正的程序員不寫使用說明書,用戶應當自己去猜測程序的功能。(3)真正的程序員幾乎不寫代碼的注釋,如果注釋很難寫,它理所當然也很難讀。(4)真正的程序員不畫流程圖,原始人和文盲才會干這事。(5)真正的程序員不看參考手冊,新手和膽小鬼才會看。(6)真正的程序員不寫文檔也不需要文檔,只有看不懂程序的笨蛋才用文檔。(7)真正的程序員認為自己比用戶更明白用戶需要什么。(8)真正的程序員不承受團隊開發的理念,除非他自己是頭頭。(9)真正的程序員的程

25、序不會在第一次就正確運行,但是他們愿意守著機器進展假設干個30小時的調試改錯。(10)真正的程序員不會在上午9:00到下午5:00之間工作,如果你看到他在上午9:00工作,這說明他從昨晚一直干到現在。具備上述特征越多,越顯得水平高,資格老。所以別奇怪,程序員的很多缺點竟然可以被當作優點來欣賞。就象在武俠小說中,那些獨來獨往、不受約束且帶點邪氣的高手最令人崇拜。我曾經也這樣信奉,并且希望自己成為那樣的真正的程序員,結果沒有得到好下場。我從讀大學到博士畢業十年來一直勤奮好學,累計編寫了數十萬行C+/C代碼。有這樣的苦勞和疲勞,我應該稱得上是編程老手了吧?我開發的軟件都與科研相關集成電路CAD和3D

26、圖形學領域,動輒數萬行程序,技術復雜,難度頗高。這些軟件頻頻獲獎,有一個軟件獲得首屆中國大學生電腦大賽軟件展示一等獎。在1995年開發的一套圖形軟件庫到2000年還有人買。羅列出這些業績,可以說明我算得上是編程高手了吧?可惜這種個人感覺不等于事實。讀博期間我曾用一年時間開發了一個近10萬行C+代碼的3D圖形軟件產品,我心得意外表謙虛地向一位真正的軟件高手請教。他雖然從未涉足過3D圖形領域,卻在幾十分鐘指出該軟件多處重大設計錯誤。讓人感覺那套軟件是用紙糊的華美衣服,扯一下掉一塊,戳一下破個洞。我目瞪口呆地意識到這套軟件毫無實用價值,一年的心血白化了,并且害死了自己的軟件公司。人的頓悟通常發生在最

27、心痛的時刻,在沮喪和心痛之后,我作了深刻反省,面壁半年,重新溫習軟件設計的根底知識。補修功之后,又覺得腰板硬了起來。博士畢業前半年,我曾到微軟中國研究院找工作,承受微軟公司一位資深軟件工程師的面試。他讓我寫函數strcpy的代碼。太容易了吧?錯!這么一個小不點的函數,他從三個方面考察:1編程風格;2出錯處理;3算法復雜度分析用于提高性能。在大學里從來沒有人如此嚴格地考察過我的程序。我化了半個小時,修改了數次,他還不盡滿意,讓我回家好好琢磨。我精神抖擻地進考場,大汗淋漓地出考場。這高手當得也太窩囊了。我又好好地反省了一次。我把反省后的心得體會寫成文章放在網上傳閱,引起了不少軟件開發人員的共鳴。我

28、因此有幸和國產大型IT企業如華為、貝爾、中興等公司的同志們廣泛交流。大家認為提高質量與生產率是軟件工程要解決的核心問題。高質量程序設計是非常重要的環節,畢竟軟件是靠編程來實現的。我們心目中的老手們和高手們能否編寫出高質量的程序來?不見得都能!就我的經歷與閱歷來看,國大學的計算機教育壓根就沒有灌輸高質量程序設計的觀念,教師們和學生們也很少自覺關心軟件的質量。勤奮好學的程序員長期在低質量的程序堆中滾爬,吃盡苦頭之后才有一些心得體會,長進極慢,我就是一例。現在國IT企業擁有學士、碩士、博士文憑的軟件開發人員比比皆是,但他們在承受大學教育時就先天缺乏,豈能一到企業就突然實現質的飛躍。試問有多少軟件開發

29、人員對正確性、強健性、可靠性、效率、易用性、可讀性可理解性、可擴展性、可復用性、兼容性、可移植性等質量屬性了如指掌?并且能在實踐中運用自如?。高質量可不是干活小心點就能實現的!我們有充分的理由疑慮:1編程老手可能會長期用隱含錯誤的方式編程習慣成自然,發現毛病后都不愿相信那是真的!2編程高手可以在*一領域寫出極有水平的代碼,但未必能從全局把握軟件質量的方方面面。事實證明如此。我到貝爾工作一年來,陸續面試或測試過近百名新老程序員的編程技能,質量合格率大約是10。很少有人能夠寫出完全符合質量要求的if語句,很多程序員對指針、存管理一知半解,。領導們不敢相信這是真的。我做過現場試驗:有一次部門新進14

30、名碩士生,在開歡送會之前對他們進展C+/C編程技能摸底考試。我問大家試題難不難?所有的人都答復不難。結果沒有一個人及格,有半數人得零分。競爭對手公司的朋友們也做過試驗,同樣一敗涂地。真的不是我心狠手辣或者要求過高,而是很多軟件開發人員對自己的要求不夠高。要知道華為、貝爾、中興等公司的員工素質在國IT企業中是比擬前列的,倘假設他們的編程質量都如此差的話,我們怎么敢期望中小公司拿出高質量的軟件呢?連程序都編不好,還談什么振興民族軟件產業,豈不胡扯。我打算定義編程老手和編程高手,請您別見笑。定義1:能長期穩定地編寫出高質量程序的程序員稱為編程老手。定義2:能長期穩定地編寫出高難度、高質量程序的程序員

31、稱為編程高手。根據上述定義,馬上得到第一推論:我既不是高手也算不上是老手。在寫此書前,我閱讀了不少程序設計方面的英文著作,越看越羞慚。因為發現自己連編程根本技能都未能全面掌握,頂多算是二流水平,還好意思談什么老手和高手。希望和我一樣在國土生土長的程序員朋友們能夠做到:1知錯就改;2經常溫故而知新;3堅持學習,天天向上。二、本書導讀首先請做附錄B的C+/C試題不要看答案,考察自己的編程質量終究如何。然后參照答案嚴格打分。1如果你只得了幾十分,請不要聲,也不要太難過。編程質量差往往是由于不良習慣造成的,與人的智力、能力沒有多大關系,還是有藥可救的。成績越差,可以進步的空間就越大,中國不就是在落后中

32、趕超興旺資本主義國家嗎?只要你能下決心改掉不良的編程習慣,第二次考試就能及格了。2如果你考及格了,說明你的技術根底不錯,希望你能虛心學習、不斷進步。如果你還沒有找到適宜的工作單位,不妨到貝爾試一試。3如果你考出85分以上的好成績,你有義務和資格為你所在的團隊作C+/C編程培訓。希望你能和我們多多交流、相互促進。半年前我曾經發現一顆好苗子,就把他挖到我們小組來。4如果你在沒有任何提示的情況下考了總分值,希望你能收我做你的徒弟。編程考試完畢后,請閱讀本書的正文。本書第一章至第六章主要論述C+/C編程風格。難度不高,但是細節比擬多。別小看了,提高質量就是要從這些點點滴滴做起。世上不存在最好的編程風格

33、,一切因需求而定。團隊開發講究風格一致,如果制定了大家認可的編程風格,則所有組員都要遵守。如果讀者覺得本書的編程風格比擬合你的工作,則就采用它,不要只看不做。人在小時候說話發音不準,寫字潦草,如果不改正,總有懊悔的時候。編程也是同樣道理。第七章至第十一章是專題論述,技術難度比擬高,看書時要積極思考。特別是第七章存管理,讀了并不表示懂了,懂了并不表示就能正確使用。有一位同事看了第七章后覺得野指針寫得不錯,與我切磋了一把。可是過了兩周,他告訴我,他忙了兩天追查出一個Bug,想不到又是野指針出問題,只好重讀第七章。光看本書對提高編程質量是有限的,建議大家閱讀本書的參考文獻,那些都是經典名著。如果你的

34、編程質量已經過關了,不要就此滿足。如果你想成為優秀的軟件開發人員,建議你閱讀并按照CMMI規做事,讓自己的綜合水平上升一個臺階。貝爾的員工可以向網絡應用事業部軟件工程研究小組索取CMMI有關資料,最好能參加培訓。三、聲明本書的大局部容取材于作者一年前的書籍手稿尚未出版,現整理匯編成為貝爾網絡應用事業部的一個規化文件,同時作為培訓教材。由于C+/C編程是眾所周知的技術,沒有什么可言。編程的好經歷應該大家共享,我們自己也是這么學來的。作者愿意公開本書的電子文檔。聲明如下:1讀者可以任意拷貝、修改本書的容,但不可以篡改作者及所屬單位。2未經作者許可,不得出版或大量印發本書。3如果競爭對手公司的員工得

35、到本書,請勿公開使用,以免發生糾紛。預計到2002年7月,我們將建立切合中國國情的CMMI 3級解決方案。屆時,包括本書在的約1000頁規將嚴格受控。歡送讀者對本書提出批評建議。林銳,2001年7月第1章文件構造每個C+/C程序通常分為兩個文件。一個文件用于保存程序的聲明declaration,稱為頭文件。另一個文件用于保存程序的實現implementation,稱為定義definition文件。C+/C程序的頭文件以.h為后綴,C程序的定義文件以.c為后綴,C+程序的定義文件通常以.cpp為后綴也有一些系統以.cc或.c*為后綴。1.1 和版本的聲明和版本的聲明位于頭文件和定義文件的開頭參見

36、例如1-1,主要容有:1信息。2文件名稱,標識符,摘要。3當前版本號,作者/修改者,完成日期。4版本歷史信息。/* Copyright (c) 2001,貝爾網絡應用事業部* All rights reserved.* * 文件名稱:filename.h* 文件標識:見配置管理方案書* 摘 要:簡要描述本文件的容* * 當前版本:1.1* 作 者:輸入作者或修改者名字* 完成日期:2001年7月20日* 取代版本:1.0 * 原作者 :輸入原作者或修改者名字* 完成日期:2001年5月10日*/例如1-1 和版本的聲明1.2 頭文件的構造頭文件由三局部容組成:1頭文件開頭處的和版本聲明參見例如

37、1-1。2預處理塊。3函數和類構造聲明等。假設頭文件名稱為 graphics.h,頭文件的構造參見例如1-2。【規則1-2-1】為了防止頭文件被重復引用,應當用ifndef/define/endif構造產生預處理塊。【規則1-2-2】用#include 格式來引用標準庫的頭文件編譯器將從標準庫目錄開場搜索。【規則1-2-3】用#include filename.h 格式來引用非標準庫的頭文件編譯器將從用戶的工作目錄開場搜索。【建議1-2-1】頭文件中只存放聲明而不存放定義在C+ 語法中,類的成員函數可以在聲明的同時被定義,并且自動成為聯函數。這雖然會帶來書寫上的方便,但卻造成了風格不一致,弊大

38、于利。建議將成員函數的定義與聲明分開,不管該函數體有多么小。【建議1-2-2】不提倡使用全局變量,盡量不要在頭文件中出現象e*tern int value 這類聲明。/ 和版本聲明見例如1-1,此處省略。#ifndefGRAPHICS_H/ 防止graphics.h被重復引用#defineGRAPHICS_H#include / 引用標準庫的頭文件#include myheader.h / 引用非標準庫的頭文件void Function1();/ 全局函數聲明class Bo* / 類構造聲明;#endif例如1-2 C+/C頭文件的構造1.3 定義文件的構造定義文件有三局部容:1定義文件開頭

39、處的和版本聲明參見例如1-1。2對一些頭文件的引用。3程序的實現體包括數據和代碼。假設定義文件的名稱為 graphics.cpp,定義文件的構造參見例如1-3。/ 和版本聲明見例如1-1,此處省略。#include graphics.h/ 引用頭文件/ 全局函數的實現體void Function1()/ 類成員函數的實現體void Bo*:Draw()例如1-3 C+/C定義文件的構造1.4 頭文件的作用早期的編程語言如Basic、Fortran沒有頭文件的概念,C+/C語言的初學者雖然會用使用頭文件,但常常不明其理。這里對頭文件的作用略作解釋:1通過頭文件來調用庫功能。在很多場合,源代碼不便

40、或不準向用戶公布,只要向用戶提供頭文件和二進制的庫即可。用戶只需要按照頭文件中的接口聲明來調用庫功能,而不必關心接口怎么實現的。編譯器會從庫中提取相應的代碼。2頭文件能加強類型平安檢查。如果*個接口被實現或被使用時,其方式與頭文件中的聲明不一致,編譯器就會指出錯誤,這一簡單的規則能大大減輕程序員調試、改錯的負擔。1.5 目錄構造如果一個軟件的頭文件數目比擬多如超過十個,通常應將頭文件和定義文件分別保存于不同的目錄,以便于維護。例如可將頭文件保存于include目錄,將定義文件保存于source目錄可以是多級目錄。如果*些頭文件是私有的,它不會被用戶的程序直接引用,則沒有必要公開其聲明。為了加強

41、信息隱藏,這些私有的頭文件可以和定義文件存放于同一個目錄。第2章程序的版式版式雖然不會影響程序的功能,但會影響可讀性。程序的版式追求清晰、美觀,是程序風格的重要構成因素。可以把程序的版式比喻為書法。好的書法可讓人對程序一目了然,看得興致勃勃。差的程序書法如螃蟹爬行,讓人看得索然無味,更令維護者煩惱有加。請程序員們學習程序的書法,彌補大學計算機教育的漏洞,實在很有必要。2.1 空行空行起著分隔程序段落的作用。空行得體不過多也不過少將使程序的布局更加清晰。空行不會浪費存,雖然打印含有空行的程序是會多消耗一些紙,但是值得。所以不要舍不得用空行。【規則2-1-1】在每個類聲明之后、每個函數定義完畢之后

42、都要加空行。參見例如2-1a【規則2-1-2】在一個函數體,邏揖上密切相關的語句之間不加空行,其它地方應加空行分隔。參見例如2-1b / 空行void Function1()/ 空行void Function2()/ 空行void Function3()/ 空行while (condition)statement1;/ 空行if (condition) statement2;elsestatement3;/ 空行statement4; 例如2-1(a) 函數之間的空行 例如2-1(b) 函數部的空行2.2 代碼行【規則2-2-1】一行代碼只做一件事情,如只定義一個變量,或只寫一條語句。這樣的代

43、碼容易閱讀,并且方便于寫注釋。【規則2-2-2】if、for、while、do等語句自占一行,執行語句不得緊跟其后。不管執行語句有多少都要加。這樣可以防止書寫失誤。例如2-2a為風格良好的代碼行,例如2-2b為風格不良的代碼行。int width;/ 寬度int height;/ 高度int depth;/ 深度int width, height, depth; / 寬度高度深度* = a + b;y = c + d;z = e + f;* a + b; y = c + d; z = e + f;if (width height) dosomething();if (width =、=、+、*

44、、%、&、|、這類操作符前后不加空格。【建議2-3-1】對于表達式比擬長的for語句和if語句,為了緊湊起見可以適當地去掉一些空格,如for (i=0; i10; i+)和if (a=b) & (c= 2000) / 良好的風格if(year=2000) / 不良的風格if (a=b) & (c=b&c=d) / 不良的風格for (i=0; i10; i+) / 良好的風格for(i=0;i10;i+) / 不良的風格for (i = 0; I 10; i +) / 過多的空格* = a b a : b; / 良好的風格*=aFunction(); / 不要寫成 b - Function()

45、;例如2-3 代碼行的空格2.4 對齊【規則2-4-1】程序的分界符和應獨占一行并且位于同一列,同時與引用它們的語句左對齊。【規則2-4-2】 之的代碼塊在右邊數格處左對齊。例如2-4a為風格良好的對齊,例如2-4b為風格不良的對齊。void Function(int *) / program codevoid Function(int *) / program codeif (condition) / program codeelse / program codeif (condition) / program codeelse / program codefor (initializati

46、on; condition; update) / program codefor (initialization; condition; update) / program codeWhile (condition) / program codewhile (condition) / program code如果出現嵌套的,則使用縮進對齊,如: 例如2-4(a) 風格良好的對齊 例如2-4(b) 風格不良的對齊2.5 長行拆分【規則2-5-1】代碼行最大長度宜控制在70至80個字符以。代碼行不要過長,否則眼睛看不過來,也不便于打印。【規則2-5-2】長表達式要在低優先級操作符處拆分成新行,操作

47、符放在新行之首以便突出操作符。拆分出的新行要進展適當的縮進,使排版整齊,語句可讀。if (very_longer_variable1 = very_longer_variable12)& (very_longer_variable3 = very_longer_variable14)& (very_longer_variable5 Draw();/ 類的成員函數【規則3-1-8】用正確的反義詞組命名具有互斥意義的變量或相反動作的函數等。例如:intminValue;intma*Value;intSetValue();intGetValue();【建議3-1-1】盡量防止名字中出現數字編號,如V

48、alue1,Value2等,除非邏輯上確實需要編號。這是為了防止程序員偷懶,不肯為命名動腦筋而導致產生無意義的名字因為用數字編號最省事。3.2 簡單的Windows應用程序命名規則作者對匈牙利命名規則做了合理的簡化,下述的命名規則簡單易用,比擬適合于Windows應用軟件的開發。【規則3-2-1】類名和函數名用大寫字母開頭的單詞組合而成。例如:class Node;/ 類名class LeafNode;/ 類名void Draw(void);/ 函數名void SetValue(int value);/ 函數名【規則3-2-2】變量和參數用小寫字母開頭的單詞組合而成。例如:BOOL flag;

49、int drawMode;【規則3-2-3】常量全用大寫的字母,用下劃線分割單詞。例如:const int MA* = 100;const int MA*_LENGTH = 100;【規則3-2-4】靜態變量加前綴s_表示static。例如:void Init()static int s_initValue;/ 靜態變量【規則3-2-5】如果不得已需要全局變量,則使全局變量加前綴g_表示global。例如:int g_howManyPeople;/ 全局變量int g_howMuchMoney;/ 全局變量【規則3-2-6】類的數據成員加前綴m_表示member,這樣可以防止數據成員與成員函數

50、的參數同名。例如:void Object:SetValue(int width, int height)m_width = width;m_height = height;【規則3-2-7】為了防止*一軟件庫中的一些標識符和其它軟件庫中的沖突,可以為各種標識符加上能反映軟件性質的前綴。例如三維圖形標準OpenGL的所有庫函數均以gl開頭,所有常量或宏定義均以GL開頭。3.3 簡單的Uni*應用程序命名規則第4章表達式和根本語句讀者可能疑心:連if、for、while、goto、switch這樣簡單的東西也要探討編程風格,是不是小題大做?我真的覺察很多程序員用隱含錯誤的方式寫表達式和根本語句,我

51、自己也犯過類似的錯誤。表達式和語句都屬于C+/C的短語構造語法。它們看似簡單,但使用時隱患比擬多。本章歸納了正確使用表達式和語句的一些規則與建議。4.1 運算符的優先級C+/C語言的運算符有數十個,運算符的優先級與結合律如表4-1所示。注意一元運算符 + - * 的優先級高于對應的二元運算符。優先級運算符結合律從高到低排列( ) - .從左至右! + - 類型 sizeof+ - * &從右至左* / %從左至右+ -從左至右從左至右 =從左至右= !=從左至右&從左至右從左至右|從左至右&從左至右|從右至左:從右至左= += -= *= /= %= &= =|= =從左至右表4-1 運算符的

52、優先級與結合律【規則4-1-1】如果代碼行中的運算符比擬多,用括號確定表達式的操作順序,防止使用默認的優先級。由于將表4-1熟記是比擬困難的,為了防止產生歧義并提高可讀性,應當用括號確定表達式的操作順序。例如:word = (high = b & c d & c + f = g + h ;/ 復合表達式過于復雜【規則4-2-2】不要有多用途的復合表達式。例如:d = (a = b + c) + r ; 該表達式既求a值又求d值。應該拆分為兩個獨立的語句:a = b + c;d = a + r;【規則4-2-3】不要把程序中的復合表達式與真正的數學表達式混淆。例如:if (a b c)/ a b

53、 c是數學表達式而不是程序表達式并不表示if (ab) & (bc)而是成了令人費解的if ( (ab)=或=-EPSINON) & (*=EPSINON)其中EPSINON是允許的誤差即精度。4.3.4 指針變量與零值比擬【規則4-3-4】應當將指針變量用=或!=與NULL比擬。指針變量的零值是空記為NULL。盡管NULL的值與0一樣,但是兩者意義不同。假設指針變量的名字為p,它與零值比擬的標準if語句如下:if (p = NULL)/ p與NULL顯式比擬,強調p是指針變量if (p != NULL)不要寫成if (p = 0) / 容易讓人誤解p是整型變量if (p != 0) 或者if

54、 (p)/ 容易讓人誤解p是布爾變量if (!p)4.3.5 對if語句的補充說明有時候我們可能會看到 if (NULL = p) 這樣乖僻的格式。不是程序寫錯了,是程序員為了防止將 if (p = NULL) 誤寫成 if (p = NULL),而有意把p和NULL顛倒。編譯器認為 if (p = NULL) 是合法的,但是會指出 if (NULL = p)是錯誤的,因為NULL不能被賦值。程序中有時會遇到if/else/return的組合,應該將如下不良風格的程序if (condition)return *;return y;改寫為if (condition)return *;elsere

55、turn y;或者改寫成更加簡練的 return (condition * : y);4.4 循環語句的效率C+/C循環語句中,for語句使用頻率最高,while語句其次,do語句很少用。本節重點論述循環體的效率。提高循環體效率的根本方法是降低循環體的復雜性。【建議4-4-1】在多重循環中,如果有可能,應當將最長的循環放在最層,最短的循環放在最外層,以減少CPU跨切循環層的次數。例如例如4-4(b)的效率比例如4-4(a)的高。for (row=0; row100; row+)for ( col=0; col5; col+ )sum = sum + arowcol;for (col=0; co

56、l5; col+ )for (row=0; row100; row+) sum = sum + arowcol;例如4-4(a) 低效率:長循環在最外層 例如4-4(b) 高效率:長循環在最層【建議4-4-2】如果循環體存在邏輯判斷,并且循環次數很大,宜將邏輯判斷移到循環體的外面。例如4-4(c)的程序比例如4-4(d)多執行了N-1次邏輯判斷。并且由于前者老要進展邏輯判斷,打斷了循環流水線作業,使得編譯器不能對循環進展優化處理,降低了效率。如果N非常大,最好采用例如4-4(d)的寫法,可以提高效率。如果N非常小,兩者效率差異并不明顯,采用例如4-4(c)的寫法比擬好,因為程序更加簡潔。for

57、 (i=0; iN; i+)if (condition) DoSomething();else DoOtherthing();if (condition)for (i=0; iN; i+) DoSomething();else for (i=0; iN; i+) DoOtherthing();表4-4(c) 效率低但程序簡潔 表4-4(d) 效率高但程序不簡潔4.5 for 語句的循環控制變量【規則4-5-1】不可在for 循環體修改循環變量,防止for 循環失去控制。【建議4-5-1】建議for語句的循環控制變量的取值采用半開半閉區間寫法。例如4-5(a)中的*值屬于半開半閉區間0 = *

58、N,起點到終點的間隔為N,循環次數為N。例如4-5(b)中的*值屬于閉區間0 = * = N-1,起點到終點的間隔為N-1,循環次數為N。相比之下,例如4-5(a)的寫法更加直觀,盡管兩者的功能是一樣的。for (int *=0; *N; *+)for (int *=0; * 0 )*pbTo + = *pbFrom + ;return pvTo;例如6-5 復制不重疊的存塊assert不是一個倉促拼湊起來的宏。為了不在程序的Debug版本和Release版本引起差異,assert不應該產生任何副作用。所以assert不是函數,而是宏。程序員可以把assert看成一個在任何系統狀態下都可以平安

59、使用的無害測試手段。如果程序在assert處終止了,并不是說含有該assert的函數有錯誤,而是調用者出了過失,assert可以幫助我們找到發生錯誤的原因。很少有比跟蹤到程序的斷言,卻不知道該斷言的作用更讓人沮喪的事了。你化了很多時間,不是為了排除錯誤,而只是為了弄清楚這個錯誤到底是什么。有的時候,程序員偶爾還會設計出有錯誤的斷言。所以如果搞不清楚斷言檢查的是什么,就很難判斷錯誤是出現在程序中,還是出現在斷言中。幸運的是這個問題很好解決,只要加上清晰的注釋即可。這本是顯而易見的事情,可是很少有程序員這樣做。這好比一個人在森林里,看到樹上釘著一塊危險的大牌子。但危險到底是什么?樹要倒?有廢井?有

60、野獸?除非告訴人們危險是什么,否則這個警告牌難以起到積極有效的作用。難以理解的斷言常常被程序員忽略,甚至被刪除。Maguire, p8-p30【規則6-5-1】使用斷言捕捉不應該發生的非法情況。不要混淆非法情況與錯誤情況之間的區別,后者是必然存在的并且是一定要作出處理的。【規則6-5-2】在函數的入口處,使用斷言檢查參數的有效性合法性。【建議6-5-1】在編寫函數時,要進展反復的考察,并且自問:我打算做哪些假定?一旦確定了的假定,就要使用斷言對假定進展檢查。【建議6-5-2】一般教科書都鼓勵程序員們進展防錯設計,但要記住這種編程風格可能會隱瞞錯誤。當進展防錯設計時,如果不可能發生的事情確實發生

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論