CC++高質(zhì)量編程綜合指南_第1頁
CC++高質(zhì)量編程綜合指南_第2頁
CC++高質(zhì)量編程綜合指南_第3頁
CC++高質(zhì)量編程綜合指南_第4頁
CC++高質(zhì)量編程綜合指南_第5頁
已閱讀5頁,還剩189頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、 HYPERLINK 高質(zhì)量C+/C編程指南南文件狀態(tài) 草稿稿文件 正式文文件 更改改正式文件文件標(biāo)識:當(dāng)前版本:1.0作 者:林銳 博士完成日期:2001年7月月24日前 言軟件質(zhì)量是被被大多數(shù)程序序員掛在嘴上上而不是放在在心上的東西西!除了完全外行行和真正的編編程高手外,初初讀本書,你你最先的感受受將是驚慌:“哇!我以前捏捏造的C+/C程序怎怎么會有那么么多的毛?。俊眲e難過,作者者只不過比你你早幾年、多多幾次驚慌而而已。請花一兩個小小時認(rèn)真閱讀讀這本百頁經(jīng)經(jīng)書,你將會會獲益匪淺,這這是前面N-1個讀者的的建議。一、編程老手與與高手的誤區(qū)區(qū)自從計算機問世世以來,程序序設(shè)計就成了了令人羨慕的的

2、職業(yè),程序序員在受人寵寵愛之后容易易發(fā)展成為毛毛病特多卻常常能自我臭美美的群體。如今在Inteernet上上流傳的“真正”的程序員據(jù)據(jù)說是這樣的的:真正的程序員沒沒有進度表,只只有討好領(lǐng)導(dǎo)導(dǎo)的馬屁精才才有進度表,真真正的程序員員會讓領(lǐng)導(dǎo)提提心吊膽。真正的程序員不不寫使用說明明書,用戶應(yīng)應(yīng)當(dāng)自己去猜猜想程序的功功能。真正的程序員幾幾乎不寫代碼碼的注釋,如如果注釋很難難寫,它理所所當(dāng)然也很難難讀。真正的程序員不不畫流程圖,原原始人和文盲盲才會干這事事。真正的程序員不不看參考手冊冊,新手和膽膽小鬼才會看看。真正的程序員不不寫文檔也不不需要文檔,只只有看不懂程程序的笨蛋才才用文檔。真正的程序員認(rèn)認(rèn)為自

3、己比用用戶更明白用用戶需要什么么。真正的程序員不不接受團隊開開發(fā)的理念,除除非他自己是是頭頭。真正的程序員的的程序不會在在第一次就正正確運行,但但是他們愿意意守著機器進進行若干個330小時的調(diào)調(diào)試改錯。真正的程序員不不會在上午99:00到下午午5:00之間工工作,如果你你看到他在上上午9:00工作,這這表明他從昨昨晚一直干到到現(xiàn)在。具備上述特征越越多,越顯得得水平高,資資格老。所以以別奇怪,程程序員的很多多缺點竟然可可以被當(dāng)作優(yōu)優(yōu)點來欣賞。就就象在武俠小小說中,那些些獨來獨往、不不受約束且?guī)c邪氣的高高手最令人崇崇拜。我曾經(jīng)經(jīng)也這樣信奉奉,并且希望望自己成為那那樣的“真正”的程序員,結(jié)結(jié)果沒

4、有得到到好下場。我從讀大學(xué)到博博士畢業(yè)十年年來一直勤奮奮好學(xué),累計計編寫了數(shù)十十萬行C+/C代碼。有有這樣的苦勞勞和疲勞,我我應(yīng)該稱得上上是編程老手手了吧?我開發(fā)的軟件都都與科研相關(guān)關(guān)(集成電路路CAD和33D圖形學(xué)領(lǐng)領(lǐng)域),動輒輒數(shù)萬行程序序,技術(shù)復(fù)雜雜,難度頗高高。這些軟件件頻頻獲獎,有有一個軟件獲獲得首屆中國國大學(xué)生電腦腦大賽軟件展展示一等獎。在在1995年開開發(fā)的一套圖圖形軟件庫到到2000年年還有人買。羅羅列出這些“業(yè)績”,可以說明明我算得上是是編程高手了了吧?可惜這種個人感感覺不等于事事實。讀博期間我曾用用一年時間開開發(fā)了一個近近10萬行CC+代碼的的3D圖形軟軟件產(chǎn)品,我我內(nèi)心得

5、意表表面謙虛地向向一位真正的的軟件高手請請教。他雖然然從未涉足過過3D圖形領(lǐng)領(lǐng)域,卻在幾幾十分鐘內(nèi)指指出該軟件多多處重大設(shè)計計錯誤。讓人人感覺那套軟軟件是用紙糊糊的華麗衣服服,扯一下掉掉一塊,戳一一下破個洞。我我目瞪口呆地地意識到這套套軟件毫無實實用價值,一一年的心血白白化了,并且且害死了自己己的軟件公司司。人的頓悟通常發(fā)發(fā)生在最心痛痛的時刻,在在沮喪和心痛痛之后,我作作了深刻反省省,“面壁”半年,重新新溫習(xí)軟件設(shè)設(shè)計的基礎(chǔ)知知識。補修“內(nèi)功”之后,又覺覺得腰板硬了了起來。博士士畢業(yè)前半年年,我曾到微微軟中國研究究院找工作,接接受微軟公司司一位資深軟軟件工程師的的面試。他讓讓我寫函數(shù)sstrc

6、pyy的代碼。太容易了吧?錯!這么一個小不點點的函數(shù),他他從三個方面面考查:(1)編程風(fēng)格格;(2)出錯處理理;(3)算法復(fù)雜雜度分析(用用于提高性能能)。在大學(xué)里從來沒沒有人如此嚴(yán)嚴(yán)格地考查過過我的程序。我我化了半個小小時,修改了了數(shù)次,他還還不盡滿意,讓讓我回家好好好琢磨。我精精神抖擻地進進“考場”,大汗淋漓漓地出“考場”。這“高手”當(dāng)?shù)靡蔡C窩囊了。我又又好好地反省省了一次。我把反省后的心心得體會寫成成文章放在網(wǎng)網(wǎng)上傳閱,引引起了不少軟軟件開發(fā)人員員的共鳴。我我因此有幸和和國產(chǎn)大型IIT企業(yè)如華華為、上海貝貝爾、中興等等公司的同志志們廣泛交流流。大家認(rèn)為為提高質(zhì)量與與生產(chǎn)率是軟軟件工程要

