版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
if第5const#define有了 為什么還要new/delete new/delete附錄A:C++/C代碼表附錄B:C++/C試題賞。就象在武俠小說(shuō)中,那些獨(dú)來(lái)獨(dú)往、不受約束且?guī)c(diǎn)邪氣的高手最令人。我曾經(jīng)也這樣信奉,這些軟件頻頻獲獎(jiǎng),有一個(gè)軟件獲得首屆學(xué)生電腦大賽軟件展示一等獎(jiǎng)。在1995年開(kāi)發(fā)的一套圖位真正的軟件高手請(qǐng)教。他雖然從未涉足過(guò)3D圖形領(lǐng)域,卻在幾十分鐘內(nèi)該軟件多處重大設(shè)計(jì)錯(cuò)誤。讓人感覺(jué)那套軟件是用紙糊的華麗衣服,扯一下掉一塊,戳一下破個(gè)洞。我目瞪口呆地這套設(shè)計(jì)的基礎(chǔ)知識(shí)。補(bǔ)修“內(nèi)功”之后,又覺(jué)得腰板硬了起來(lái)。博士畢業(yè)前半年,我曾到微軟中國(guó)找在大學(xué)里從來(lái)沒(méi)有人如此嚴(yán)格地考查過(guò)我的程序。我化了半個(gè)小時(shí),修改了數(shù)次,他還不盡滿意,讓我回家好好琢磨。我精神抖擻地進(jìn)“考場(chǎng)”,大汗淋漓地出“考場(chǎng)”。這“高手”當(dāng)?shù)靡蔡C囊了。我又好好地反省了一次。型IT企業(yè)如、貝爾、中興等公司的們廣泛交流。大家認(rèn)為提高質(zhì)量與生產(chǎn)率是軟件工程要現(xiàn)在國(guó)內(nèi)IT企業(yè)擁有學(xué)士、、博士文憑的軟件開(kāi)發(fā)人員比比皆是,但他們?cè)诮邮艽髮W(xué)教育時(shí)就“且能在實(shí)踐中運(yùn)用自如??!案哔|(zhì)量”可不是干活點(diǎn)就能實(shí)現(xiàn)的!事實(shí)證明如此。我到貝爾工作一年來(lái),陸續(xù)面試或測(cè)試過(guò)近百名“新”“老”程序員的編程技能,質(zhì)量大約是10%。很少有人能夠?qū)懗鐾耆腺|(zhì)量要求的if語(yǔ)句,很多程序員對(duì)指針、內(nèi)存管理們不敢相信這是真的。我做過(guò)現(xiàn)場(chǎng)試驗(yàn):有一次部門新進(jìn)14名生,在開(kāi)歡迎會(huì)之前對(duì)他們進(jìn)行數(shù)人得。競(jìng)爭(zhēng)對(duì)手公司的朋友們也做過(guò)試驗(yàn),同樣一敗涂地。要知道、貝爾、中興等公司的員工素質(zhì)在國(guó)內(nèi)IT企業(yè)中是比較前列的,倘若他們的編程質(zhì)量都后中趕超發(fā)達(dá)國(guó)家嗎?只要你能下決心改掉不良的編程習(xí)慣,第二次考試就能及格了。適的工作單位,不妨到貝爾試一試。果制定了大家認(rèn)可的編程風(fēng)格,那么所有組員都要遵守。如果讀者覺(jué)得本書的編程風(fēng)格比較合你的工作,那么就采用它,不要只看不做。人在小時(shí)候說(shuō)話發(fā)音,寫字潦草,如果不改正,總有后悔的時(shí)候。第七章至第十一章是專題論述,技術(shù)難度比較高,看書時(shí)要積極思考。特別是第七章“內(nèi)存管理”,讀了并不表示懂了,懂了并不表示就能正確使用。有一位同事看了第七章后覺(jué)得“野指針”寫得不錯(cuò),與我切磋了一把??墒沁^(guò)了兩周,他告訴我,他忙了兩天追查出一個(gè)Bug,想不到又是“野指針”出問(wèn)題,只按照CMMI規(guī)范做事,讓自己的綜合水平上升一個(gè)臺(tái)階。貝爾的員工可以向網(wǎng)絡(luò)應(yīng)用事業(yè)部軟件工 作者,不得或大量本書預(yù)計(jì)到2002年7月,建立切合中國(guó)國(guó)情的CMMI3級(jí)解決方案。屆時(shí),包括本書在內(nèi)的約 Copyright(c)2001,貝爾網(wǎng)絡(luò)應(yīng)用事業(yè)Allrights 年 原作者:輸入原作者(或修改者) 年
和版本(參見(jiàn)示例1-1)假設(shè)頭文件名稱為【規(guī)則1-2-2】用#include<filename.h>格式來(lái)標(biāo)準(zhǔn)庫(kù)的頭文件(編譯器將從標(biāo)準(zhǔn)庫(kù)開(kāi) 【規(guī)則1-2-3】用#include“filename.h”格式來(lái)非標(biāo)準(zhǔn)庫(kù)的頭文件(編譯器將從用戶的工作【建議1-2-1】頭文件中只存放“”而不存放“定義在C++語(yǔ)法中,類的成員函數(shù)可以在的同時(shí)被定義,并且自動(dòng)成為內(nèi)聯(lián)函數(shù)。這雖然會(huì)帶來(lái)書寫上的方便,但卻造成了風(fēng)格不一致,弊大于利。建議將成員函數(shù)的定義與分開(kāi),不論該函數(shù)體有多么【建議1-2-2】不提倡使用全局變量,盡量不要在頭文件中出現(xiàn)象externintvalue這類 #ifndefGRAPHICS_H//防止graphics.h被重復(fù)#define#include //標(biāo)準(zhǔn)庫(kù)的頭文…#include“myheader.h”//非標(biāo)準(zhǔn)庫(kù)的頭文…voidFunction1(…);//…class 類結(jié)構(gòu){… 和版本(參見(jiàn)示例1-1)對(duì)一些頭文件的假設(shè)定義文件的名稱為 #include //頭文…void{…}void{…}
通過(guò)頭文件來(lái)調(diào)用庫(kù)功能。在很多場(chǎng)合,源代碼不便(或)向用戶公布,只要向用戶提供頭錄,以便于。 隔。參見(jiàn)示例2-1(b)void{…}void{…}void{…}while{if{}{}}示例2-1(a)函數(shù)之間的空 示例2-1(b)函數(shù)內(nèi)部的空多少都要加{}。這樣可以防止書寫。intwidth;//寬度intheight;//intdepth;//intwidth,height,depth;//x=a+y=c+z=e+X=a+b;y=c+d;z=e+if(width<{}if(width<height)for(initialization;condition;{}空行for(initialization;condition;update)示例2-2(a)風(fēng)格良好的代碼 示例2-2(b)風(fēng)格不良的代碼intwidth=10; intheight=10;//定義并初紿化heightintdepth 定義并初紿化【規(guī)則2-3-1】關(guān)鍵字之后要留空格。象const、virtual、inline、case等關(guān)鍵字之后至少要留一【規(guī)則2-3-4】‘,’之后要留空格,如Function(x,y,z)。如果‘;’不是一行的結(jié)束符號(hào),其后要留空格,如for(initialization;condition;update)。如“=”、、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后應(yīng)當(dāng)加空格,如for(i=0;i<10i++)和if((a<=b)&&voidFunc1(intx,inty,intvoidFunc1(intx,inty,intif(year>=if((a>=b)&&for(i=0;i<10;i++)for(i=0;I<10;ix=a<b?a:int*x=int*x=&array[5]=0;array5ab【規(guī)則2-4-1】程序的分界符‘{’和‘}’應(yīng)獨(dú)占一行并且位于同一列,同時(shí)與它們的語(yǔ)句左對(duì){}voidFunction(int{…//program}voidFunction(int…//program}ifif{…//program…//program}}else…//program{}…//program}for(initialization;condition;{…//program}for(initialization;condition;…//program}While{…//program}while…//program}{…{…}…}示例2-4(a)風(fēng)格良好的對(duì) 示例2-4(b)風(fēng)格不良的對(duì)if((very_longer_variable1>=&&(very_longer_variable3<=very_longer_variable14)&&(very_longer_variable5<={}virtualCMatrixCMultiplyMatrix(CMatrixCMatrixfor{}
示例2-5*靠近數(shù)據(jù)類型,例如:int*x;從語(yǔ)義上講此寫法比較直觀,即x是int上述寫法的弊端是容易引起誤解,例如:int*x,y;此處y容易被誤解為指針變量。雖然將x和y分行定義【規(guī)則2-6-1*charint*xy;//此處y i1程程返回值:voidFunction(floatx,floaty,float{…}.8if{…while{…}//endof…}//endof釋釋protected和private,分別用于哪些數(shù)據(jù)和函數(shù)是公有的、受保護(hù)的或者是私有的。這樣可以達(dá)到信封裝功能,它當(dāng)成火鍋,什么東西都往里扔。classclass{void… i,j;floatx,y;…}class{ i,j;floatx,y;void…}示例8.3(a)以數(shù)據(jù)為中心版 示例8.3(b)以行為為中心的版比較著名名規(guī)則當(dāng)推公司的“匈牙利”法,該命名規(guī)則的主要思想是“在變量和函數(shù)名中加入 i,j,k;floatx,y, iI,iJ,ik;//前綴i表示int類型floatfX,fY,fZ;//f表示float類型據(jù),沒(méi)有一種命名規(guī)則可以讓所有的程序員贊同,程序設(shè)計(jì)教科書一般都不指定命名規(guī)則。命名規(guī)則對(duì)軟件產(chǎn)品而言并不是“成敗悠關(guān)”的事,我們不要化太多精力試圖發(fā)明世界上最好名規(guī)則,而應(yīng)當(dāng)制定一種令大多數(shù)項(xiàng)目成員滿意名規(guī)則,并在項(xiàng)目中實(shí)施。 【規(guī)則3-1-2】標(biāo)識(shí)符的長(zhǎng)度應(yīng)當(dāng)符合“min-length&&max-information”幾十年前老ANSIC規(guī)定名字超過(guò)6個(gè)字符,現(xiàn)今的C++/C不再有此限制。一般來(lái)說(shuō),長(zhǎng)名字能更好地表達(dá)含義,所以函數(shù)名、變量名、類名長(zhǎng)達(dá)十幾個(gè)字符不足為怪。那么名字是否越長(zhǎng)約好?不見(jiàn)得!例如變量名maxval就比maxValueUntilOverflow好用。單字符的名字也是有用的,常見(jiàn)的如i,j,k,m,n,x,y,zintx, 變量xXvoidfoo(int 函數(shù)foo與FOOvoidFOO(floatfloatfloatoldValue;floatnewValue; classNode; //類名classLeafNode; //類名void //函數(shù)voidSetValue(intvalue);//BOOLintconstintMAX=constintMAX_LENGTH=void{staticint …}int intg_howMu //全局變voidObject::SetValue(intwidth,int{m_width=width;m_height=height;}C++/C語(yǔ)言的運(yùn)算符有數(shù)十個(gè),運(yùn)算符的優(yōu)先級(jí)與結(jié)合律如表4-1+-*的優(yōu)([->!~++--(類型)+-**/+<<<>==&^|=+=-=*=/=%=&==<<=word=(high<<8)|if((a|b)&&(a&abc0這樣的表達(dá)式稱為復(fù)合表達(dá)式。允許復(fù)合表達(dá)式存在的理由是:(1)iab&&cd&&cfgh;//d=(a=b+c)+ra=b+d=a+if(a<b<c) abc是數(shù)學(xué)表達(dá)式而不是程序表達(dá)式if((a<b)&&if((a<b)<cif竟是什么并沒(méi)有統(tǒng)一的標(biāo)準(zhǔn)。例如VisualC++將TRUE定義為1,而VisualBasic則將TRUE定義為-1。if 表示flagif 表示flagif(flag==if(flag==1if(flag==FALSE)if(flag==0)if(value==if(value!=if(value) value是布爾變量if(!value)if(x==0.0) if((x>=-EPSINON)&&if(p==NULL) p與NULL顯式比較,強(qiáng)調(diào)p是指針變量if(p!=NULL)if(p0)//容易讓人誤解pif(p!=if //ifif(NULLp)ifNULL)if(pNULL),而有意把p和NULLifpNULL)if(NULL=p)是錯(cuò)誤的,因?yàn)镹ULL不能被賦值。ifreturny;if{return}{return}return(condition?x:forfor(col=0;col<5;col++{for(row=0;row<100;{sum=sum+}}for(row=0;row<100;{for(col=0;col<5;col++{sum=sum+}}示例4-4(a)低效率:長(zhǎng)循環(huán)在最外 示例4-4(b)高效率:長(zhǎng)循環(huán)在最內(nèi)【建議2】如果循環(huán)體內(nèi)存在邏輯判斷,并且循環(huán)次數(shù)很大,宜將邏輯判斷移到循環(huán)體的外面。示例)的程序比示例)多執(zhí)行了1次邏輯判斷。并且由于前者老要進(jìn)行邏輯判斷,打斷了循環(huán)“流水線”作業(yè),使得編譯器不能對(duì)循環(huán)進(jìn)行優(yōu)化處理,降低了效率。如果N非常大,最好采用示例)的寫法,可以提高效率。如果N非常小,兩者效率差別并不明顯,采用示例)for(i=0;i<N;{if(condition)}if{for(i=0;i<N;i++)}{for(i=0;i<N;i++)}表4-4(c)效率低但程序簡(jiǎn) 表4-4(d)效率高但程序不簡(jiǎn)示例4-5(a)中的x值屬于半開(kāi)半閉區(qū)間“0xN”,起點(diǎn)到終點(diǎn)的間隔為N,循環(huán)次數(shù)為N。示例4-5(b)中的x值屬于閉區(qū)間“0=<x<=N-1”,起點(diǎn)到終點(diǎn)的間隔為N-1,循環(huán)次數(shù)為N。for(intx=0;x<N;for(intx=0;x<=N-1;{{……}}示例4-5(a)循環(huán)變量屬于半開(kāi)半閉區(qū) 示例4-5(b)循環(huán)變量屬于閉區(qū)switch(variable){casevalue1:…casevalue2:……default: }【規(guī)則4-6-2】記最后那個(gè)default分支。即使程序真的不需要default處理,也應(yīng)該保留語(yǔ) default:break;這樣做并非多此一舉,而是為了防止別人誤以為你忘了default處理。自從提倡結(jié)構(gòu)化設(shè)計(jì)以來(lái),goto就成了有爭(zhēng)議的語(yǔ)句。首先,由于goto語(yǔ)句可以靈活跳轉(zhuǎn),如果不加限制,它的確會(huì)破壞結(jié)構(gòu)化設(shè)計(jì)風(fēng)格。其次,goto語(yǔ)句經(jīng)常帶來(lái)錯(cuò)誤或隱患。它可能跳過(guò)了某些對(duì)象的gotoStrings1,s2;被gotointsum=0;//被goto……很多人建議C++/C的goto語(yǔ)句,以絕后患。但實(shí)事求是地說(shuō),錯(cuò)誤是程序員自己造成的,不是goto的過(guò)錯(cuò)。goto語(yǔ)句至少有一處可顯神通,它能從多重循環(huán)體中咻地一下子跳到外面,用不著寫很多次的break語(yǔ)句;例如{{{goto}}}…語(yǔ)言用語(yǔ)言除了【規(guī)則5-1-1 MAX /*C語(yǔ)言的宏常量const MAX //C++語(yǔ)言的constconst PI //C++語(yǔ)言的constconst#defineconstfloatRADIUS=constfloatDIAMETER=RADIUS*classconstintSIZE= //錯(cuò)誤,企圖在類中初始化const數(shù)據(jù)成int 錯(cuò)誤,未知的classAA(int constintSIZEA::A(intsize {…}Aa(100);對(duì)象a的SIZE值為100Ab(200);b的SIZE值為classenumSIZE1100,SIZE2200};intint(passbyvalue)和指針傳遞(passbypointer)。C++語(yǔ)言中多了傳遞(passbyreference)。由于voidSetValue(intwidth,intheight);//voidSetValue(int, float float voidStringCopy(char*str1,char voidStringCopy(char*strSource,charcharStringCopy(str,“oWorld”);//參數(shù)順序顛voidStringCopy(char*strDestination,constcharintprintf(constchat*format[,argument]…);亂,規(guī)定任何C++/C函數(shù)都必須有類型。如果函數(shù)沒(méi)有返回值,那么應(yīng)為void類型。charc=getchar();if(c==…int失敗,這種“”人們一般哪里料得到!導(dǎo)致本例錯(cuò)誤的責(zé)任并不在用戶,是函數(shù)getchar誤導(dǎo)了使用函數(shù)getcharBOOLGetChar(char靈活,例如());char*strcpy(char*strDest,constcharcharintlength=strlen(strcpy(str,“oWorld”)效率。而有些場(chǎng)合只能用“值傳遞”而不能用“傳遞”,否則會(huì)出錯(cuò)。classString&operate=(constString//相加函數(shù),如果沒(méi)有friend修飾則只許有一個(gè)右側(cè)參數(shù) Stringoperate+(constString&s1,constString&s2);char}String的賦值函數(shù)operateString&String::operate=(constString{if(this==&other)return*this;deletem_data=newchar[strlen(other.data)+1];strcpy(m_data,other.data);return //返回的是*this的,無(wú)需拷貝過(guò)}String…a 如果用“值傳遞”*thisabc;//如果用“值傳遞”*thisString的相加函數(shù)operateStringoperate+(constString&s1,constString{Stringdeletetemp.data; //temp.data是僅含‘\0’的字符串temp.datanewchar[strlen(s1.datastrlen(s2.data)+1];strcpy(temp.data,s1.data);returntemp;}指向局部對(duì)象temp的“”。由于temp在函數(shù)結(jié)束時(shí)被自動(dòng)銷毀,將導(dǎo)致返回的“”無(wú)效。例如:c=a+ab并不返回期望值,c們可以在函數(shù)體的“處”和“出口處”從嚴(yán)把關(guān),從而提高函數(shù)的質(zhì)量。char*{charstr[]=“o …return }要搞清楚返回的究竟是“值”、“指針”還是“”returnString(s1+Stringtemp(s1+returnreturnint(xy);inttemp=x+return帶有“”功能的函數(shù),其行為可能是不可預(yù)測(cè)的,因?yàn)樗男袨榭赡苋Q于某種“狀態(tài)”。這樣的函數(shù)既不易理解又不利于測(cè)試和。在C/C++語(yǔ)言中,函數(shù)的static局部變量是函數(shù)的“”器。斷言assert是僅在Debug版本起作用的宏,它用于檢查“不應(yīng)該”發(fā)生的情況。示例6-5是一個(gè)內(nèi)存函數(shù)。在運(yùn)行過(guò)程中,如果assert的參數(shù)為假,那么程序就會(huì)中止(一般地還會(huì)出現(xiàn)提示,說(shuō)明在什么地方了assert)。void*memcpy(void*pvTo,constvoid*pvFrom,size_t{assert((pvToNULL&&pvFrom byte*pbTo(byte*) 防止改變pvTobyte*pbFrombyte*)pvFrom;防止改變pvFromwhile(size-->0*pbTo++=*pbFrom++;returnpvTo;}示例6-5不的內(nèi)存DbuRelae版本引起差別,ser不應(yīng)該產(chǎn)生ser害測(cè)試。如程序assr處終了,并是說(shuō)含該assr出t序員忽略,甚至被刪除。[Maguire,p8-p30]【規(guī)則6-5-2】在函數(shù)的處,使用斷言檢查參數(shù)的有效性()是C++中的概念,初學(xué)者容易把和指針一起。一下程序中,n是m的一(reference),m是被物(referent)intint&n=n相當(dāng)于m的別名(),對(duì)n的任何操作就是對(duì)m的操作。例人名叫王小毛,他的是“三(1)被創(chuàng)建的同時(shí)必須被初始化(指針則可以在任何時(shí)候被初始化)不能有NULL,必須與合法的單元關(guān)聯(lián)(指針則可以是NULL)一旦被初始化,就不能改 。語(yǔ)句k=j并不能將k修改成為j的,只是把k的值改變成inti=intj=6;int&k=i;k k和i的值都變成了回值。C++語(yǔ)言中,函數(shù)的參數(shù)和返回值的傳遞方式有三種:值傳遞、指針傳遞和傳遞。voidFunc1(int{x=x+}…intn=cout<<“n=”<<n<< //n=voidFunc2(int{(*x)=(*x)+}…intn=0;cout<<“n=”<<n<< //n=以下是“傳遞”的示例程序。由于Func3函數(shù)體內(nèi)的x是外部變量n的,x和n是同一個(gè)東西,改voidFunc3(int{x=x+}…intn=0;cout<<“n=”<<n<< //n=對(duì)比上述三個(gè)示例程序,會(huì)發(fā)現(xiàn)“傳遞”的性質(zhì)象“指針傳遞”,而書寫方式象“值傳遞”。實(shí)際上“”可以做的任何事情“指針”也都能夠做,為什么還要“”這東西?如果的確只需要借用一下某個(gè)對(duì)象的“別名”,那么就用“”,而不要用“指針”,以免發(fā)生意外。比如說(shuō),需要一份證明,本來(lái)在文件上蓋上公章的印子就行了,如果把取公章的交給他,那么他就歡迎進(jìn)入內(nèi)存這片雷區(qū)。偉大的BillGates640Koughttobeenoughfor—BillGates從靜態(tài)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量 或ew申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用或delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由我們決定,使用非常靈活,但問(wèn)題也最到。而這些錯(cuò)誤大多沒(méi)有明顯的癥狀,時(shí)隱時(shí)現(xiàn),增加了改錯(cuò)的難度。有時(shí)用戶怒氣沖沖地找來(lái),編程新手常犯這種錯(cuò)誤,因?yàn)樗麄儧](méi)有內(nèi)存分配會(huì)不成功。常用解決辦法是,在使用內(nèi)存之前檢查指針是否為NULL。如果指針p是函數(shù)的參數(shù),那么在函數(shù)的處用assert(p!=NULL)進(jìn)行檢查。如果 或ew來(lái)申請(qǐng)內(nèi)存,應(yīng)該用if(p==NULL)或if(p!=NULL)進(jìn)行防錯(cuò)處理。函數(shù)的return語(yǔ)句寫錯(cuò)了,注意不要返回指向“棧內(nèi)存”的“指針”或者“”,因?yàn)樵搩?nèi)存在函數(shù)體 或ew申請(qǐng)內(nèi)存之后,應(yīng)該立即檢查指針值是否為NULL。防止使用指 示例7-3-1中,字符數(shù)組a的容量是6個(gè)字符,其內(nèi)容為o\0。a的內(nèi)容可以改變,如a[0]=‘X’。指針p指向常量字符串“world”(位于靜態(tài)區(qū),內(nèi)容為world\0),常量字符串的內(nèi)容是不可以被修改的。從語(yǔ)法上看,編譯器并不覺(jué)得語(yǔ)句p[0]=‘X’有什么不妥,但是該語(yǔ)句企圖修改常量字符串的內(nèi)容而導(dǎo)致chara[]= a[0]=cout<<a<<char*p p[0] cout<<p<<內(nèi)容與比不能對(duì)數(shù)組名進(jìn)行直接與比較。示例7-3-2中,若想把數(shù)組a的內(nèi)容給數(shù)組b,不能用語(yǔ)句b=a,否則將產(chǎn)生編譯錯(cuò)誤。應(yīng)該用標(biāo)準(zhǔn)庫(kù)函數(shù)strcpy進(jìn)行。同理,比較b和a的內(nèi)容是否相同,不能用if(b==a)來(lái)判斷,應(yīng)該用標(biāo)準(zhǔn)庫(kù)函數(shù)strcmp進(jìn)行比較。語(yǔ)句p=a并不能把a(bǔ)的內(nèi)容指針p,而是把a(bǔ)的地址賦給了p。要想a的內(nèi)容,可以先用庫(kù)函數(shù)malloc為p申請(qǐng)一塊容量為strlen(a)+1個(gè)字符的內(nèi)存,再用strcpy進(jìn)行字符串。同理,語(yǔ)句if(p==a)比數(shù)組chara[]="charstrcpy(b,a); //不能用b=a;if(strcmp(b,a0)//不能用if(ba)…指針intlen=char*pchar*)malloc(sizeof(char)*(len+1)); //不要用p=a;if(strcmp(p,a0)//if(p…示例7-3-2數(shù)組和指針的內(nèi)容與比組a的容量是多少,sizeof(a)始終等于sizeof(char*)。chara[]= ochar*p=coutsizeof(aendl;//12字節(jié)cout<<sizeof(p)<<endl;//4字節(jié)voidFunc(char{coutsizeof(aendl;//4字節(jié)而不是100}示例7-3-3(b)數(shù)組為指voidGetMemory(char*p,int{p=(char*)malloc(sizeof(char)*}void{char*str=GetMemory(str,100); strNULLstrcpy(str,"o");//運(yùn)行錯(cuò)誤}毛病出在函數(shù)Getemoy中。編譯器總是要為函數(shù)的每個(gè)參數(shù)制作臨時(shí)副本,指針參數(shù)p的副本是編譯器使_p=p。如果函數(shù)體內(nèi)的程序修改了p的內(nèi)容,就導(dǎo)致參數(shù)p的內(nèi)容作相應(yīng)的修改。這就是指針可以用作輸出參數(shù)的原因。在本例中,p申請(qǐng)了新的內(nèi)存,只是把p所指的內(nèi)存地址改變了,但是p絲毫未變。所以函數(shù)GetMeory并不能輸出任何東西。事實(shí)上,每執(zhí)行一次GetMeory就會(huì)一塊內(nèi)存,因沒(méi)有用釋放內(nèi)。voidGetMemory2(char**p,int{*p=(char*)malloc(sizeof(char)*}char*GetMemory3(int{char*p=(char*)malloc(sizeof(char)*num);returnp;}void{char*str=str=GetMemory3(100);strcpy(str,"o");cout<<str<<endl;}char{charp[]="oreturnp;//}void{char*str=strGetString();//strcout<<str<<}用調(diào)試器逐步Test4,發(fā)現(xiàn)執(zhí)行str=GetString語(yǔ)句后str不再是NULL指針,但是str的內(nèi)容不是“char{char*p="oworld";returnp;}void{char*str=NULL;str=GetString2();cout<<str<<} (pNULL)進(jìn)行防錯(cuò)處理。很遺憾,此時(shí)if語(yǔ)句起不到防錯(cuò)作用,因?yàn)榧幢鉷不是NULL指針,它也不指char*p=(char*)strcpy(p,“ p所指的內(nèi)存被釋放,但是p…if(pNULL)//{strcpy(p,“world”);//}
示例7-5p針變量,它消亡的時(shí)候會(huì)讓它所指的動(dòng)態(tài)內(nèi)存一起。這是錯(cuò)覺(jué)!void{char*pchar*)malloc(100} char*p=char*str=(char*) class{voidFunc(void){cout<<“FuncofclassA”<<endl;void{A{Ap a} p是“野指針} 為什么還要new/delete對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言,光用maloc/動(dòng)態(tài)對(duì)象的要求。對(duì)象在創(chuàng)建的同時(shí)要自執(zhí)行構(gòu)造函數(shù),對(duì)象在消亡之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)。由于malloc/ class{publicObj(void){cout<<“Initialization”<<endl;~Obj(void){cout<<“Destroy”<<endl; Initialize(void){cout<<“Initialization”<<endl;} Destroy(void){cout<<“Destroy”<<endl;}void {Obj*a(obj*)malloc(sizeof(obj));// a->Destroy();// }void{Obj*anewObj;//delete }類Obj的函數(shù)Initialize模擬了構(gòu)造函數(shù)的功能,函數(shù)Destroy模擬了析構(gòu)函數(shù)的功能。函數(shù) 和ew將返回NULL指針,內(nèi)存申請(qǐng)失void{A*a=newA;if(a=={}…}void{A*a=newA;if(a=={cout<<“MemoryExhausted”<<endl;}…}為new和malloc設(shè)置異常處理函數(shù)。例如VisualC++可以用_set_new_hander函數(shù)為new設(shè)置用戶自 與ew相同的異常處理函數(shù)。詳細(xì)內(nèi)容請(qǐng)參考C++使用手有一個(gè)很重要的現(xiàn)象要告訴大家。對(duì)于32位以上的應(yīng)用程序而言,無(wú)論怎樣使用與ew,幾乎不可能導(dǎo)致“內(nèi)存耗盡”。我在Windows98下用VisualC++編寫了測(cè)試程序,見(jiàn)示例7-9。這個(gè)程序會(huì)無(wú)休只聽(tīng)到硬盤嘎吱嘎吱地響,Window98已經(jīng)累得對(duì)鍵盤、鼠標(biāo)毫無(wú)反應(yīng)。void{float*p=NULL;{p=new cout<<“eatmemory”<<endl;}}
void*malloc(size_tint*p=(int*)malloc(sizeof(int)*malloc返回值的類型是void*,所以在調(diào)用malloc時(shí)要顯式地進(jìn)行類型轉(zhuǎn)換,將void*轉(zhuǎn)換成所住int,float等數(shù)據(jù)類型的變量的確切字節(jié)數(shù)。例如int變量在16位系統(tǒng)下是2個(gè)字節(jié),在32位下是4個(gè)cout<<sizeof(char)<<endl;cout<<sizeof(int)<<cout<<sizeof(unsignedint)<<endl;cout<<sizeof(long)<<endl;cout<<sizeof(unsignedlong)<<endl;cout<<sizeof(float)<<endl;cout<<sizeof(double)<<endl;cout<<sizeof(void*)<<endl;在malloc的“()”中使用sizeofpmalloc(sizeofvoid(void*memblock (p)能正確地釋放內(nèi)存。如果p是NULL指針,那么對(duì)p無(wú)論操作多少次都不會(huì)出問(wèn)題。如果p不是NULL指針,那么對(duì)p連續(xù)操作兩次就會(huì)導(dǎo)致程序運(yùn)行錯(cuò)誤。int*p1=(int*)malloc(sizeof(int)*int*p2=new建動(dòng)態(tài)對(duì)象的同時(shí)完成了初始化工作。如果對(duì)象有多個(gè)構(gòu)造函數(shù),那么new的語(yǔ)句也可以有多種形式。class{public Obj(int …}void{Obj*a=newObj*bnew 初值為…deletea;delete}Obj*objects=newObj[100]; Obj*objectsnewObj[100](1);//創(chuàng)建100個(gè)動(dòng)態(tài)對(duì)象的同時(shí)賦初值1delete delete 我認(rèn)識(shí)不少技術(shù)不錯(cuò)的C++/C程序員,很少有人能拍拍胸脯說(shuō)通曉指針與內(nèi)存管理(包括)。我最初學(xué)習(xí)C語(yǔ)言時(shí)特別怕指針,導(dǎo)致我開(kāi)發(fā)第一個(gè)應(yīng)用軟件(約1萬(wàn)行C代碼)時(shí)沒(méi)有使用一個(gè)指針,全自然語(yǔ)言中,一個(gè)詞可以有許多不同的含義,即該詞被重載了。人們可以通過(guò)上下文來(lái)判斷該詞到底是哪種含義。“詞的重載”可以使語(yǔ)言更加簡(jiǎn)練。例如“吃飯”的含義十分廣泛,人們沒(méi)有必要每次非得說(shuō)在C++程序中,可以將語(yǔ)義、功能相似的幾個(gè)函數(shù)用同一個(gè)名字表示,即函數(shù)重載。這樣便于,提高了函數(shù)的易用性,這是C++語(yǔ)言采用重載機(jī)制的一個(gè)理由。例如示例8-1-1中的函數(shù)voidvoidvoidEat(Beef//可以改 voidEat(Fish//可以改 voidEat(Chicken示例8-1-1重載函數(shù)C++語(yǔ)言采用重載機(jī)制的另一個(gè)理由是:類的構(gòu)造函數(shù)需要重載機(jī)制。因?yàn)镃++規(guī)定構(gòu)造函數(shù)與類同voidintFunctionintx=Functionvoidfoo(intx,intextern{voidfoo(intx,int}extern{#include其它C}開(kāi)發(fā)商已經(jīng)對(duì)C標(biāo)準(zhǔn)庫(kù)的頭文件作了extern“C”處理,所以我們可以用#include直接這些頭文件void classvoid } //示例813中,第一個(gè)ouput函數(shù)的參數(shù)是int類型,第二個(gè)outut函數(shù)的參數(shù)是float類型。由于數(shù)字本身沒(méi)有類型,將數(shù)字當(dāng)作參數(shù)時(shí)將自動(dòng)進(jìn)行類型轉(zhuǎn)換(稱為隱式類型轉(zhuǎn)換)。語(yǔ)句outut(05)譯錯(cuò)誤,因?yàn)榫幾g器不知道該將05轉(zhuǎn)換成int還是float類型的參數(shù)。隱式類型轉(zhuǎn)換在很多地方可以簡(jiǎn)化#includevoidoutputint voidoutput(floatx);//voidoutput(int{cout<<"outputint"<<x<<endl}voidoutput(float{cout<<"outputfloat"<<x<<endl}void{intx=1;floaty=1.0; //outputint //outputfloat //outputint// error!ambiguouscalloutput(int(0.5));//outputintoutput(float(0.5));//outputfloat}#includeclass{voidf(intx){cout<<"Base::f(int)"<<x<<endl;}voidf(floatx){cout<<"Base::f(float)"<<x<<endl;}virtualvoidg(void){cout<<"Base::g(void)"<<classDerived:public{virtualvoidg(void){cout<<"Derived::g(void)"<<void{DerivedBase*pb= //Base::f(int) //Base::f(float) //}#includeclass{virtualvoidf(floatx){cout<<"Base::f(float)"<<x<<endl;}voidg(floatx){cout<<"Base::g(float)"<<x<<endl;}voidh(floatx){cout<<"Base::h(float)"<<x<<endl;classDerived:public{virtualvoidf(floatx){cout<<"Derived::f(float)"<<x<<endl;}voidg(intx){cout<<"Derived::g(int)"<<x<<endl;}voidh(floatx){cout<<"Derived::h(float)"<<x<<endl;voidvoid{DerivedBase*pb=Derived*pd=//Good:behaviordependssolelyontypeoftheobjectpb->f(3.14f);//Derived::f(float)3.14pd->f(3.14f);//Derived::f(float)//Bad:behaviordependsontypeofthepointerpb->g(3.14f);//Base::g(float)3.14pd->g(3.14f);//Derived::g(int) //Bad:behaviordependsontypeofthepointerpb->h(3.14f);//Base::h(float)3.14 pd->h(3.14f);//Derived::h(float)3.14}
隱藏規(guī)則引起了不少麻煩。示例8-2-3程序中,語(yǔ)句pd->f(10)的本意是想調(diào)用函數(shù)Base::f(int),但是Base::f(int)不幸被Derived::f(char*)隱藏了。由于數(shù)字10不能被隱式地轉(zhuǎn)化為字符串,所以在編譯時(shí)出class{voidf(intclassDerived:public{voidf(charvoid{Derived*pd=newDerived; //error}寫語(yǔ)句pd->f(10)的人可能真的想調(diào)用Derived::f(char*)函數(shù),只是他誤將參數(shù)寫錯(cuò)了。有了隱藏規(guī)則,編譯器就可以明確錯(cuò)誤,這未必不是好事。否則,編譯器會(huì)靜悄悄地將錯(cuò)就錯(cuò),程序員classDerived:public{voidf(charvoidf(intx){Base::f(x);voidFoo(intx=0,int //正確,缺省值出現(xiàn)在函數(shù)的voidFoo(intx=0,int {…}為什么會(huì)這樣?是有兩個(gè)原因:一是函數(shù)的實(shí)現(xiàn)(定義)本來(lái)就與參數(shù)是否有缺省值無(wú)關(guān),所以沒(méi)有必要讓缺省值出現(xiàn)在函數(shù)的定義體中。二是參數(shù)的缺省值可能會(huì)改動(dòng),顯然修改函數(shù)的比修改函voidFoo(intx,inty=0,intvoidFoo(intx=0,inty,int當(dāng)產(chǎn)生效果。示例8-3-2中,不合理地使用參數(shù)的缺省值將導(dǎo)致重載函數(shù)output產(chǎn)生二義性。#includevoidoutput(intvoidoutput(intx,floatvoidoutput(int{cout<<"outputint"<<x<<endl}voidoutput(intx,float{cout<<"outputint"<<x<<"andfloat"<<y<<endl}void{intx=1;//output(x); //error!ambiguouscall //outputint1andfloat0.5} ComplexAdd(constComplex&a,constComplexComplexoperator+(constComplex&a,constComplexComplexa,b,…cAdd(a,b);ca 從語(yǔ)法上講,運(yùn)算符既可以定義為全局函數(shù),也可以定義為成員函數(shù)。文獻(xiàn)[Murrayp44-p47]對(duì)此問(wèn)=()[]-+=-=/=*=&=|=~=%=>>=C++語(yǔ)言支持函數(shù)內(nèi)聯(lián),其目的是為了提高函數(shù)的執(zhí)行效率(速度)在C程序中,可以用宏代碼提高執(zhí)行效率。宏代碼本身不是函數(shù),但使用起來(lái)象函數(shù)。預(yù)處理器用復(fù)制宏代碼的方式代替函數(shù)調(diào)用,省去了參數(shù)壓棧、生成匯編語(yǔ)言的ALL調(diào)用、返回參數(shù)、執(zhí)行return等過(guò)程,從而提高了速度。使用宏代碼最大的缺點(diǎn)是容易出錯(cuò),預(yù)處理器在宏代碼時(shí)常常產(chǎn)生意想不#defineMAX(a, (a)>(b)?(a):result=MAX(i,j)+2result=(i)>(j)?(i):(j)+2result=((i)>(j)?(i):(j))+2#defineMAX(a, ((a)>(b)?(a):(b)result=MAX(i++,result=(i++)>(j)?(i++):C++語(yǔ)言的函數(shù)內(nèi)聯(lián)機(jī)制既具備宏代碼的效率,又增加了安全性,而且可以自由操作類的數(shù)據(jù)成員。所以在C++程序中,應(yīng)該用內(nèi)聯(lián)函數(shù)取代所有宏代碼,“斷言assert”恐怕是唯一的例外。assertDebuginlinevoidFoo(intx,int //inline僅與函數(shù)放在一voidFoo(intx,int{…}voidFoo(intx,intinlinevoidFoo(intx,inty)//inline{…}函數(shù)的,但是看不到函數(shù)的定義。盡管在大多數(shù)教科書中內(nèi)聯(lián)函數(shù)的、定義體前面都加了 class{voidFoo(intx,inty) }class{voidFoo(intx,int}inlinevoidA::Foo(intx,int{…}內(nèi)聯(lián)是以代碼膨脹()為代價(jià),僅僅省去了函數(shù)調(diào)用的開(kāi)銷,從而提高函數(shù)的執(zhí)行效率。如果執(zhí)函數(shù)的調(diào)用都要代碼,將使程序的總代碼量增大,消耗的內(nèi)存空間。以下情況不宜使用內(nèi)聯(lián):C++語(yǔ)言中的重載、內(nèi)聯(lián)、缺省參數(shù)、隱式轉(zhuǎn)換等機(jī)制展現(xiàn)了很多優(yōu)點(diǎn),但是這些優(yōu)點(diǎn)的背后都隱藏 A(constA A&operateconstA class{String(constchar*str String(constString ~ String&operateconstString 作為比C更先進(jìn)的語(yǔ)言,C++提供了更好的機(jī)制來(lái)增強(qiáng)程序的安全性。C++編譯器具有嚴(yán)格的類型安全檢查功能,它幾乎能找出程序中所有的語(yǔ)法問(wèn)題,這的確幫了程序員的大忙。但是程序通過(guò)了編譯檢查并不表示錯(cuò)誤已經(jīng)不存在了,在“錯(cuò)誤”的大家庭里,“語(yǔ)法錯(cuò)誤”的地位只能算是小弟弟。級(jí)別高的錯(cuò)工作很容易遺忘。Stroustrup在設(shè)計(jì)C++語(yǔ)言時(shí)充分考慮了這個(gè)問(wèn)題并很好地予以解決:把對(duì)象的初構(gòu)造函數(shù)與析構(gòu)函數(shù)的名字不能隨便起,必須讓編譯器認(rèn)得出才可以被自動(dòng)執(zhí)行。Stroustrup名除了名字外,構(gòu)造函數(shù)與析構(gòu)函數(shù)的另一個(gè)特別之處是沒(méi)有返回值類型,這與返回值類型為void的函數(shù)不同。構(gòu)造函數(shù)與析構(gòu)函數(shù)的使命非常明確,就象出生與,光溜溜地來(lái)光溜溜地去。如果它們有返回值類型,那么編譯器將不知所措。為了防止節(jié)外生枝,干脆規(guī)定沒(méi)有返回值類型。(kel,p55p6])之后,卻在函數(shù)體{}之前。這說(shuō)明該表里的初始化工作發(fā)生在函數(shù)體內(nèi)的任何代碼被執(zhí)行之前。classA(int AclassB:publicB(intx,inty);//BB::B(intx,int //{…}class A(constA A&operateconstA class{B(constA&a); A B::B(constB::B(constA{m_a=…}B::B(constA:{…}示例9-2(a)成員對(duì)象在初始化表中被初始 示例9-2(b)成員對(duì)象在函數(shù)體內(nèi)被初始class{F(intx,int intm_x,m_y;intm_i,m_j;}F::F(intF::F(intx,int{m_x=x;m_y=y;m_i=0;m_j=}F::F(intx,int:m_x(x),{m_i=m_j=}示例9-2(c)數(shù)據(jù)成員在初始化表中被初始 示例9-2(d)數(shù)據(jù)成員在函數(shù)體內(nèi)被初始[Eckel,p260-261]//String的普通構(gòu)造函數(shù)String::String(constchar*str){{m_data=new*m_data=}{intlength=strlen(str);m_data=newchar[length+1];strcpy(m_data,str);}}//String的析構(gòu)函數(shù){delete[]由于m_datadelete}現(xiàn)將a賦給b,缺省賦值函數(shù)的“位拷貝”意味著執(zhí)行b.m_data=a.m_data。這將造成三個(gè)錯(cuò)誤:一是b.m_data原有的內(nèi)存沒(méi)被釋放,造成內(nèi)存;二是b.m_data和a.m_data指向同一塊內(nèi)存,a或b任何一Stringa(“StringStringc=a; c(a);c=b;//調(diào)用了賦值函數(shù))String::String(constString{允許操作other的私有成員m_dataintlength=strlen(other.m_data);m_data=newchar[length+1];strcpy(m_data,other.m_data);}String&String::operate=(constString{//(1)檢查自賦值if(this&other)return*this;(2)delete[]//(3)分配新的內(nèi)存資源,并內(nèi)容intlength=strlen(other.m_data);m_data=newchar[length+1];strcpy(m_data,return}類String拷貝構(gòu)造函數(shù)與普通構(gòu)造函數(shù)(參見(jiàn)9.4節(jié))的區(qū)別是:在函數(shù)處無(wú)需與NULL進(jìn)行比較,這是因?yàn)椤啊辈豢赡苁荖ULL,而“指針”可以為NULL。aa這樣的自賦值語(yǔ)句!b=b=……c=a=…a=if(this==if(*this==束符‘\0’。函數(shù)strcpy則連‘\0’一起。第四步,返回本對(duì)象的,目的是為了實(shí)現(xiàn)象a=b=c這樣的鏈?zhǔn)奖磉_(dá)。注意不要將*thisreturnthis。那么能否寫成returnother那么returnother返回的將是。class{…A(constA A&operateconstA A b #includeclass{virtual~Base(){cout<<"~Base"<<endl;classDerived:public{virtual~Derived(){cout<<"~Derived"<<endl;void{Base*pB=newDerived;//upcastdeletepB;}class{…Base&operate(constBase 類Baseintm_i,m_j,classDerived:public{…Derived&operateconstDerived //intm_x,m_y,Derived&Derived::operate=(constDerived{if(this==&other)returnBase::operate m_x=other.m_x;m_y=other.m_y;m_z=return*this;}Three”,請(qǐng)好好閱讀參考文獻(xiàn)[Cline][Meyers][Murry]。class{
voidFunc1(void);voidclassB:public{
voidFunc3(void);void{B //B從A繼承了函數(shù)Func1 //B從A繼承了函數(shù)Func2}屬性。不要覺(jué)得“白吃白不吃”,讓一個(gè)好端端的健壯青年無(wú)緣無(wú)故地參補(bǔ)身體?!疽?guī)則10-1-2】若在邏輯上B是A的“一種”(akindof),則允許B繼承Aclass{…classMan:public{…classBoy:public{…class{virtualvoid…classOstrich:public{…【規(guī)則10-2-1】若在邏輯上A是B的“一部分”(apartof),則不允許B從A派生,用A和class{voidclass{voidclass{voidclass{voidclass{ {m_eye.Look();} {m_nose.Smell();} Eat(void){m_mouth.Eat();} {m_ear.Listen(); Mouthm_mouth; m_ear;如果允許Head從Eye、Nose、Mouth、Ear派生而成,那么Head將自動(dòng)具有LookSmell、Eat、Listen這classHead:publicEye,publicNose,publicMouth,public{ const定義常量,那么相當(dāng)于把僅用于制作鞭。const更大的是它可以修飾函數(shù)的參數(shù)、返回動(dòng),能提高程序的健壯性。所以很多C++程序設(shè)計(jì)書籍建議:“Useconstwheneveryouneed”。voidStringCopy(char*strDestination,constchar例如不要將函數(shù)voidFunc1(intx)寫成voidFunc1(constintx)。同理不要將函數(shù)voidFunc2(Aa)寫成voidFunc2(constAa)。其中A為用戶自定義的數(shù)據(jù)類型。對(duì)于非內(nèi)部數(shù)據(jù)類型的參數(shù)而言,象voidFunc(Aa)這樣的函數(shù)注定效率比較底。因?yàn)楹瘮?shù)體內(nèi)將產(chǎn)生A類型的臨時(shí)對(duì)象用于參數(shù)a,而臨時(shí)對(duì)象的構(gòu)造、、析構(gòu)過(guò)程都將消耗時(shí)為了提高效率,可以將函數(shù)改為voidFunc(A&a),因?yàn)椤皞鬟f”僅借用一下參數(shù)的別名而已,不需要產(chǎn)生臨時(shí)對(duì)象。但是函數(shù)voidFunc(A&a)存在一個(gè)缺點(diǎn):“傳遞”有可能改變參數(shù)a,這是我們不期望的。解決這個(gè)問(wèn)題很容易,加const修飾即可,因此函數(shù)最終成為voidFunc(constA&a)。以此類推,是否應(yīng)將voidFunc(intx)改寫為voidFunc(constint&x),以便提高效率?完全沒(méi)有必要,因率。例如將voidFunc(Aa改為voidFunc(constA&a)效率的目的,又降低了函數(shù)的可理解性。例如voidFunc(intx)不應(yīng)該改為voidFunc(constint&x)表11-1-1“const&”constchar*char*str=constchar*str=例如函數(shù)intGetInt(void)寫成constintGetInt(void)同理函數(shù)AGetA(void)寫成constAGetA(void),其中A為用戶自定義的數(shù)據(jù)類型如果返回值不是內(nèi)部數(shù)據(jù)類型,將函數(shù)AGetA(void)改寫為constA&GetA(void)的確能提高效率。但此時(shí)千萬(wàn)千萬(wàn)要,一定要搞清楚函數(shù)究竟是想返回一個(gè)對(duì)象的“拷貝”還是僅返回“別名”就可以了,classA&operate(constA Aa,b, a,b,c為A…ab (ab) 如果將賦值函數(shù)的返回值加constabc仍然正確,但是語(yǔ)句(a=b)=c則是的。classStack{ GetCount(void)const;//const成員函數(shù) intStack::GetCount(void){++m_num;//編譯錯(cuò)誤,企圖修改數(shù)據(jù)成員m_num //編譯錯(cuò)誤,企圖調(diào)用非const函數(shù)return}[Cline]MarshallP.ClineandGregA.Lomow,C++FAQs,Addison-Wesley,[Eckel]BruceEckel,ThinkinginC++(C++編程思想,等譯),機(jī)械工業(yè),2000[Maguire]SteveMaguire,WritingCleanCode(編程精粹,等譯),電子工業(yè),1993[Meyers]ScottMeyers,EffectiveC++,Addison-Wesley,1992[Murry]RobertB.Murry,C++StrategiesandTactics,Addison-Wesley,[Summit]SteveSummit,CProgrammingFAQs,Addison-Wesley,項(xiàng) 頭文件是否使用了ifndef/define/endif預(yù)處理塊項(xiàng)“{”和“}”在定義變量(或參數(shù))時(shí),是否將修飾符*類結(jié)構(gòu)的public,protected,private順序是否在所有的程序中保持項(xiàng)標(biāo)識(shí)符的長(zhǎng)度應(yīng)當(dāng)符合“min-length&&max-information”項(xiàng)是否用隱含錯(cuò)誤的方式寫if語(yǔ)句?使用goto語(yǔ)句時(shí)是否留下隱患?例如跳過(guò)了某些對(duì)象的構(gòu)造、變項(xiàng)+項(xiàng)使用了assert?例如情況與錯(cuò)誤情況,后者是必然數(shù)、返回值,甚至函數(shù)的定義體?!癠seconstwheneveryou項(xiàng) 或ew申請(qǐng)內(nèi)存之后,是否立即檢查指針值是否為 和new/delete使用C++項(xiàng)項(xiàng)是否違背編程規(guī)范而讓C+編譯器自動(dòng)為類產(chǎn)生四個(gè)缺省的函內(nèi)存資源;(3)分配新的內(nèi)存資源,并內(nèi)容;(4)返回項(xiàng)若在邏輯上A是B的“一部分”(apartof),則不允許B從項(xiàng)一、請(qǐng)?zhí)顚態(tài)OOLfloat,“零值”if語(yǔ)句。(10分提示:這里“零值”可以是0,0.0FALSE或者“空指針”intn與“零值”ifif(n==0if(n!=0BOOLflag與“零值”iffloatx與“零值”ifchar*p與“零值”ifcharstr[]=o”voidFunc(char{sizeof(str)}char*p=str n=sizeof(str)sizeof(p)void*p=malloc(100sizeof(n)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國(guó)伏格列波糖數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2025-2030年(全新版)中國(guó)纖維食品市場(chǎng)未來(lái)發(fā)展趨勢(shì)及前景調(diào)研分析報(bào)告
- 2025-2030年中國(guó)順酐市場(chǎng)運(yùn)行動(dòng)態(tài)分析與營(yíng)銷策略研究報(bào)告
- 2025-2030年中國(guó)防水建材市場(chǎng)運(yùn)行現(xiàn)狀及發(fā)展前景預(yù)測(cè)報(bào)告
- 2025-2030年中國(guó)輪轂電機(jī)驅(qū)動(dòng)電動(dòng)汽車行業(yè)未來(lái)發(fā)展趨勢(shì)及前景調(diào)研分析報(bào)告
- 塑料在通訊設(shè)備材料的應(yīng)用考核試卷
- 園林金屬工具企業(yè)文化建設(shè)考核試卷
- 傳動(dòng)軸的扭轉(zhuǎn)振動(dòng)分析與控制考核試卷
- 2025年度文化創(chuàng)意產(chǎn)業(yè)園區(qū)運(yùn)營(yíng)勞務(wù)合同
- 供應(yīng)鏈案例分析模板考核試卷
- 對(duì)講機(jī)外殼注射模設(shè)計(jì) 模具設(shè)計(jì)及制作專業(yè)
- 2024年四川省德陽(yáng)市中考道德與法治試卷(含答案逐題解析)
- 施工現(xiàn)場(chǎng)水電費(fèi)協(xié)議
- SH/T 3046-2024 石油化工立式圓筒形鋼制焊接儲(chǔ)罐設(shè)計(jì)規(guī)范(正式版)
- 六年級(jí)數(shù)學(xué)質(zhì)量分析及改進(jìn)措施
- 一年級(jí)下冊(cè)數(shù)學(xué)口算題卡打印
- 真人cs基于信號(hào)發(fā)射的激光武器設(shè)計(jì)
- 【閱讀提升】部編版語(yǔ)文五年級(jí)下冊(cè)第三單元閱讀要素解析 類文閱讀課外閱讀過(guò)關(guān)(含答案)
- 四年級(jí)上冊(cè)遞等式計(jì)算練習(xí)200題及答案
- 法院后勤部門述職報(bào)告
- 2024年國(guó)信證券招聘筆試參考題庫(kù)附帶答案詳解
評(píng)論
0/150
提交評(píng)論