7、解解決的核心問問題。高質(zhì)量量程序設(shè)計是是非常重要的的環(huán)節(jié),畢竟竟軟件是靠編編程來實現(xiàn)的的。我們心目中的老老手們和高手手們能否編寫寫出高質(zhì)量的的程序來?不見得都能!就我的經(jīng)歷與閱閱歷來看,國國內(nèi)大學(xué)的計計算機教育壓壓根就沒有灌灌輸高質(zhì)量程程序設(shè)計的觀觀念,教師們們和學(xué)生們也也很少自覺關(guān)關(guān)心軟件的質(zhì)質(zhì)量。勤奮好好學(xué)的程序員員長期在低質(zhì)質(zhì)量的程序堆堆中滾爬,吃吃盡苦頭之后后才有一些心心得體會,長長進極慢,我我就是一例?,F(xiàn)在國內(nèi)IT企企業(yè)擁有學(xué)士士、碩士、博博士文憑的軟軟件開發(fā)人員員比比皆是,但但他們在接受受大學(xué)教育時時就“先天不足”,豈能一到到企業(yè)就突然然實現(xiàn)質(zhì)的飛飛躍。試問有有多少軟件開開發(fā)人員對

8、正正確性、健壯壯性、可靠性性、效率、易易用性、可讀讀性(可理解解性)、可擴擴展性、可復(fù)復(fù)用性、兼容容性、可移植植性等質(zhì)量屬屬性了如指掌掌?并且能在在實踐中運用用自如??!案哔|(zhì)量”可不是干活活小心點就能能實現(xiàn)的!我們有充分的理理由疑慮:(1)編程老手手可能會長期期用隱含錯誤誤的方式編程程(習(xí)慣成自自然),發(fā)現(xiàn)現(xiàn)毛病后都不不愿相信那是是真的!(2)編程高手手可以在某一一領(lǐng)域?qū)懗鰳O極有水平的代代碼,但未必必能從全局把把握軟件質(zhì)量量的方方面面面。事實證明如此此。我到上海海貝爾工作一一年來,陸續(xù)續(xù)面試或測試試過近百名“新”“老”程序員的編編程技能,質(zhì)質(zhì)量合格率大大約是10。很少有人人能夠?qū)懗鐾晖耆腺|(zhì)

9、量量要求的iff語句,很多多程序員對指指針、內(nèi)存管管理一知半解解,。領(lǐng)導(dǎo)們不敢相信信這是真的。我我做過現(xiàn)場試試驗:有一次次部門新進114名碩士生生,在開歡迎迎會之前對他他們進行“C+/C編程技技能”摸底考試。我我問大家試題題難不難?所所有的人都回回答不難。結(jié)結(jié)果沒有一個個人及格,有有半數(shù)人得零零分。競爭對對手公司的朋朋友們也做過過試驗,同樣樣一敗涂地。真的不是我“心心狠手辣”或者要求過過高,而是很很多軟件開發(fā)發(fā)人員對自己己的要求不夠夠高。要知道華為、上上海貝爾、中中興等公司的的員工素質(zhì)在在國內(nèi)IT企業(yè)中是是比較前列的的,倘若他們們的編程質(zhì)量量都如此差的的話,我們怎怎么敢期望中中小公司拿出出高質(zhì)

10、量的軟軟件呢?連程程序都編不好好,還談什么么振興民族軟軟件產(chǎn)業(yè),豈豈不胡扯。我打算定義編程程老手和編程程高手,請您您別見笑。定義1:能長期期穩(wěn)定地編寫寫出高質(zhì)量程程序的程序員員稱為編程老老手。定義2:能長期期穩(wěn)定地編寫寫出高難度、高高質(zhì)量程序的的程序員稱為為編程高手。根據(jù)上述定義,馬馬上得到第一一推論:我既既不是高手也也算不上是老老手。在寫此書前,我我閱讀了不少少程序設(shè)計方方面的英文著著作,越看越越羞慚。因為為發(fā)現(xiàn)自己連連編程基本技技能都未能全全面掌握,頂頂多算是二流流水平,還好好意思談什么么老手和高手手。希望和我我一樣在國內(nèi)內(nèi)土生土長的的程序員朋友友們能夠做到到:(1)知錯就改改;(2)經(jīng)常

11、溫故故而知新;(3)堅持學(xué)習(xí)習(xí),天天向上上。二、本書導(dǎo)讀首先請做附錄錄B的C+/CC試題(不要看看答案),考考查自己的編編程質(zhì)量究竟竟如何。然后后參照答案嚴(yán)嚴(yán)格打分。(1)如果你只只得了幾十分分,請不要聲聲張,也不要要太難過。編編程質(zhì)量差往往往是由于不不良習(xí)慣造成成的,與人的的智力、能力力沒有多大關(guān)關(guān)系,還是有有藥可救的。成成績越差,可可以進步的空空間就越大,中中國不就是在在落后中趕超超發(fā)達資本主主義國家嗎?只要你能下下決心改掉不不良的編程習(xí)習(xí)慣,第二次次考試就能及及格了。(2)如果你考考及格了,表表明你的技術(shù)術(shù)基礎(chǔ)不錯,希希望你能虛心心學(xué)習(xí)、不斷斷進步。如果果你還沒有找找到合適的工工作單位,

12、不不妨到上海貝貝爾試一試。(3)如果你考考出85分以以上的好成績績,你有義務(wù)務(wù)和資格為你你所在的團隊隊作“C+/CC編程”培訓(xùn)。希望你你能和我們多多多交流、相相互促進。半半年前我曾經(jīng)經(jīng)發(fā)現(xiàn)一顆好好苗子,就把把他挖到我們們小組來。(4)如果你在在沒有任何提提示的情況下下考了滿分,希希望你能收我我做你的徒弟弟。編程考試結(jié)束束后,請閱讀讀本書的正文文。本書第一章至至第六章主要要論述C+/C編程風(fēng)風(fēng)格。難度不不高,但是細(xì)細(xì)節(jié)比較多。別別小看了,提提高質(zhì)量就是是要從這些點點點滴滴做起起。世上不存存在最好的編編程風(fēng)格,一一切因需求而而定。團隊開開發(fā)講究風(fēng)格格一致,如果果制定了大家家認(rèn)可的編程程風(fēng)格,那么么

13、所有組員都都要遵守。如如果讀者覺得得本書的編程程風(fēng)格比較合合你的工作,那那么就采用它它,不要只看看不做。人在在小時候說話話發(fā)音不準(zhǔn),寫寫字潦草,如如果不改正,總總有后悔的時時候。編程也也是同樣道理理。第七章至第十十一章是專題題論述,技術(shù)術(shù)難度比較高高,看書時要要積極思考。特特別是第七章章“內(nèi)存管理”,讀了并不不表示懂了,懂懂了并不表示示就能正確使使用。有一位位同事看了第第七章后覺得得“野指針”寫得不錯,與與我切磋了一一把??墒沁^過了兩周,他他告訴我,他他忙了兩天追追查出一個BBug,想不不到又是“野指針”出問題,只只好重讀第七七章。光看本書對提高高編程質(zhì)量是是有限的,建建議大家閱讀讀本書的參考

14、考文獻,那些些都是經(jīng)典名名著。如果你的編程程質(zhì)量已經(jīng)過過關(guān)了,不要要就此滿足。如如果你想成為為優(yōu)秀的軟件件開發(fā)人員,建建議你閱讀并并按照CMMMI規(guī)范做事事,讓自己的的綜合水平上上升一個臺階階。上海貝爾爾的員工可以以向網(wǎng)絡(luò)應(yīng)用用事業(yè)部軟件件工程研究小小組索取CMMMI有關(guān)資資料,最好能能參加培訓(xùn)。三、版權(quán)聲明本書的大部分分內(nèi)容取材于于作者一年前前的書籍手稿稿(尚未出版版),現(xiàn)整理理匯編成為上上海貝爾網(wǎng)絡(luò)絡(luò)應(yīng)用事業(yè)部部的一個規(guī)范范化文件,同同時作為培訓(xùn)訓(xùn)教材。由于C+/C編程是眾眾所周知的技技術(shù),沒有秘秘密可言。編編程的好經(jīng)驗驗應(yīng)該大家共共享,我們自自己也是這么么學(xué)來的。作作者愿意公開開本書的電

15、子子文檔。版權(quán)聲明如下下:(1)讀者可以以任意拷貝、修修改本書的內(nèi)內(nèi)容,但不可可以篡改作者者及所屬單位位。(2)未經(jīng)作者者許可,不得得出版或大量量印發(fā)本書。(3)如果競爭爭對手公司的的員工得到本本書,請勿公公開使用,以以免發(fā)生糾紛紛。預(yù)計到20002年7月,我我們將建立切切合中國國情情的CMMII 3級解決決方案。屆時時,包括本書書在內(nèi)的約11000頁規(guī)規(guī)范將嚴(yán)格受受控。歡迎讀者對本本書提出批評評建議。林銳,20011年7月第1章 文件結(jié)結(jié)構(gòu)每個C+/CC程序通常分分為兩個文件件。一個文件件用于保存程程序的聲明(ddeclarrationn),稱為頭頭文件。另一一個文件用于于保存程序的的實現(xiàn)(

16、immplemeentatiion),稱稱為定義(ddefiniition)文文件。C+/C程序序的頭文件以以“.h”為后綴,CC程序的定義義文件以“.c”為后綴,CC+程序的的定義文件通通常以“.cpp”為后綴(也也有一些系統(tǒng)統(tǒng)以“.cc”或“.cxx”為后綴)。1.1 版權(quán)和和版本的聲明明版權(quán)和版本的聲聲明位于頭文文件和定義文文件的開頭(參參見示例1-1),主要要內(nèi)容有:(1)版權(quán)信息息。(2)文件名稱稱,標(biāo)識符,摘摘要。(3)當(dāng)前版本本號,作者/修改者,完完成日期。(4)版本歷史史信息。/* Copyrright (c) 22001,上海貝爾有有限公司網(wǎng)絡(luò)絡(luò)應(yīng)用事業(yè)部部* All rri

17、ghtss reseerved.* * 文件名稱:* 文件標(biāo)識:見配置管理計計劃書* 摘 要:簡要描描述本文件的的內(nèi)容* * 當(dāng)前版本:1.1* 作 者:輸入作者者(或修改者者)名字* 完成日期:2001年年7月20日日* 取代版本:1.0 * 原作者 :輸入原作作者(或修改改者)名字* 完成日期:2001年年5月10日日*/示例1-1 版版權(quán)和版本的的聲明1.2 頭文件件的結(jié)構(gòu)頭文件由三部分分內(nèi)容組成:(1)頭文件開開頭處的版權(quán)權(quán)和版本聲明明(參見示例例1-1)。(2)預(yù)處理塊塊。(3)函數(shù)和類類結(jié)構(gòu)聲明等等。假設(shè)頭文件名稱稱為 grapphics.h,頭文件件的結(jié)構(gòu)參見見示例1-22?!疽?guī)

18、則1-2-1】為了防止頭頭文件被重復(fù)復(fù)引用,應(yīng)當(dāng)當(dāng)用ifnddef/deefine/endiff結(jié)構(gòu)產(chǎn)生預(yù)預(yù)處理塊?!疽?guī)則1-2-2】用 #incllude 格式來引引用標(biāo)準(zhǔn)庫的的頭文件(編編譯器將從標(biāo)標(biāo)準(zhǔn)庫目錄開開始搜索)?!疽?guī)則1-2-3】用 #incllude “” 格式來引用用非標(biāo)準(zhǔn)庫的的頭文件(編編譯器將從用用戶的工作目目錄開始搜索索)?!窘ㄗh1-2-1】頭文件中只只存放“聲明”而不存放“定義”在C+ 語法法中,類的成成員函數(shù)可以以在聲明的同同時被定義,并并且自動成為為內(nèi)聯(lián)函數(shù)。這這雖然會帶來來書寫上的方方便,但卻造造成了風(fēng)格不不一致,弊大大于利。建議議將成員函數(shù)數(shù)的定義與聲聲明分開

19、,不不論該函數(shù)體體有多么小。【建議1-2-2】不提倡使用用全局變量,盡盡量不要在頭頭文件中出現(xiàn)現(xiàn)象exteern innt vallue 這類類聲明。/ 版權(quán)和版版本聲明見示示例1-1,此處處省略。#ifndeffGRAPHHICS_HH/ 防止grapphics.h被重復(fù)引引用#defineeGRAPHHICS_HH#includde / 引用標(biāo)準(zhǔn)庫庫的頭文件#includde “myyheadeer.h” / 引用非標(biāo)準(zhǔn)準(zhǔn)庫的頭文件件void Fuunctioon1();/ 全局函函數(shù)聲明class BBox / 類結(jié)構(gòu)聲聲明;#endif示例1-2 CC+/C頭頭文件的結(jié)構(gòu)構(gòu)1.3 定義

20、文文件的結(jié)構(gòu)定義文件有三部部分內(nèi)容:定義文件開頭處處的版權(quán)和版版本聲明(參參見示例1-1)。對一些頭文件的的引用。程序的實現(xiàn)體(包包括數(shù)據(jù)和代代碼)。假設(shè)定義文件的的名稱為 ggraphiics.cppp,定義文件的結(jié)結(jié)構(gòu)參見示例1-3。/ 版權(quán)和版版本聲明見示示例1-1,此處處省略。#includde “grraphiccs.h”/ 引用頭文件件/ 全局函數(shù)數(shù)的實現(xiàn)體void Fuunctioon1()/ 類成員函函數(shù)的實現(xiàn)體體void Boox:Drraw()示例1-3 CC+/C定定義文件的結(jié)結(jié)構(gòu)1.4 頭文件件的作用早期的編程語言言如Basic、FFortraan沒有頭文文件的概念,C

21、C+/C語語言的初學(xué)者者雖然會用使使用頭文件,但但常常不明其其理。這里對對頭文件的作作用略作解釋釋:(1)通過頭文文件來調(diào)用庫庫功能。在很很多場合,源源代碼不便(或或不準(zhǔn))向用用戶公布,只只要向用戶提提供頭文件和和二進制的庫庫即可。用戶戶只需要按照照頭文件中的的接口聲明來來調(diào)用庫功能能,而不必關(guān)關(guān)心接口怎么么實現(xiàn)的。編編譯器會從庫庫中提取相應(yīng)應(yīng)的代碼。(2)頭文件能能加強類型安安全檢查。如如果某個接口口被實現(xiàn)或被被使用時,其其方式與頭文文件中的聲明明不一致,編編譯器就會指指出錯誤,這這一簡單的規(guī)規(guī)則能大大減減輕程序員調(diào)調(diào)試、改錯的的負(fù)擔(dān)。1.5 目錄結(jié)結(jié)構(gòu)如果一個軟件的的頭文件數(shù)目目比較多(如

22、如超過十個),通通常應(yīng)將頭文文件和定義文文件分別保存存于不同的目目錄,以便于于維護。例如可將頭文件件保存于inncludee目錄,將定定義文件保存存于sourrce目錄(可可以是多級目目錄)。如果某些頭文件件是私有的,它它不會被用戶戶的程序直接接引用,則沒沒有必要公開開其“聲明”。為了加強強信息隱藏,這這些私有的頭頭文件可以和和定義文件存存放于同一個個目錄。第2章 程序的的版式版式雖然不會會影響程序的的功能,但會會影響可讀性性。程序的版版式追求清晰晰、美觀,是是程序風(fēng)格的的重要構(gòu)成因因素??梢园殉绦虻陌姘媸奖扔鳛椤皶ā薄:玫摹皶ā笨勺屓藢Τ坛绦蛞荒苛巳蝗?,看得興致致勃勃。差的的程序“書法”

23、如螃蟹爬行行,讓人看得得索然無味,更更令維護者煩煩惱有加。請請程序員們學(xué)學(xué)習(xí)程序的“書法”,彌補大學(xué)計計算機教育的的漏洞,實在在很有必要。2.1 空行空行起著分隔程程序段落的作作用。空行得得體(不過多多也不過少)將將使程序的布布局更加清晰晰??招胁粫速M內(nèi)存,雖雖然打印含有有空行的程序序是會多消耗耗一些紙張,但但是值得。所所以不要舍不不得用空行?!疽?guī)則2-1-1】在每個類聲聲明之后、每每個函數(shù)定義義結(jié)束之后都都要加空行。參參見示例2-1(a)【規(guī)則2-1-2】在一個函數(shù)數(shù)體內(nèi),邏揖揖上密切相關(guān)關(guān)的語句之間間不加空行,其其它地方應(yīng)加加空行分隔。參參見示例2-1(b )/ 空行void Fuun

24、ctioon1() / 空行void Fuunctioon2() / 空行void Fuunctioon3() / 空行while (condiition)statemment1;/ 空行if (coonditiion) stateement22;elsestateement33;/ 空行statemment4; 示例2-1(aa) 函數(shù)之之間的空行 示例例2-1(bb) 函數(shù)內(nèi)內(nèi)部的空行2.2 代碼行行【規(guī)則2-2-1】一行代碼只只做一件事情情,如只定義義一個變量,或或只寫一條語語句。這樣的的代碼容易閱閱讀,并且方方便于寫注釋釋?!疽?guī)則2-2-2】if、for、whilee、do等語句自自占

25、一行,執(zhí)執(zhí)行語句不得得緊跟其后。不不論執(zhí)行語句句有多少都要要加。這樣可可以防止書寫寫失誤。示例2-2(aa)為風(fēng)格良良好的代碼行行,示例2-2(b)為風(fēng)格不良良的代碼行。int widdth;/ 寬度int heiight;/ 高度int deppth;/ 深度int widdth, hheightt, deppth; / 寬度高高度深度x = a + b;y = c + d;z = e + f;X a + b; y = c + dd; z = e + f;if (widdth heighht) dosometthing();if (widdth =”、“=”、“+”、“*”、“%”、“&”、

26、“|”、“”這類操作符符前后不加空空格?!窘ㄗh2-3-1】對于表達達式比較長的的for語句和和if語句,為為了緊湊起見見可以適當(dāng)?shù)氐厝サ粢恍┛湛崭瘢鏵oor (i=0; i10; ii+)和if (a=b) & (c= 2000) / 良好的的風(fēng)格if(yearr=20000) / 不良良的風(fēng)格if (a=b) & (c=bb&c=d) / 不良良的風(fēng)格for (i=0; i10; ii+) / 良好好的風(fēng)格for(i=00;i100;i+) / 不良的的風(fēng)格for (i = 0; I 110; i +) / 過多多的空格x = a b ? a : bb; / 良好好的風(fēng)格x=aFuncct

27、ion(); / 不要寫寫成 b - Funnctionn();示例2-3 代代碼行內(nèi)的空空格2.4 對齊【規(guī)則2-4-1】程序的分界界符和應(yīng)獨占一行行并且位于同同一列,同時時與引用它們們的語句左對對齊?!疽?guī)則2-4-2】 之內(nèi)的的代碼塊在右邊數(shù)格處處左對齊。示例2-4(aa)為風(fēng)格良良好的對齊,示示例2-4(b)為風(fēng)格不不良的對齊。void Fuunctioon(intt x) / prrogramm codeevoid Fuunctioon(intt x) / prrogramm codeeif (connditioon) / prrogramm codeeelse / prrogramm

28、 codeeif (connditioon) / prrogramm codeeelse / prrogramm codeefor (innitiallizatiion; ccondittion; updatte) / prrogramm codeefor (innitiallizatiion; ccondittion; updatte) / prrogramm codeeWhile (condiition) / prrogramm codeewhile (condiition) / prrogramm codee如果出現(xiàn)嵌套的的,則使使用縮進對齊齊,如: 示例2-4(aa) 風(fēng)格良良好的對齊

29、 示例2-4(b) 風(fēng)格格不良的對齊齊2.5 長行拆拆分【規(guī)則2-5-1】代碼行最大大長度宜控制制在70至880個字符以以內(nèi)。代碼行行不要過長,否否則眼睛看不不過來,也不不便于打印?!疽?guī)則2-5-2】長表達式要要在低優(yōu)先級級操作符處拆拆分成新行,操操作符放在新新行之首(以以便突出操作作符)。拆分分出的新行要要進行適當(dāng)?shù)牡目s進,使排排版整齊,語語句可讀。if (veery_loonger_variaable1 = veery_loonger_variaable122)& (verry_lonnger_vvariabble3 = verry_lonnger_vvariabble14)& (verr

30、y_lonnger_vvariabble5 Draw();/ 類的成成員函數(shù)【規(guī)則3-1-8】用正確的反反義詞組命名名具有互斥意意義的變量或或相反動作的的函數(shù)等。例如:intminnValuee;intmaxxValuee;intSettValuee();intGettValuee();【建議3-1-1】盡量避免名名字中出現(xiàn)數(shù)數(shù)字編號,如如Valuee1,Vallue2等,除除非邏輯上的的確需要編號號。這是為了了防止程序員員偷懶,不肯肯為命名動腦腦筋而導(dǎo)致產(chǎn)產(chǎn)生無意義的的名字(因為為用數(shù)字編號號最省事)。3.2 簡單的的Windoows應(yīng)用程程序命名規(guī)則則作者對“匈牙牙利”命名規(guī)則做做了合理的

31、簡簡化,下述的的命名規(guī)則簡簡單易用,比比較適合于WWindowws應(yīng)用軟件件的開發(fā)。【規(guī)則3-2-1】類名和函數(shù)數(shù)名用大寫字字母開頭的單單詞組合而成成。例如:class Node;/ 類名class LeafNNode;/ 類名void Draw(void);/ 函數(shù)名名void SetVaalue(iint vaalue);/ 函數(shù)名名【規(guī)則3-2-2】變量和參參數(shù)用小寫字字母開頭的單單詞組合而成成。例如:BOOL fflag;int ddrawMoode;【規(guī)則3-2-3】常量全用用大寫的字母母,用下劃線線分割單詞。例如:const int MMAX = 100;const int MMA

32、X_LEENGTH = 1000;【規(guī)則3-2-4】靜態(tài)變量加前前綴s_(表示staatic)。例如:void Innit()staticc int s_iniitValuue;/ 靜態(tài)變變量【規(guī)則3-2-5】如果不得得已需要全局局變量,則使使全局變量加加前綴g_(表示gloobal)。例如:int g_hhowMannyPeopple;/ 全局變變量int g_hhowMucchMoneey;/ 全局變變量【規(guī)則3-2-6】類的數(shù)據(jù)據(jù)成員加前綴綴m_(表示示membeer),這樣樣可以避免數(shù)數(shù)據(jù)成員與成成員函數(shù)的參參數(shù)同名。例如:void OObjectt:SettValuee(int wi

33、dthh, intt heigght)m_widdth = widthh;m_heighht = hheightt;【規(guī)則3-2-7】為了防止止某一軟件庫庫中的一些標(biāo)標(biāo)識符和其它它軟件庫中的的沖突,可以以為各種標(biāo)識識符加上能反反映軟件性質(zhì)質(zhì)的前綴。例例如三維圖形形標(biāo)準(zhǔn)OpeenGL的所所有庫函數(shù)均均以gl開頭頭,所有常量量(或宏定義義)均以GLL開頭。3.3 簡單的的Unix應(yīng)用用程序命名規(guī)規(guī)則第4章 表達式式和基本語句句讀者可能懷疑:連if、for、whilee、goto、switcch這樣簡單單的東西也要要探討編程風(fēng)風(fēng)格,是不是是小題大做?我真的發(fā)覺很多多程序員用隱隱含錯誤的方方式寫表達式

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

35、= += -= *= /= %= &= =|= =從左至右表4-1 運算算符的優(yōu)先級級與結(jié)合律【規(guī)則4-1-1】如果代代碼行中的運運算符比較多多,用括號確確定表達式的的操作順序,避避免使用默認(rèn)認(rèn)的優(yōu)先級。由于將表4-11熟記是比較較困難的,為為了防止產(chǎn)生生歧義并提高高可讀性,應(yīng)應(yīng)當(dāng)用括號確確定表達式的的操作順序。例例如:word = (highh = bb & cc d & c + f = g + h ;/ 復(fù)合表表達式過于復(fù)復(fù)雜【規(guī)則4-2-2】不要有多多用途的復(fù)合合表達式。例如:d = (a = b + c) + r ; 該表達式既求aa值又求d值值。應(yīng)該拆分分為兩個獨立立的語句:a =

36、b + c;d = a + r;【規(guī)則4-2-3】不要把程程序中的復(fù)合合表達式與“真正的數(shù)學(xué)學(xué)表達式”混淆。例如:if (a b c)/ a b c是數(shù)學(xué)表達式式而不是程序序表達式并不表示if (ab) & (bcc)而是成了令人費費解的if ( (aab)=”或“=-EPSINNON) & (x=EPSIINON)其中EPSINNON是允許許的誤差(即即精度)。4.3.4 指指針變量與零零值比較【規(guī)則4-3-4】應(yīng)當(dāng)將指針變變量用“=”或“!=”與NULL比較較。指針變量的零零值是“空”(記為NULLL)。盡管管NULL的值值與0相同,但但是兩者意義義不同。假設(shè)設(shè)指針變量的的名字為p,它與零

37、值值比較的標(biāo)準(zhǔn)準(zhǔn)if語句如下下:if (pp = NNULL)/ p與NULL顯式式比較,強調(diào)調(diào)p是指針變量量if (pp != NNULL)不要寫成if (pp = 00) / 容易讓讓人誤解p是整型變量量if (pp != 00) 或者if (p)/ 容易讓讓人誤解p是布爾變量量if (!pp)4.3.5 對對if語句的補補充說明有時候我們可能能會看到 iif (NUULL = p) 這這樣古怪的格格式。不是程程序?qū)戝e了,是是程序員為了了防止將 iif (p = NUULL) 誤誤寫成 iff (p = NULLL),而有意意把p和NULL顛倒倒。編譯器認(rèn)認(rèn)為 if (p = NULL)

38、是合法的的,但是會指指出 if (NULLL = p)是錯誤的,因因為NULLL不能被賦值值。程序中有時會遇遇到if/eelse/rreturnn的組合,應(yīng)應(yīng)該將如下不不良風(fēng)格的程程序if (coonditiion)returrn x;returnn y;改寫為if (coonditiion)returrn x;elsereturn y;或者改寫成更加加簡練的 return (condditionn ? x : y);4.4 循環(huán)語語句的效率C+/C循循環(huán)語句中,for語句使用頻率最高,while語句其次,do語句很少用。本節(jié)重點論述循環(huán)體的效率。提高循環(huán)體效率的基本辦法是降低循環(huán)體的復(fù)雜性。

39、【建議4-4-1】在多重循環(huán)環(huán)中,如果有有可能,應(yīng)當(dāng)當(dāng)將最長的循循環(huán)放在最內(nèi)內(nèi)層,最短的的循環(huán)放在最最外層,以減減少CPU跨切循循環(huán)層的次數(shù)數(shù)。例如示例例4-4(b)的效率率比示例4-4(a)的高。for (roow=0; row1100; rrow+)for ( ccol=0; col5; cool+ )sum = ssum + arowwcoll;for (cool=0; col55; coll+ )for (roow=0; row1100; rrow+) summ = suum + aarowcol;示例4-4(aa) 低效率率:長循環(huán)在在最外層 示示例4-4(b) 高效效率:長循環(huán)環(huán)在

40、最內(nèi)層【建議4-4-2】如果循環(huán)體體內(nèi)存在邏輯輯判斷,并且且循環(huán)次數(shù)很很大,宜將邏邏輯判斷移到到循環(huán)體的外外面。示例44-4(c)的程序序比示例4-4(d)多執(zhí)行行了N-1次邏輯輯判斷。并且且由于前者老老要進行邏輯輯判斷,打斷斷了循環(huán)“流水線”作業(yè),使得得編譯器不能能對循環(huán)進行行優(yōu)化處理,降降低了效率。如果N非常大,最好采用示例4-4(d)的寫法,可以提高效率。如果N非常小,兩者效率差別并不明顯,采用示例4-4(c)的寫法比較好,因為程序更加簡潔。for (i=0; iN; i+)if (connditioon) DoSSomethhing();else DoOOthertthing();if

41、 (connditioon)for (i=0; iN; i+) DoSSomethhing();else forr (i=00; iNN; i+) DoOOthertthing();表4-4(c) 效率低但但程序簡潔 表4-4(d) 效率率高但程序不不簡潔4.5 forr 語句的循循環(huán)控制變量量【規(guī)則4-5-1】不可在ffor 循環(huán)環(huán)體內(nèi)修改循循環(huán)變量,防防止for 循環(huán)失去控控制?!窘ㄗh4-5-1】建議for語句的的循環(huán)控制變變量的取值采采用“半開半閉區(qū)區(qū)間”寫法。示例4-5(aa)中的x值屬于半開開半閉區(qū)間“0 = x N”,起點到終終點的間隔為為N,循環(huán)次數(shù)數(shù)為N。示例4-5(bb)中的

42、x值屬于閉區(qū)區(qū)間“0 = x = N-1”,起點到終終點的間隔為為N-1,循環(huán)環(huán)次數(shù)為N。相比之下,示例例4-5(a)的寫法法更加直觀,盡盡管兩者的功功能是相同的的。for (innt x=00; xNN; x+)for (innt x=00; x 0 )*pbTTo + = *pbbFrom + ;returrn pvTTo;示例6-5 復(fù)復(fù)制不重疊的的內(nèi)存塊assert不不是一個倉促促拼湊起來的的宏。為了不不在程序的DDebug版版本和Rellease版版本引起差別別,assertt不應(yīng)該產(chǎn)生生任何副作用用。所以asssert不不是函數(shù),而而是宏。程序序員可以把aassertt看成一個在在

43、任何系統(tǒng)狀狀態(tài)下都可以以安全使用的的無害測試手手段。如果程程序在asssert處終終止了,并不不是說含有該該asserrt的函數(shù)有有錯誤,而是是調(diào)用者出了了差錯,asssert可可以幫助我們們找到發(fā)生錯錯誤的原因。很少有比跟蹤到到程序的斷言言,卻不知道道該斷言的作作用更讓人沮沮喪的事了。你你化了很多時時間,不是為為了排除錯誤誤,而只是為為了弄清楚這這個錯誤到底底是什么。有有的時候,程程序員偶爾還還會設(shè)計出有有錯誤的斷言言。所以如果果搞不清楚斷斷言檢查的是是什么,就很很難判斷錯誤誤是出現(xiàn)在程程序中,還是是出現(xiàn)在斷言言中。幸運的的是這個問題題很好解決,只只要加上清晰晰的注釋即可可。這本是顯顯而易見

44、的事事情,可是很很少有程序員員這樣做。這這好比一個人人在森林里,看看到樹上釘著著一塊“危險”的大牌子。但但危險到底是是什么?樹要要倒?有廢井井?有野獸?除非告訴人人們“危險”是什么,否否則這個警告告牌難以起到到積極有效的的作用。難以以理解的斷言言常常被程序序員忽略,甚甚至被刪除。Maguire, p8-p30【規(guī)則6-5-1】使用斷言捕捕捉不應(yīng)該發(fā)發(fā)生的非法情情況。不要混混淆非法情況況與錯誤情況況之間的區(qū)別別,后者是必必然存在的并并且是一定要要作出處理的的?!疽?guī)則6-5-2】在函數(shù)的的入口處,使使用斷言檢查查參數(shù)的有效效性(合法性性)?!窘ㄗh6-5-1】在編寫函函數(shù)時,要進進行反復(fù)的考考查,并

45、且自自問:“我打算做哪哪些假定?”一旦確定了了的假定,就就要使用斷言言對假定進行行檢查?!窘ㄗh6-5-2】一般教科科書都鼓勵程程序員們進行行防錯設(shè)計,但但要記住這種種編程風(fēng)格可可能會隱瞞錯錯誤。當(dāng)進行行防錯設(shè)計時時,如果“不可能發(fā)生生”的事情的確確發(fā)生了,則則要使用斷言言進行報警。6.6 引用與與指針的比較較引用是C+中中的概念,初初學(xué)者容易把把引用和指針針混淆一起。一一下程序中,n是m的一個引用(reference),m是被引用物(referent)。int m;int &nn = m;n相當(dāng)于m的別別名(綽號),對對n的任何操作作就是對m的操作。例例如有人名叫叫王小毛,他他的綽號是“三毛”

46、。說“三毛”怎么怎么的的,其實就是是對王小毛說說三道四。所所以n既不是m的拷貝,也也不是指向mm的指針,其其實n就是m它自己。引用的一些規(guī)則則如下:(1)引用被創(chuàng)創(chuàng)建的同時必必須被初始化化(指針則可可以在任何時時候被初始化化)。(2)不能有NNULL引用用,引用必須須與合法的存存儲單元關(guān)聯(lián)聯(lián)(指針則可可以是NULLL)。(3)一旦引用用被初始化,就就不能改變引引用的關(guān)系(指指針則可以隨隨時改變所指指的對象)。以下示例程序序中,k被初始化為為i的引用。語語句k = j并不能將k修改成為j的引用,只只是把k的值改變成成為6。由于于k是i的引用,所所以i的值也變成成了6。int i = 5;int

47、j = 6;int &kk = i;k = j;/ k和i的值都變成成了6;上面的程序看看起來象在玩玩文字游戲,沒沒有體現(xiàn)出引引用的價值。引引用的主要功功能是傳遞函函數(shù)的參數(shù)和和返回值。CC+語言中中,函數(shù)的參參數(shù)和返回值值的傳遞方式式有三種:值值傳遞、指針針傳遞和引用用傳遞。以下是“值傳傳遞”的示例程序序。由于Fuunc1函數(shù)數(shù)體內(nèi)的x是外部變量n的一份拷貝貝,改變x的值不會影影響n, 所以n的值仍然是是0。void FFunc1(int xx)x = x + 10;int n = 0;Func1(n);cout “n = ” n enddl;/ n = 0以下是“指針傳傳遞”的示例程序序。

48、由于Fuunc2函數(shù)數(shù)體內(nèi)的x是指向外部部變量n的指針,改改變該指針的的內(nèi)容將導(dǎo)致致n的值改變,所所以n的值成為110。void FFunc2(int *x)(* x) = (* x) + 10;int n = 0;Func2(&n);cout “n = ” n enddl;/ n = 10以下是“引用用傳遞”的示例程序序。由于Fuunc3函數(shù)數(shù)體內(nèi)的x是外部變量量n的引用,x和n是同一個東東西,改變xx等于改變n,所以n的值成為110。void FFunc3(int &x)x = x + 10;int n = 0;Func3(n);cout “n = ” n enddl;/ n = 10對比

49、上述三個個示例程序,會會發(fā)現(xiàn)“引用傳遞”的性質(zhì)象“指針傳遞”,而書寫方方式象“值傳遞”。實際上“引用”可以做的任任何事情“指針”也都能夠做做,為什么還還要“引用”這東西?答案是“用適當(dāng)當(dāng)?shù)墓ぞ咦銮∏∪缙浞值墓すぷ鳌?。指針能夠毫無無約束地操作作內(nèi)存中的如如何東西,盡盡管指針功能能強大,但是是非常危險。就就象一把刀,它它可以用來砍砍樹、裁紙、修修指甲、理發(fā)發(fā)等等,誰敢敢這樣用?如果的確只需要要借用一下某某個對象的“別名”,那么就用用“引用”,而不要用用“指針”,以免發(fā)生生意外。比如如說,某人需需要一份證明明,本來在文文件上蓋上公公章的印子就就行了,如果果把取公章的的鑰匙交給他他,那么他就就獲得了不

50、該該有的權(quán)利。第7章 內(nèi)存管管理歡迎進入內(nèi)存存這片雷區(qū)。偉偉大的Billl Gattes 曾經(jīng)經(jīng)失言:640K ouught tto be enouggh forr everrybodyy Bill Gatess 19811程序員們經(jīng)常編編寫內(nèi)存管理理程序,往往往提心吊膽。如如果不想觸雷雷,唯一的解解決辦法就是是發(fā)現(xiàn)所有潛潛伏的地雷并并且排除它們們,躲是躲不不了的。本章的內(nèi)容容比一般教科科書的要深入入得多,讀者者需細(xì)心閱讀讀,做到真正正地通曉內(nèi)存存管理。7.1內(nèi)存分配配方式內(nèi)存分配方式有有三種:從靜態(tài)存儲區(qū)域域分配。內(nèi)存存在程序編譯譯的時候就已已經(jīng)分配好,這這塊內(nèi)存在程程序的整個運運行期間都存

51、存在。例如全全局變量,sstaticc變量。在棧上創(chuàng)建。在在執(zhí)行函數(shù)時時,函數(shù)內(nèi)局局部變量的存存儲單元都可可以在棧上創(chuàng)創(chuàng)建,函數(shù)執(zhí)執(zhí)行結(jié)束時這這些存儲單元元自動被釋放放。棧內(nèi)存分分配運算內(nèi)置置于處理器的的指令集中,效效率很高,但但是分配的內(nèi)內(nèi)存容量有限限。從堆上分配,亦亦稱動態(tài)內(nèi)存存分配。程序序在運行的時時候用mallloc或new申請任任意多少的內(nèi)內(nèi)存,程序員員自己負(fù)責(zé)在在何時用frree或delette釋放內(nèi)存存。動態(tài)內(nèi)存存的生存期由由我們決定,使使用非常靈活活,但問題也也最多。7.2常見的內(nèi)內(nèi)存錯誤及其其對策發(fā)生內(nèi)存錯誤誤是件非常麻麻煩的事情。編編譯器不能自自動發(fā)現(xiàn)這些些錯誤,通常常是在

52、程序運運行時才能捕捕捉到。而這這些錯誤大多多沒有明顯的的癥狀,時隱隱時現(xiàn),增加加了改錯的難難度。有時用用戶怒氣沖沖沖地把你找來來,程序卻沒沒有發(fā)生任何何問題,你一一走,錯誤又又發(fā)作了。常見的內(nèi)存錯誤誤及其對策如如下:內(nèi)存分配未成功功,卻使用了了它。編程新手常犯這這種錯誤,因因為他們沒有有意識到內(nèi)存存分配會不成成功。常用解解決辦法是,在在使用內(nèi)存之之前檢查指針針是否為NUULL。如果果指針p是函數(shù)的參參數(shù),那么在在函數(shù)的入口口處用asssert(pp!=NULLL)進行檢檢查。如果是是用mallloc或new來申請請內(nèi)存,應(yīng)該該用if(pp=NULLL) 或if(pp!=NULLL)進行防防錯處

53、理。內(nèi)存分配雖然成成功,但是尚尚未初始化就就引用它。犯這種錯誤主要要有兩個起因因:一是沒有有初始化的觀觀念;二是誤誤以為內(nèi)存的的缺省初值全全為零,導(dǎo)致致引用初值錯錯誤(例如數(shù)數(shù)組)。內(nèi)存的缺省初值值究竟是什么么并沒有統(tǒng)一一的標(biāo)準(zhǔn),盡盡管有些時候候為零值,我我們寧可信其其無不可信其其有。所以無無論用何種方方式創(chuàng)建數(shù)組組,都別忘了了賦初值,即即便是賦零值值也不可省略略,不要嫌麻麻煩。內(nèi)存分配成功并并且已經(jīng)初始始化,但操作作越過了內(nèi)存存的邊界。例如在使用數(shù)組組時經(jīng)常發(fā)生生下標(biāo)“多1”或者“少1”的操作。特特別是在foor循環(huán)語句句中,循環(huán)次次數(shù)很容易搞搞錯,導(dǎo)致數(shù)數(shù)組操作越界界。忘記了釋放內(nèi)存存,造

54、成內(nèi)存存泄露。含有這種錯誤的的函數(shù)每被調(diào)調(diào)用一次就丟丟失一塊內(nèi)存存。剛開始時時系統(tǒng)的內(nèi)存存充足,你看看不到錯誤。終終有一次程序序突然死掉,系系統(tǒng)出現(xiàn)提示示:內(nèi)存耗盡盡。動態(tài)內(nèi)存的申請請與釋放必須須配對,程序序中mallloc與free的使使用次數(shù)一定定要相同,否否則肯定有錯錯誤(neww/deleete同理)。釋放了內(nèi)存卻繼繼續(xù)使用它。有三種情況:(1)程序中的的對象調(diào)用關(guān)關(guān)系過于復(fù)雜雜,實在難以以搞清楚某個個對象究竟是是否已經(jīng)釋放放了內(nèi)存,此此時應(yīng)該重新新設(shè)計數(shù)據(jù)結(jié)結(jié)構(gòu),從根本本上解決對象象管理的混亂亂局面。(2)函數(shù)的rreturnn語句寫錯了了,注意不要要返回指向“棧內(nèi)存”的“指針”或者

55、“引用”,因為該內(nèi)內(nèi)存在函數(shù)體體結(jié)束時被自自動銷毀。(3)使用frree或delette釋放了內(nèi)內(nèi)存后,沒有有將指針設(shè)置置為NULLL。導(dǎo)致產(chǎn)生生“野指針”?!疽?guī)則7-2-1】用mallooc或new申請內(nèi)內(nèi)存之后,應(yīng)應(yīng)該立即檢查查指針值是否否為NULLL。防止使用用指針值為NNULL的內(nèi)內(nèi)存?!疽?guī)則7-2-2】不要忘記記為數(shù)組和動動態(tài)內(nèi)存賦初初值。防止將未被初初始化的內(nèi)存存作為右值使使用?!疽?guī)則7-2-3】避免數(shù)組組或指針的下下標(biāo)越界,特特別要當(dāng)心發(fā)發(fā)生“多1”或者“少1”操作?!疽?guī)則7-2-4】動態(tài)內(nèi)存存的申請與釋釋放必須配對對,防止內(nèi)存存泄漏?!疽?guī)則7-2-5】用free或delette

56、釋放了內(nèi)內(nèi)存之后,立立即將指針設(shè)設(shè)置為NULLL,防止產(chǎn)產(chǎn)生“野指針”。7.3指針與數(shù)數(shù)組的對比C+/C程程序中,指針針和數(shù)組在不不少地方可以以相互替換著著用,讓人產(chǎn)產(chǎn)生一種錯覺覺,以為兩者者是等價的。數(shù)組要么在靜靜態(tài)存儲區(qū)被被創(chuàng)建(如全全局?jǐn)?shù)組),要要么在棧上被被創(chuàng)建。數(shù)組組名對應(yīng)著(而而不是指向)一一塊內(nèi)存,其其地址與容量量在生命期內(nèi)內(nèi)保持不變,只只有數(shù)組的內(nèi)內(nèi)容可以改變變。指針可以隨時指指向任意類型型的內(nèi)存塊,它它的特征是“可變”,所以我們們常用指針來來操作動態(tài)內(nèi)內(nèi)存。指針遠(yuǎn)遠(yuǎn)比數(shù)組靈活活,但也更危危險。下面以字符串為為例比較指針針與數(shù)組的特特性。7.3.1 修修改內(nèi)容示例7-3-1中,

57、字符數(shù)數(shù)組a的容量是66個字符,其其內(nèi)容為heello00。a的內(nèi)容可以以改變,如aa0= X。指指針p指向常量字字符串“worldd”(位于靜態(tài)存儲區(qū)區(qū),內(nèi)容為wworld0),常量量字符串的內(nèi)內(nèi)容是不可以以被修改的。從從語法上看,編編譯器并不覺覺得語句p0= X有什么么不妥,但是是該語句企圖圖修改常量字字符串的內(nèi)容容而導(dǎo)致運行行錯誤。char a = “hhello”;a0 = X;cout a endll;char *pp = “wworld”; / 注意意p指向常量字字符串p0 = X; / 編編譯器不能發(fā)發(fā)現(xiàn)該錯誤cout p endll;示例7-3-11 修改數(shù)組和和指針的內(nèi)容容7

58、.3.2 內(nèi)內(nèi)容復(fù)制與比比較不能對數(shù)組名名進行直接復(fù)復(fù)制與比較。示示例7-3-2中,若想想把數(shù)組a的內(nèi)容復(fù)制制給數(shù)組b,不能用語語句 b = a ,否否則將產(chǎn)生編編譯錯誤。應(yīng)應(yīng)該用標(biāo)準(zhǔn)庫庫函數(shù)strrcpy進行行復(fù)制。同理理,比較b和a的內(nèi)容是否否相同,不能能用if(bb=a) 來判斷,應(yīng)該該用標(biāo)準(zhǔn)庫函函數(shù)strccmp進行比比較。語句p = a 并不能能把a的內(nèi)容復(fù)制制指針p,而是把a的地址賦給給了p。要想復(fù)制制a的內(nèi)容,可可以先用庫函函數(shù)mallloc為p申請一塊容容量為strrlen(aa)+1個字字符的內(nèi)存,再再用strccpy進行字字符串復(fù)制。同同理,語句if(p=a) 比比較的不是

59、內(nèi)內(nèi)容而是地址址,應(yīng)該用庫庫函數(shù)strrcmp來比比較。/ 數(shù)組char aa = helllo;char bb10;strcpyy(b, aa);/ 不能能用b = aa;if(strrcmp(bb, a) = 0)/ 不能能用 iff (b = a)/ 指針int leen = sstrlenn(a);char *p = (char *)mallloc(ssizeoff(charr)*(leen+1);strcpyy(p,a);/ 不要用用 p = a;if(strrcmp(pp, a) = 0)/ 不要要用 if (p = a)示例7-3-22 數(shù)組和指針針的內(nèi)容復(fù)制制與比較7.3.3

60、計計算內(nèi)存容量量用運算符siizeof可可以計算出數(shù)數(shù)組的容量(字字節(jié)數(shù))。示示例7-3-3(a)中,sizzeof(aa)的值是112(注意別別忘了00)。指針針p指向a,但是sizzeof(pp)的值卻是是4。這是因因為sizeeof(p)得到的是一一個指針變量量的字節(jié)數(shù),相相當(dāng)于sizzeof(cchar*),而不是p所指的內(nèi)存存容量。C+/C語言言沒有辦法知知道指針?biāo)钢傅膬?nèi)存容量量,除非在申申請內(nèi)存時記記住它。注意當(dāng)數(shù)組作為為函數(shù)的參數(shù)數(shù)進行傳遞時時,該數(shù)組自自動退化為同同類型的指針針。示例7-3-3(b)中,不論論數(shù)組a的容量是多多少,sizzeof(aa)始終等于于sizeoof

溫馨提示

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

最新文檔

評論

0/150

提交評論