




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
C語(yǔ)言編程規(guī)范內(nèi)部資料 第12頁(yè) 注意保密文檔名稱文檔版本號(hào):V1.1文檔編號(hào):文檔密級(jí):保密歸屬部門/項(xiàng)目:開發(fā)二部產(chǎn)品名:C編碼規(guī)范子系統(tǒng)名:NA編寫人:陳小洪編寫日期:2004-11-11卓望數(shù)碼技術(shù)(深圳)有限公司版權(quán)所有內(nèi)部資料注意保密
所有權(quán)聲明本文檔的內(nèi)容將做定期性的變動(dòng),且不另行通知。更改的內(nèi)容將會(huì)補(bǔ)充到本手冊(cè)中。除特別聲明外,此文檔所用的公司名稱、個(gè)人姓名及數(shù)據(jù)均屬為說(shuō)明的目的而模擬。本文檔的版權(quán)屬卓望數(shù)碼技術(shù)(深圳)有限公司(本公司)所有,受中華人民共和國(guó)法律的保護(hù)。本文檔所含的任何構(gòu)思、設(shè)計(jì)、工藝及其他技術(shù)信息均屬本公司所有,受中華人民共和國(guó)法律的保護(hù)。未經(jīng)本公司書面同意,任何單位和個(gè)人不得擅自摘抄、全部或部分復(fù)制本書內(nèi)容,或者以其他任何方式使第三方知悉。MISC?為卓望數(shù)碼技術(shù)(深圳)有限公司所有,不得仿冒。修訂記錄:版本號(hào)修訂人修訂日期修訂描述V1.1陳小洪2004-11-11
目錄TOC\o"1-6"\h\z第一章介紹 2第二章編碼規(guī)范 21總則 21.1功能模塊編碼原則 21.2編程標(biāo)準(zhǔn) 21.3頭文件標(biāo)準(zhǔn) 21.4源代碼層次 22命名約定 22.1類型命名 22.2變量命名 22.3函數(shù)及數(shù)組的命名 22.4宏命名 22.5命名長(zhǎng)度 23程序規(guī)則 23.1常量的聲明和定義 23.1.1常量定義規(guī)則 23.1.2為常量聲明宏 23.2變量聲明和定義 23.2.1注意要點(diǎn) 23.2.2初始化 23.3函數(shù)聲明和定義 23.3.1參數(shù)的規(guī)則 23.3.2返回值的規(guī)則 23.3.3函數(shù)內(nèi)部實(shí)現(xiàn)的規(guī)則 23.3.4其它 23.4語(yǔ)句 23.4.1if語(yǔ)句 變量與常量的比較 布爾變量與零值比較 整型變量與零值比較 浮點(diǎn)變量與零值比較 指針變量與零值比較 對(duì)if語(yǔ)句的補(bǔ)充說(shuō)明 23.4.2for語(yǔ)句的循環(huán)控制變量 23.4.3switch語(yǔ)句 23.4.4禁止語(yǔ)句 23.5返回碼 24排版格式規(guī)則 24.1空行 24.2代碼行 24.3代碼行內(nèi)的空格 24.4分行 24.5對(duì)齊 24.6修飾符的位置 24.7預(yù)處理(宏) 24.8變量、類型聲明 25注釋格式 25.1模塊注釋 25.2函數(shù)注釋 25.3修改代碼的注釋 25.4其它注釋 26程序的安全 26.1基本的數(shù)據(jù)定義 26.2函數(shù)安全 26.3內(nèi)存安全 26.4數(shù)組、指針、字符串 26.4.1注意要點(diǎn) 26.4.2初始化 27程序的效率 27.1注意要點(diǎn) 27.2循環(huán)語(yǔ)句的效率 2第三章代碼管理 21目錄管理 22文件管理 2第四章縮寫規(guī)則 2第五章附錄A:部分單詞的縮寫列表 2第六章附錄B:C代碼審查表 2
介紹本文的宗旨在于規(guī)范化源代碼的編寫,滿足系統(tǒng)結(jié)構(gòu)化要求、可讀性要求、正確性與容錯(cuò)性要求和可重用性要求。規(guī)則是最低要求,建議是更高標(biāo)準(zhǔn)。適用范圍:本文檔描述C語(yǔ)言編程規(guī)范,該規(guī)范僅用于指導(dǎo)開發(fā)二部基于標(biāo)準(zhǔn)C的系統(tǒng)的代碼編制。注:該規(guī)范類型分為兩類,一是規(guī)則,二是建議,。一位有修養(yǎng)的程序員應(yīng)該有以下幾方面的素質(zhì):
1、有專研精神,勤學(xué)善問(wèn)、舉一反三。
2、積極向上的態(tài)度,有創(chuàng)造性思維。
3、與人積極交流溝通的能力,有團(tuán)隊(duì)精神。
4、謙虛謹(jǐn)慎,戒驕戒燥。
5、寫出的代碼質(zhì)量高。包括:代碼的穩(wěn)定、易讀、規(guī)范、易維護(hù)、專業(yè)。您做到了嗎??
編碼規(guī)范總則功能模塊編碼原則【規(guī)則2-1-1】程序要簡(jiǎn)單,直接了當(dāng),代碼精簡(jiǎn)?!窘ㄗh2-1-2】盡量使用標(biāo)準(zhǔn)庫(kù)函數(shù)和公共函數(shù)?!疽?guī)則2-1-3】不要隨意定義全局變量,盡量使用局部變量。【規(guī)則2-1-4】使用括號(hào)以避免二義性。【規(guī)則2-1-6】避免不必要的分支?!疽?guī)則2-1-7】嚴(yán)禁長(zhǎng)期占有CPU,在使用死循環(huán)時(shí),必須要考慮將時(shí)間片讓出去,不要搶占系統(tǒng)資源。編程標(biāo)準(zhǔn)【2-1-8】不要使用完全依賴于某個(gè)特定編譯器的特性,不要使用C++語(yǔ)法,即使編譯器支持?!疽?guī)則2-1-9】最重要的目標(biāo)是程序的可讀性和可維護(hù)性。一個(gè)程序有唯一的出口和入口。不要到處用exit()盡量簡(jiǎn)化main(),不要超過(guò)60行.頭文件標(biāo)準(zhǔn)【規(guī)則2-1-10】只有那些被大量公用的部分才可以定義為宏,放在頭文件中;其他包括程序中大量使用的類型,外部函數(shù)原型,公用的全程變量聲明等等。注意要使每個(gè)源文件都可以使用這個(gè)公共的頭文件。每一項(xiàng)只聲明一次。并且要保證一個(gè)頭文件在一個(gè)文件中只被真正的包含一次。例如:smpp.h的格式應(yīng)該這樣: #ifndef__SMPP_H #define__SMPP_H………. #endif//__SMPP_H【規(guī)則2-1-11】在使用系統(tǒng)庫(kù)函數(shù)和系統(tǒng)變量時(shí)要引用系統(tǒng)頭文件,系統(tǒng)頭文件是獨(dú)立于應(yīng)用之外維護(hù)的。【規(guī)則2-1-12】頭文件順序:首先是系統(tǒng)頭文件,然后是項(xiàng)目頭文件,最后是程序頭文件【建議2-1-13】每個(gè)模塊最好只包含一個(gè)系統(tǒng)頭文件。源代碼層次【規(guī)則2-1-14】按照以下要求組織源代碼:版本版權(quán)聲明模塊注釋引用系統(tǒng)頭文件引用項(xiàng)目頭文件引用本程序頭文件常量宏參數(shù)宏固有類型聲明(指針、數(shù)組等,如:typedeflongLongArr[MacMaxNumber])復(fù)雜類型定義(結(jié)構(gòu)、聯(lián)合等,如:typedefstuctdaterecDate)函數(shù)聲明:所有要使用的函數(shù)都要先聲明后使用。如果一個(gè)函數(shù)未在頭文件中聲明,則必須在本程序中完成。如果僅僅是本模塊調(diào)用的函數(shù),則應(yīng)該只在本模塊源代碼內(nèi)部定義。只有那些由本程序內(nèi)部多個(gè)模塊調(diào)用的函數(shù)放在全程變量區(qū)聲明。函數(shù)聲明的順序如下:外部函數(shù)內(nèi)部函數(shù)外部變量聲明;本模塊全程變量定義,注意要加適當(dāng)?shù)淖⑨寖?nèi)部函數(shù)體,每個(gè)函數(shù)前要加注釋塊.順序如下:main()(如果存在).高層函數(shù)定義,如初始化函數(shù)、主處理函數(shù)、結(jié)束函數(shù)底層函數(shù)定義,要符合一個(gè)從高到低的邏輯。命名約定類型命名【規(guī)則2-2-1】使用typedef進(jìn)行定義。結(jié)構(gòu)體類型名加前綴rec、枚舉類型前加enu。例如: typedefstructt_Date{ intnYear; intnMonth; intnDay; }recDate; typedefenum{EFirst,ESecond,Ethird}enuSet;和系統(tǒng)相關(guān)的類型用typedef定義。如:typedefintsocket_ttypedefintshm_ttypedefintsem_ttypedefintmutex_t這樣在代碼移植和維護(hù)時(shí)不容易產(chǎn)生錯(cuò)誤變量命名【規(guī)則2-2-2】前綴規(guī)則:變量類型簡(jiǎn)寫說(shuō)明charch所有的字符變量均以ch開始cyteb所有的字節(jié)變量均以b開始longl所有的長(zhǎng)整型變量均以l開始intn所有的整型變量均以n開始size_tsize所有的空間尺寸變量均以size開始voidv所有的無(wú)類型變量均以v開始unsignedu所有的無(wú)符號(hào)變量均以u(píng)開始shortsh所有的短整型變量均以sh開始char[]s所有字符串變量均以s開始floatfl所有的浮點(diǎn)型變量均以fl開始doubledl所有的雙精度型變量均以dl開始enuSete所有的枚舉變量均以e開始recDater所有的結(jié)構(gòu)變量均以r開始FILE*fp所有的文件指針變量均以fp開始示例2-1前綴規(guī)則(a)對(duì)于指向某個(gè)數(shù)據(jù)類型的指針,可以先象上面那樣建立一個(gè)類型的名字,然后給該名字加上前綴字母p:變量類型說(shuō)明char*ps指向字符變量的指針以ps開始long*pl指向長(zhǎng)整型變量的指針以pl開始int*pn指向整型變量的指針以pn開始void*pv指向無(wú)類型變量的指針以pv開始char*pps指向字符指針的指針byte*ppb指向字符指針的指針示例2-2前綴規(guī)則(b)對(duì)于全局變量,再在按上面方式命名的變量名字前加上前綴字母g:charg_ch;/*字符類型的全局變量以gch開始*/int*g_pn;/*指向整型的全局指針變量以gpn開始*/【規(guī)則2-2-3】后綴規(guī)則:對(duì)于變量的命名,除了要求在變量名中加入前綴使變量的類型一目了然之外,我們應(yīng)在前綴之后的描述中表明該變量在程序中的作用?!窘ㄗh2-2-4】標(biāo)識(shí)符應(yīng)當(dāng)直觀且可以拼讀,可望文知意,不必進(jìn)行“解碼”。
標(biāo)識(shí)符最好采用英文單詞或其組合,便于記憶和閱讀。切忌使用漢語(yǔ)拼音來(lái)命名。程序中的英文單詞一般不會(huì)太復(fù)雜,用詞應(yīng)當(dāng)準(zhǔn)確。例如不要把CurrentValue寫成NowValue?!疽?guī)則2-2-5】程序中不要出現(xiàn)僅靠大小寫區(qū)分的相似的標(biāo)識(shí)符。【規(guī)則2-2-6】程序中不要出現(xiàn)標(biāo)識(shí)符完全相同的局部變量和全局變量,盡管兩者的作用域不同而不會(huì)發(fā)生語(yǔ)法錯(cuò)誤,但會(huì)使人誤解。全局變量應(yīng)該使用g_匈牙利命名比較好?!窘ㄗh2-2-7】變量的名字應(yīng)當(dāng)使用“名詞”或者“形容詞+名詞”。floatflValue;floatflOldValue;
floatflNewValue;【建議2-2-8】用正確的反義詞組命名具有互斥意義的變量或相反動(dòng)作的函數(shù)等。
例如:
intnMinValue;
intnMaxValue;
intnSetValue(…);
intnGetValue(…);【建議2-2-9】盡量避免名字中出現(xiàn)數(shù)字編號(hào),如Value1,Value2等,除非邏輯上的確需要編號(hào)。這是為了防止程序員偷懶,不肯為命名動(dòng)腦筋而導(dǎo)致產(chǎn)生無(wú)意義的名字(因?yàn)橛脭?shù)字編號(hào)最省事)。函數(shù)及數(shù)組的命名【規(guī)則2-2-10】函數(shù)及數(shù)組的命名遵循與變量的命名大體同樣的約定,只是函數(shù)名前面不要加前綴。但是,函數(shù)如果可以明確斷定歸屬于某個(gè)模塊,應(yīng)該在類型描述后加模塊名。在數(shù)組的命名中在類型名之后加一數(shù)字以表示數(shù)組的維數(shù)。例如:charchLastKeyPressed;/*字符變量*/charsInputBuffer[];/*字符數(shù)組*/charReadKeyBoard();/*返回字符類型的函數(shù)*/intCfgReadKeyBoard();/*歸屬于Cfg模塊的返回字符類型的函數(shù)*/宏命名【規(guī)則2-2-11】常量宏全部采用大寫,單詞間隔用下劃線;例如#defineMAX_NUMBER100命名長(zhǎng)度變量名(函數(shù)名,過(guò)程名)最小長(zhǎng)度符合以下規(guī)則:【規(guī)則2-2-12】除了特例,要大于5個(gè)字符(特例包括n,m,i,j表示整數(shù),s,p,q表示字符串指針)【建議2-2-13】滿足最大規(guī)則的前提下盡量使變量名短小【規(guī)則2-2-14】最大不超過(guò)31個(gè),這是ANSI標(biāo)準(zhǔn)要求的.【規(guī)則2-2-15】保證externalfunction前6個(gè)字符在系統(tǒng)中是唯一的,如果是接口函數(shù),最好在接口函數(shù)前加上模塊名的縮寫,模塊名的縮寫是唯一的。程序規(guī)則常量的聲明和定義常量定義規(guī)則【規(guī)則2-3-1】需要對(duì)外公開的常量放在頭文件中,不需要對(duì)外公開的常量放在定義文件的頭部。為便于管理,可以把不同模塊的常量集中存放在一個(gè)公共的頭文件中?!疽?guī)則2-3-2】如果某一常量與其它常量密切相關(guān),應(yīng)在定義中包含這種關(guān)系,而不應(yīng)給出一些孤立的值。例如:constfloatRADIUS=100;constfloatDIAMETER=RADIUS*2;為常量聲明宏【建議2-3-3】最好不要在程序中出現(xiàn)數(shù)字式的“硬編碼”。如:intnUser[120];for(i=0;i<120;i++){
}#defineMAX_USR_CNT120
for(i=0;i<MAX_USER_CNT;i++){
}示例2-3(a)不良的風(fēng)格示例2-3(a)良好的風(fēng)格120是什么?為什么會(huì)是120?這種“硬編碼”不僅讓程序很難讀,而且也讓程序很不好維護(hù),如果要改變這個(gè)數(shù)字,得同時(shí)對(duì)所有程序中這個(gè)120都要做修改,這對(duì)修改程序的人來(lái)說(shuō)是一個(gè)很大的痛苦。所以還是把常量聲明成宏,這樣,一改百改,而且也很利于程序閱讀?!窘ㄗh2-3-4】出錯(cuò)信息或是提示信息,應(yīng)該統(tǒng)一處理,而不是像上面這樣,寫成一個(gè)“硬編碼”。如果要管理錯(cuò)誤信息,那就要有以下的處理:
/*聲明出錯(cuò)代碼*/
#defineERR_NO_ERROR0/*Noerror*/
#defineERR_OPEN_FILE1/*Openfileerror*/
#defineERR_SEND_MESG2/*sendingamessageerror*/
#defineERR_BAD_ARGS3/*Badarguments*/
#defineERR_MEM_NONE4/*Memeroyisnotenough*/
#defineERR_SERV_DOWN5/*Servicedowntrylater*/
#defineERR_UNKNOW_INFO6/*Unknowinformation*/
#defineERR_SOCKET_ERR7/*Socketoperationfailed*/
#defineERR_PERMISSION8/*Permissiondenied*/
#defineERR_BAD_FORMAT9/*Badconfigurationfile*/
#defineERR_TIME_OUT10/*Communicationtimeout*/
/*聲明出錯(cuò)信息*/
char*sErrmsg[]={
/*0*/"Noerror",
/*1*/"Openfileerror",
/*2*/"Failedinsending/receivingamessage",
/*3*/"Badarguments",
/*4*/"Memeroyisnotenough",
/*5*/"Serviceisdown;trylater",
/*6*/"Unknowinformation",
/*7*/"Asocketoperationhasfailed",
/*8*/"Permissiondenied",
/*9*/"Badconfigurationfileformat",
/*10*/"Communicationtimeout",
};
/*聲明錯(cuò)誤代碼全局變量*/
longlErrno=0;
/*打印出錯(cuò)信息函數(shù)*/
voidPerror(char*psInfo)
{
if(psInfo==NULL){
printf("%s:%sn",info,sErrmsg[lErrno]);
return;
}
printf("Error:%sn",sErrmsg[lErrno]);
}
這個(gè)基本上是ANSI的錯(cuò)誤處理實(shí)現(xiàn)細(xì)節(jié)了,于是當(dāng)你程序中有錯(cuò)誤時(shí)你就可以這樣處理:
boolCheckPermission(char*psUserName)
{
if(strcpy(psUserName,"root")!=0){
lErrno=ERR_PERMISSION_DENIED;
return(FALSE);
}
...
}
main()
{
...
if(!CheckPermission(psUserName)){
Perror("main()");
}
...
}
一個(gè)即有共性,也有個(gè)性的錯(cuò)誤信息處理,這樣做有利同種錯(cuò)誤出一樣的信息,統(tǒng)一用戶界面,而不會(huì)因?yàn)槲募蜷_失敗,A程序員出一個(gè)信息,B程序員又出一個(gè)信息。而且這樣做,非常容易維護(hù),代碼也易讀。
當(dāng)然,物極必反,也沒(méi)有必要把所有的輸出都放到sErrmsg中,抽取比較重要的出錯(cuò)信息或是提示信息是其關(guān)鍵,但即使這樣,這也包括了大多數(shù)的信息。變量聲明和定義注意要點(diǎn)【建議2-3-5】盡量不定義全局變量,在允許的情況下,使用函數(shù)參數(shù)的形式取代外部變量?!疽?guī)則2-3-6】當(dāng)定義全程變量時(shí),注意用注釋概要描述變量的使用。【規(guī)則2-3-7】不要定義本模塊中不用的變量或者不必要的變量。【建議2-3-8】定義結(jié)構(gòu)體的時(shí)候進(jìn)行字節(jié)對(duì)齊,盡量少定義大小不能被4、8、16字節(jié)整除的變量。如:charsName[21];//不良的風(fēng)格charsName[24];//良好的風(fēng)格初始化【規(guī)則2-3-9】一定要初始化標(biāo)志變量.【規(guī)則2-3-10】在使用之前,一定要初始化累計(jì)變量和循環(huán)的計(jì)數(shù)變量.【規(guī)則2-3-11】一定要初始化存儲(chǔ)返回值的變量.【規(guī)則2-3-12】一定要初始化指針變量(包括FILE*)為NULL值或者一個(gè)合法的地址。【規(guī)則2-3-13】當(dāng)指針變量長(zhǎng)時(shí)間不用時(shí),應(yīng)重新賦值為NULL。否則容易產(chǎn)生指向非法地址的指針。 C語(yǔ)言編程規(guī)范內(nèi)部資料 第39頁(yè) 注意保密函數(shù)聲明和定義參數(shù)的規(guī)則【建議2-3-14】不要把結(jié)構(gòu)作為參數(shù),而是使用此結(jié)構(gòu)的指針作為參數(shù)?!窘ㄗh2-3-15】盡量保持函數(shù)的返回值為int型,而且保持返回0為成功。小于0表示錯(cuò)誤。【規(guī)則2-3-16】參數(shù)的書寫要完整,不要貪圖省事只寫參數(shù)的類型而省略參數(shù)名字。如果函數(shù)沒(méi)有參數(shù),則用void填充。例如:voidSetValue(intnWidth,intnHeight); //良好的風(fēng)格voidSetValue(int,int); //不良的風(fēng)格floatGetValue(void); //良好的風(fēng)格floatGetValue(); //不良的風(fēng)格【規(guī)則2-3-17】參數(shù)命名要恰當(dāng),順序要合理。例如編寫字符串拷貝函數(shù)StringCopy,它有兩個(gè)參數(shù)。如果把參數(shù)名字起為str1和str2,例如voidStringCopy(char*psStr1,char*psSstr2);那么我們很難搞清楚究竟是把psStr1拷貝到psStr2中,還是剛好倒過(guò)來(lái)??梢园褏?shù)名字起得更有意義,如叫strSource和strDestination。這樣從名字上就可以看出應(yīng)該把psStrSource拷貝到psStrDestination。還有一個(gè)問(wèn)題,這兩個(gè)參數(shù)那一個(gè)該在前那一個(gè)該在后?參數(shù)的順序要遵循程序員的習(xí)慣。一般地,應(yīng)將目的參數(shù)放在前面,源參數(shù)放在后面。如果將函數(shù)聲明為:voidStringCopy(char*psStrSource,char*psStrDestination);別人在使用時(shí)可能會(huì)不假思索地寫成如下形式:charsStr[20];StringCopy(sStr,“HelloWorld”); //參數(shù)順序顛倒【建議2-3-18】如果參數(shù)僅作輸入用,則應(yīng)在類型前加const,以防止該指針在函數(shù)體內(nèi)被意外修改。例如:voidStringCopy(char*psStrDestination,constchar*psStrSource);【建議2-3-19】避免函數(shù)有太多的參數(shù),參數(shù)個(gè)數(shù)盡量控制在5個(gè)以內(nèi)。如果參數(shù)太多,在使用時(shí)容易將參數(shù)類型或順序搞錯(cuò)?!窘ㄗh2-3-20】盡量不要使用類型和數(shù)目不確定的參數(shù)。C標(biāo)準(zhǔn)庫(kù)函數(shù)printf是采用不確定參數(shù)的典型代表,其原型為:intprintf(constchat*psFormat[,argument]…);這種風(fēng)格的函數(shù)在編譯時(shí)喪失了嚴(yán)格的類型安全檢查。返回值的規(guī)則【規(guī)則2-3-21】不要省略返回值的類型。C語(yǔ)言中,凡不加類型說(shuō)明的函數(shù),一律自動(dòng)按整型處理。這樣做不會(huì)有什么好處,卻容易被誤解為void類型。C++語(yǔ)言有很嚴(yán)格的類型安全檢查,不允許上述情況發(fā)生。由于C++程序可以調(diào)用C函數(shù),為了避免混亂,規(guī)定任何C++/C函數(shù)都必須有類型。如果函數(shù)沒(méi)有返回值,那么應(yīng)聲明為void類型?!疽?guī)則2-3-22】函數(shù)名字與返回值類型在語(yǔ)義上不可沖突。違反這條規(guī)則的典型代表是C標(biāo)準(zhǔn)庫(kù)函數(shù)getchar。例如:charc;c=getchar();if(c==EOF)…按照getchar名字的意思,將變量c聲明為char類型是很自然的事情。但不幸的是getchar的確不是char類型,而是int類型,其原型如下: intgetchar(void);由于c是char類型,取值范圍是[-128,127],如果宏EOF的值在char的取值范圍之外,那么if語(yǔ)句將總是失敗,這種“危險(xiǎn)”人們一般哪里料得到!導(dǎo)致本例錯(cuò)誤的責(zé)任并不在用戶,是函數(shù)getchar誤導(dǎo)了使用者?!疽?guī)則2-3-23】不要將正常值和錯(cuò)誤標(biāo)志混在一起返回。正常值用輸出參數(shù)獲得,而錯(cuò)誤標(biāo)志用return語(yǔ)句返回?;仡櫳侠?,C標(biāo)準(zhǔn)庫(kù)函數(shù)的設(shè)計(jì)者為什么要將getchar聲明為令人迷糊的int類型呢?他會(huì)那么傻嗎?在正常情況下,getchar的確返回單個(gè)字符。但如果getchar碰到文件結(jié)束標(biāo)志或發(fā)生讀錯(cuò)誤,它必須返回一個(gè)標(biāo)志EOF。為了區(qū)別于正常的字符,只好將EOF定義為負(fù)數(shù)(通常為負(fù)1)。因此函數(shù)getchar就成了int類型。我們?cè)趯?shí)際工作中,經(jīng)常會(huì)碰到上述令人為難的問(wèn)題。為了避免出現(xiàn)誤解,我們應(yīng)該將正常值和錯(cuò)誤標(biāo)志分開。即:正常值用輸出參數(shù)獲得,而錯(cuò)誤標(biāo)志用return語(yǔ)句返回。函數(shù)getchar可以改寫成BOOLGetChar(char*c);雖然gechar比GetChar靈活,例如putchar(getchar());但是如果getchar用錯(cuò)了,它的靈活性又有什么用呢?【規(guī)則2-3-24】對(duì)系統(tǒng)調(diào)用的返回必須進(jìn)行判斷對(duì)于一些系統(tǒng)調(diào)用,比如打開文件,許多程序員對(duì)fopen返回的指針不做任何判斷,就直接使用了。然后發(fā)現(xiàn)文件的內(nèi)容怎么也讀出不,或是怎么也寫不進(jìn)去。還是判斷一下吧:fp=fopen("log.txt","a");if(fp==NULL){printf("Error:openfileerrorn");returnFALSE;}其它還有許多啦,比如:socket返回的socket號(hào),malloc返回的內(nèi)存。請(qǐng)對(duì)這些系統(tǒng)調(diào)用返回的東西進(jìn)行判斷。函數(shù)內(nèi)部實(shí)現(xiàn)的規(guī)則不同功能的函數(shù)其內(nèi)部實(shí)現(xiàn)各不相同,看起來(lái)似乎無(wú)法就“內(nèi)部實(shí)現(xiàn)”達(dá)成一致的觀點(diǎn)。但根據(jù)經(jīng)驗(yàn),我們可以在函數(shù)體的“入口處”和“出口處”從嚴(yán)把關(guān),從而提高函數(shù)的質(zhì)量?!疽?guī)則2-3-25】在函數(shù)體的“入口處”,對(duì)參數(shù)的有效性進(jìn)行檢查。很多程序錯(cuò)誤是由非法參數(shù)引起的,我們應(yīng)該充分理解并正確使用“斷言”(assert)來(lái)防止此類錯(cuò)誤。例:char*strcpy(char*psStrDest,constchar*psStrSrc);{assert((psStrDest!=NULL)&&(psStrSrc!=NULL)); char*psAddress=psStrDest; while((*psStrDest++=*psStrSrc++)!=‘\0’) { ;/*空語(yǔ)句*/}returnpsAddress; }【規(guī)則2-3-26】在函數(shù)體的“出口處”,對(duì)return語(yǔ)句的正確性進(jìn)行檢查。 如果函數(shù)有返回值,那么函數(shù)的“出口處”是return語(yǔ)句。我們不要輕視r(shí)eturn語(yǔ)句。如果return語(yǔ)句寫得不好,函數(shù)將要出錯(cuò)。注意事項(xiàng)如下:(1)return語(yǔ)句不可返回指向“棧內(nèi)存”的“指針”,因?yàn)樵搩?nèi)存在函數(shù)體結(jié)束時(shí)被自動(dòng)銷毀。例如 char*Func(void) { charsStr[]=“helloworld”; //str的內(nèi)存位于棧上 … returnsStr; //將導(dǎo)致錯(cuò)誤 }(2)要搞清楚返回的究竟是“值”還是“指針”。其它【建議2-3-27】不要寫超過(guò)三層的嵌套邏輯(if,while,for…),這樣會(huì)犧牲程序的易讀性,如果有這樣的情況,需要拆分為多個(gè)函數(shù)?!窘ㄗh2-3-28】函數(shù)的功能要單一,不要設(shè)計(jì)多用途的函數(shù)?!疽?guī)則2-3-29】函數(shù)體的規(guī)模要小盡量在60行以內(nèi),任何函數(shù)不得超過(guò)200行,如有超過(guò)的請(qǐng)考慮依據(jù)功能進(jìn)行拆分,(特殊情況:對(duì)結(jié)構(gòu)體進(jìn)行解碼,且基本沒(méi)有分支沒(méi)有循環(huán))。。【建議2-3-30】盡量避免函數(shù)帶有“記憶”功能。相同的輸入應(yīng)當(dāng)產(chǎn)生相同的輸出。帶有“記憶”功能的函數(shù),其行為可能是不可預(yù)測(cè)的,因?yàn)樗男袨榭赡苋Q于某種“記憶狀態(tài)”。這樣的函數(shù)既不易理解又不利于測(cè)試和維護(hù)。在C/C++語(yǔ)言中,函數(shù)的static局部變量是函數(shù)的“記憶”存儲(chǔ)器。建議盡量少用static局部變量,除非必需?!窘ㄗh2-3-31】不僅要檢查輸入?yún)?shù)的有效性,還要檢查通過(guò)其它途徑進(jìn)入函數(shù)體內(nèi)的變量的有效性,例如全局變量、文件句柄等?!窘ㄗh2-3-32】用于出錯(cuò)處理的返回值一定要清楚,讓使用者不容易忽視或誤解錯(cuò)誤情況。語(yǔ)句if語(yǔ)句變量與常量的比較【建議2-3-33】條件語(yǔ)句中的常量應(yīng)該寫在“==”的左邊以免形成賦值。例如:if(nFlag==3)很容易被錯(cuò)誤地寫成if(nFlag=3),而這個(gè)錯(cuò)誤在編譯的時(shí)候不會(huì)被發(fā)現(xiàn)。但是如果寫成if(3=nFlag)在編譯的時(shí)候就會(huì)被檢查出來(lái)。布爾變量與零值比較【規(guī)則2-3-34】不可將布爾變量直接與TRUE、FALSE或者1、0進(jìn)行比較。根據(jù)布爾類型的語(yǔ)義,零值為“假”(記為FALSE),任何非零值都是“真”(記為TRUE)。TRUE的值究竟是什么并沒(méi)有統(tǒng)一的標(biāo)準(zhǔn)。例如VisualC++將TRUE定義為1,而VisualBasic則將TRUE定義為-1。假設(shè)布爾變量名字為flag,它與零值比較的標(biāo)準(zhǔn)if語(yǔ)句如下:if(flag) //表示flag為真if(!flag) //表示flag為假其它的用法都屬于不良風(fēng)格,例如: if(flag==TRUE) if(flag==1) if(flag==FALSE) if(flag==0) 整型變量與零值比較【規(guī)則2-3-35】應(yīng)當(dāng)將整型變量用“==”或“!=”直接與0比較。 假設(shè)整型變量的名字為value,它與零值比較的標(biāo)準(zhǔn)if語(yǔ)句如下:if(0==value)if(value!=0)不可模仿布爾變量的風(fēng)格而寫成if(value) //會(huì)讓人誤解value是布爾變量if(!value)浮點(diǎn)變量與零值比較【規(guī)則2-3-36】不可將浮點(diǎn)變量用“==”或“!=”與任何數(shù)字比較。 千萬(wàn)要留意,無(wú)論是float還是double類型的變量,都有精度限制。所以一定要避免將浮點(diǎn)變量用“==”或“!=”與數(shù)字比較,應(yīng)該設(shè)法轉(zhuǎn)化成“>=”或“<=”形式。 假設(shè)浮點(diǎn)變量的名字為x,應(yīng)當(dāng)將 if(0.0==x) //隱含錯(cuò)誤的比較轉(zhuǎn)化為if((x>=-EPSINON)&&(x<=EPSINON))其中EPSINON是允許的誤差(即精度)。指針變量與零值比較【規(guī)則2-3-37】應(yīng)當(dāng)將指針變量用“==”或“!=”與NULL比較。 指針變量的零值是“空”(記為NULL)。盡管NULL的值與0相同,但是兩者意義不同。假設(shè)指針變量的名字為p,它與零值比較的標(biāo)準(zhǔn)if語(yǔ)句如下: if(NULL==p) //p與NULL顯式比較,強(qiáng)調(diào)p是指針變量 if(p!=NULL) 不要寫成 if(0==p) //容易讓人誤解p是整型變量 if(p!=0) 或者if(p) //容易讓人誤解p是布爾變量 if(!p) 對(duì)if語(yǔ)句的補(bǔ)充說(shuō)明有時(shí)候我們可能會(huì)看到if(NULL==p)這樣古怪的格式。不是程序?qū)戝e(cuò)了,是程序員為了防止將if(p==NULL)誤寫成if(p=NULL),而有意把p和NULL顛倒。編譯器認(rèn)為if(p=NULL)是合法的,但是會(huì)指出if(NULL=p)是錯(cuò)誤的,因?yàn)镹ULL不能被賦值。程序中有時(shí)會(huì)遇到if/else/return的組合,應(yīng)該將如下不良風(fēng)格的程序 if(condition) returnx; returny;改寫為 if(condition) { returnx; } else {returny;}或者改寫成更加簡(jiǎn)練的return(condition?x:y);for語(yǔ)句的循環(huán)控制變量【規(guī)則2-3-38】不可在for循環(huán)體內(nèi)修改循環(huán)變量,防止for循環(huán)失去控制。【建議2-3-39】建議for語(yǔ)句的循環(huán)控制變量的取值采用“半開半閉區(qū)間”寫法。示例2-4(a)中的x值屬于半開半閉區(qū)間“0=<x<N”,起點(diǎn)到終點(diǎn)的間隔為N,循環(huán)次數(shù)為N。示例2-4(b)中的x值屬于閉區(qū)間“0=<x<=N-1”,起點(diǎn)到終點(diǎn)的間隔為N-1,循環(huán)次數(shù)為N。相比之下,示例2-4(a)的寫法更加直觀,盡管兩者的功能是相同的。示例:intx;for(x=0;x<N;x++){…}intx;for(x=0;x<=N-1;x++){…}示例2-4(a)循環(huán)變量屬于半開半閉區(qū)間示例2-4(b)循環(huán)變量屬于閉區(qū)間switch語(yǔ)句 有了if語(yǔ)句為什么還要switch語(yǔ)句?switch是多分支選擇語(yǔ)句,而if語(yǔ)句只有兩個(gè)分支可供選擇。雖然可以用嵌套的if語(yǔ)句來(lái)實(shí)現(xiàn)多分支選擇,但那樣的程序冗長(zhǎng)難讀。這是switch語(yǔ)句存在的理由。針對(duì)可以簡(jiǎn)單映射的數(shù)據(jù),盡量使用數(shù)據(jù)字典,而不要使用switch。 switch語(yǔ)句的基本格式是:switch(variable){casevalue1: …break;casevalue2: …break; … default: …break;}【規(guī)則2-3-40】每個(gè)case語(yǔ)句的結(jié)尾不要忘了加break,否則將導(dǎo)致多個(gè)分支重疊(除非有意使多個(gè)分支重疊)。【規(guī)則2-3-41】不要忘記最后那個(gè)default分支。即使程序真的不需要default處理,也應(yīng)該保留語(yǔ)句 default:break;這樣做并非多此一舉,而是為了防止別人誤以為你忘了default處理。禁止語(yǔ)句【規(guī)則2-3-42】禁止使用goto語(yǔ)句;Proc*C除外【規(guī)則2-3-43】永遠(yuǎn)執(zhí)行不到的代碼禁止在程序中出現(xiàn)。返回碼【規(guī)則2-3-44】所有的函數(shù)返回值用0表示正常返回,其他返回則用宏表示而不是具體值.【規(guī)則2-3-45】stdlib.h中定義了EXIT_SUCCESSandEXIT_FAILURE來(lái)表示exit()的返回值.使用MacAppSuccess和MacAppFailure來(lái)表示那些只需返回是和否的函數(shù)的返回值.當(dāng)需要有多個(gè)返回值時(shí),用MacApp???來(lái)表示,不要直接用常量值來(lái)表示排版格式規(guī)則空行空行起著分隔程序段落的作用??招械皿w(不過(guò)多也不過(guò)少)將使程序的布局更加清晰。空行不會(huì)浪費(fèi)內(nèi)存,雖然打印含有空行的程序是會(huì)多消耗一些紙張,但是值得。所以不要舍不得用空行?!疽?guī)則2-4-1】在每個(gè)函數(shù)定義結(jié)束之后都要加空行。參見示例2-5(a)【規(guī)則2-4-2】在一個(gè)函數(shù)體內(nèi),邏揖上密切相關(guān)的語(yǔ)句之間不加空行,其它地方應(yīng)加空行分隔。參見示例2-5(b)//空行voidFunction1(…){…}//空行voidFunction2(…){…}//空行voidFunction3(…){…}//空行while(condition){ statement1; //空行 if(condition) { statement2; } else { statement3; }//空行 statement4;}示例2-5(a)函數(shù)之間的空行示例2-5(b)函數(shù)內(nèi)部的空行代碼行【規(guī)則2-4-3】一行代碼只做一件事情,如只定義一個(gè)變量,或只寫一條語(yǔ)句。這樣的代碼容易閱讀,并且方便于寫注釋。【規(guī)則2-4-4】if、for、while、do等語(yǔ)句自占一行,執(zhí)行語(yǔ)句不得緊跟其后。不論執(zhí)行語(yǔ)句有多少都要加{}。這樣可以防止書寫失誤。示例2-6(a)為風(fēng)格良好的代碼行,示例2-6(b)為風(fēng)格不良的代碼行。intnWidth; //寬度intnHeight; //高度intnDepth; //深度intnWidth,nHeight,nDepth;//寬度高度深度x=a+b;y=c+d;z=e+f;X=a+b;y=c+d;z=e+f;if(nWidth<nHeight){dosomething();}if(width<height)dosomething();for(initialization;condition;update){dosomething();}//空行other();for(initialization;condition;update)dosomething();other();示例2-6(a)風(fēng)格良好的代碼行示例2-6(b)風(fēng)格不良的代碼行【建議2-4-5】盡可能在定義變量的同時(shí)初始化該變量(就近原則)如果變量的引用處和其定義處相隔比較遠(yuǎn),變量的初始化很容易被忘記。如果引用了未被初始化的變量,可能會(huì)導(dǎo)致程序錯(cuò)誤。本建議可以減少隱患。例如intnWidth=10; //定義并初紿化widthintnHeight=10; //定義并初紿化heightintnDepth=10; //定義并初紿化depth【建議2-4-6】盡量不要使用空語(yǔ)句,若要使用,空語(yǔ)句要獨(dú)占一行,并且使用注釋說(shuō)明之。While(getchar()!=‘\n’){;/*空語(yǔ)句*/}代碼行內(nèi)的空格【規(guī)則2-4-7】關(guān)鍵字之后要留空格。象const、virtual、inline、case等關(guān)鍵字之后至少要留一個(gè)空格,否則無(wú)法辨析關(guān)鍵字。象if、for、while等關(guān)鍵字之后應(yīng)留一個(gè)空格再跟左括號(hào)‘(’,以突出關(guān)鍵字?!疽?guī)則2-4-8】函數(shù)名之后不要留空格,緊跟左括號(hào)‘(’,以與關(guān)鍵字區(qū)別?!疽?guī)則2-4-9】‘(’向后緊跟,‘)’、‘,’、‘;’向前緊跟,緊跟處不留空格。【規(guī)則2-4-10】‘,’之后要留空格,如Function(x,y,z)。如果‘;’不是一行的結(jié)束符號(hào),其后要留空格,如for(initialization;condition;update)?!疽?guī)則2-4-11】賦值操作符、比較操作符、算術(shù)操作符、邏輯操作符、位域操作符,如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后應(yīng)當(dāng)加空格?!疽?guī)則2-4-12】一元操作符如“!”、“~”、“++”、“--”、“&”(地址運(yùn)算符)等前后不加空格?!疽?guī)則2-4-13】象“[]”、“.”、“->”這類操作符前后不加空格?!窘ㄗh2-4-14】對(duì)于表達(dá)式比較長(zhǎng)的for語(yǔ)句和if語(yǔ)句,為了緊湊起見可以適當(dāng)?shù)厝サ粢恍┛崭瘢鏵or(i=0;i<10;i++)和if((a<=b)&&(c<=d))voidFunc1(intx,inty,intz);//良好的風(fēng)格voidFunc1(intx,inty,intz);//不良的風(fēng)格if(year>=2000)//良好的風(fēng)格if(year>=2000)//不良的風(fēng)格if((a>=b)&&(c<=d))//良好的風(fēng)格if(a>=b&&c<=d)//不良的風(fēng)格for(i=0;i<10;i++)//良好的風(fēng)格for(i=0;i<10;i++)//不良的風(fēng)格for(i=0;I<10;i++)//過(guò)多的空格x=a<b?a:b;//良好的風(fēng)格x=a<b?a:b;//不好的風(fēng)格int*x=&y;//良好的風(fēng)格int*x=&y;//不良的風(fēng)格array[5]=0;//不要寫成array[5]=0;a.Function();//不要寫成a.Function();b->Function();//不要寫成b->Function();示例2-7代碼行內(nèi)的空格分行【規(guī)則2-4-15】代碼行最大長(zhǎng)度宜控制在80個(gè)字符以內(nèi)。代碼行不要過(guò)長(zhǎng),否則眼睛看不過(guò)來(lái),也不便于打印。【規(guī)則2-4-16】長(zhǎng)表達(dá)式要在低優(yōu)先級(jí)操作符處拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要進(jìn)行適當(dāng)?shù)目s進(jìn),使排版整齊,語(yǔ)句可讀。if((very_longer_variable1>=very_longer_variable12)&&(very_longer_variable3<=very_longer_variable14)&&(very_longer_variable5<=very_longer_variable16)){dosomething();}voidMultiplyMatrix(intleftMatrix,intrightMatrix);for(very_longer_initialization; very_longer_condition; very_longer_update){ dosomething();}示例2-8分行對(duì)齊【規(guī)則2-4-17】程序的分界符‘{’和‘}’應(yīng)獨(dú)占一行并且位于同一列,同時(shí)與引用它們的語(yǔ)句左對(duì)齊。【規(guī)則2-4-18】{}之內(nèi)的代碼塊在‘{’右邊四格處左對(duì)齊,禁止使用tab鍵對(duì)齊,在不同編輯器下展現(xiàn)會(huì)有差別。示例2-9(a)為風(fēng)格良好的對(duì)齊,示例2-9(b)為風(fēng)格不良的對(duì)齊。voidFunction(intx){…//programcode}voidFunction(intx){…//programcode}if(condition){…//programcode}else{…//programcode}if(condition){…//programcode}else{…//programcode}for(initialization;condition;update){…//programcode}for(initialization;condition;update){…//programcode}While(condition){…//programcode}while(condition){…//programcode}如果出現(xiàn)嵌套的{},則使用縮進(jìn)對(duì)齊,如: { … { … } …}示例2-9(a)風(fēng)格良好的對(duì)齊示例2-9(b)風(fēng)格不良的對(duì)齊修飾符的位置修飾符*和&應(yīng)該靠近數(shù)據(jù)類型還是該靠近變量名,是個(gè)有爭(zhēng)議的活題。若將修飾符*靠近數(shù)據(jù)類型,例如:int*x;從語(yǔ)義上講此寫法比較直觀,即x是int類型的指針。上述寫法的弊端是容易引起誤解,例如:int*x,y;此處y容易被誤解為指針變量。雖然將x和y分行定義可以避免誤解,但并不是人人都愿意這樣做?!疽?guī)則2-4-19】應(yīng)當(dāng)將修飾符*和&緊靠變量名例如:char*name; int*x,y; //此處y不會(huì)被誤解為指針預(yù)處理(宏)【規(guī)則2-4-20】符號(hào)‘#’總是置于第一列(對(duì)于#嵌套的情況有所例外)?!窘ㄗh2-4-21】盡量作到把常量宏定義放在一起?!疽?guī)則2-4-22】如果必須使用多行的宏定義,合理分行,在每一行的末尾使用符號(hào)“\”。變量、類型聲明【規(guī)則2-4-23】全程變量在全程變量區(qū)第一列聲明?!疽?guī)則2-4-24】每一行聲明一個(gè)變量,緊跟分號(hào),不要加空格.【規(guī)則2-4-25】對(duì)齊公用同一類型聲明的變量,逗號(hào)、分號(hào)之前都不要加空格.intnLength,nHeight,nWidth;doubledlLast,dlFirst;注釋格式模塊注釋【規(guī)則2-5-2】每個(gè)模塊應(yīng)包含以下模塊注釋:Copyright版本版權(quán)聲明CurrentVersion當(dāng)前版本號(hào)FileName程序文件名Description模塊邏輯Functions本模塊函數(shù)聲明ModificationLog修改日志示例:模塊說(shuō)明/******************************************************************************************Copyright(c)2004,ASPIRETECHNOLOGIES(SHENZHEN)LTD*Allrightsreserved.**CurrentVersion:1.1**FileName:addUser.c**Description:Thismodulewilladdausertothesystem**Functions:boolbSortName()*boolbCheckDuplicate()*boolbAddUser()**ModificationLog:*DATEAUTHORDESCRIPTION**2004-11-15QiangWangInitialRelease****************************************************************************************/示例2-11模塊注釋函數(shù)注釋【規(guī)則2-5-3】在每個(gè)函數(shù)開始之前,應(yīng)該加以下注釋:Functionname函數(shù)名.Description功能簡(jiǎn)介Parameters參數(shù)說(shuō)明類型參數(shù)名輸入、輸出參數(shù)功能使用簡(jiǎn)要描述.ReturnValue返回值描述:類型名字簡(jiǎn)要描述,例如可能的值ModificationLog修改日志示例:函數(shù)說(shuō)明/******************************************************************************************Functionname:sortname**Description:Thisfunctionwillsorttheusername**Parameters:char**psInputNameList(I)-inputnamelist*char**psSortNameList(O)-sortednamelist**ReturnValue:bool*SUCCESS-sortsuccessful*FAILURE-sortfailed**ModificationLog:*DATEAUTHORDESCRIPTION**2004-11-15QiangWangInitialRelease****************************************************************************************/示例2-12函數(shù)注釋修改代碼的注釋【規(guī)則2-5-4】修改別人的程序時(shí),請(qǐng)不要?jiǎng)h除別人的程序,如果你覺得別人的程序有所不妥,請(qǐng)注釋掉,然后添加自己的處理程序。如下所示,這就是一種比較好的修改方法:/**commentedbyQiangWang2004/11/11**char*p=(char*)malloc(10);*memset(p,0,10);*//*AddedbyQiangWang2004/11/11*/char*p=(char*)calloc(10,sizeofchar);/**/...其它注釋【規(guī)則2-5-5】注釋要準(zhǔn)確,簡(jiǎn)單,無(wú)二意性。程序代碼中的主要邏輯部分要有適當(dāng)?shù)淖⑨?。如果代碼已經(jīng)很清楚,則無(wú)需注釋。否則多此一舉,令人厭煩。例如:i++; //i加1,多余的注釋【規(guī)則2-5-6】邊寫代碼邊注釋,修改代碼的同時(shí)修改注釋。保持代碼于注釋一致,同時(shí)刪掉無(wú)用的注釋?!疽?guī)則2-5-7】注釋的位置應(yīng)與被描述的代碼相鄰,可以放在代碼的上方或右方,不可放在下方。【規(guī)則2-5-8】復(fù)雜條件判斷要加簡(jiǎn)單注釋說(shuō)明含義?!疽?guī)則2-5-9】對(duì)于函數(shù)內(nèi)部的重要變量做簡(jiǎn)單注釋?!疽?guī)則2-5-10】對(duì)于頭文件中的類型定義,要對(duì)每個(gè)域有簡(jiǎn)單注釋。【規(guī)則2-5-11】頭文件中的常量、宏等需要注釋其作用。【建議2-5-12】注釋是對(duì)代碼的“提示”,而不是文檔。程序中的注釋不可喧賓奪主,注釋太多了會(huì)讓人眼花繚亂。注釋的花樣要少。程序的安全基本的數(shù)據(jù)定義【建議2-6-1】在具體的編碼中,保持基本的數(shù)據(jù)定義的一致性。(1)整數(shù):8位、16位、32位、64位,有符號(hào)、無(wú)符號(hào)的定義為:位數(shù)類型前綴簡(jiǎn)寫8位:int8_t,uint8_tn8,un816位:int16_t,uint16_tn16,un32位:int32_t,uint32_tn32,un3264位:int64_t,uint64_tn64,un64以上這種定義方法十分清晰,建議不要使用int、short、long這樣的定義。(2)長(zhǎng)度參數(shù)當(dāng)函數(shù)接口涉及傳遞參數(shù)的長(zhǎng)度時(shí),推薦使用size_t作為長(zhǎng)度的類型。函數(shù)安全【建議2-6-2】函數(shù)應(yīng)有盡量少的出口調(diào)用return語(yǔ)句顯式返回(對(duì)于main()用exit())。盡量減少多點(diǎn)返回。內(nèi)存安全內(nèi)存分配方式有三種:從靜態(tài)存儲(chǔ)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static變量。在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。從堆上分配,亦稱動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由我們決定,使用非常靈活,但問(wèn)題也最多。【規(guī)則2-6-3】用malloc申請(qǐng)內(nèi)存之后,應(yīng)該立即檢查指針值是否為NULL。防止使用指針值為NULL的內(nèi)存?!疽?guī)則2-6-4】動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放必須配對(duì),有一個(gè)malloc,就應(yīng)該有一個(gè)free,防止內(nèi)存泄漏?!疽?guī)則2-6-5】malloc分配的內(nèi)存一定要初始化;用free釋放了內(nèi)存之后,立即將指針設(shè)置為NULL,防止產(chǎn)生“野指針”。【建議2-6-6】盡量在同一層上使用,不要出現(xiàn)malloc在函數(shù)中,而free在函數(shù)外的情況。最好在同一調(diào)用層上使用這兩個(gè)函數(shù)?!窘ㄗh2-6-7】避免數(shù)組或指針的下標(biāo)越界,特別要當(dāng)心發(fā)生“多1”或者“少1”操作。數(shù)組、指針、字符串注意要點(diǎn)【規(guī)則2-6-8】字符串的長(zhǎng)度不要過(guò)長(zhǎng),限制進(jìn)程空間內(nèi)自動(dòng)變量占用的內(nèi)存大小,以便保留更多得??臻g。需要大于5k空間的數(shù)組時(shí),要用malloc動(dòng)態(tài)分配,而不要用自動(dòng)變量,以便節(jié)省??臻g?!疽?guī)則2-6-9】指針使用之前,需要先判斷是否為NULL?!疽?guī)則2-6-10】計(jì)算數(shù)組元素個(gè)數(shù)時(shí)請(qǐng)使用sizeof(type)而不是sizeof(變量名)。許多程序員在使用sizeof中,喜歡sizeof變量名,例如:
intscore[100];
charfilename[20];
structUserInfousr[100];
在sizeof這三個(gè)的變量名時(shí),都會(huì)返回正確的結(jié)果,于是許多程序員就開始sizeof變量名。這個(gè)習(xí)慣很雖然沒(méi)有什么不好,但我還是建議sizeof類型。
我看到過(guò)這個(gè)的程序:
pScore=(int*)malloc(SUBJECT_CNT);
memset(pScore,0,sizeof(pScore));
此時(shí),sizeof(pScore)返回的就是4(指針的長(zhǎng)度),不會(huì)是整個(gè)數(shù)組,于是,memset就不能對(duì)這塊內(nèi)存進(jìn)行初始化。為了程序的易讀和易維護(hù),我強(qiáng)烈建議使用類型而不是變量,如:
對(duì)于score:sizeof(int)*100/*100個(gè)int*/
對(duì)于filename:sizeof(char)*20/*20個(gè)char*/
對(duì)于usr:sizeof(structUserInfo)*100/*100個(gè)UserInfo*/
這樣的代碼是不是很易讀?一眼看上去就知道什么意思了?!疽?guī)則2-6-11】關(guān)鍵字符串?dāng)?shù)組的元素個(gè)數(shù)使用常量宏+1的方式定義。防止元素使用時(shí)越界。初始化【規(guī)則2-6-12】對(duì)棧上分配的struct或數(shù)組要進(jìn)行初始化。(最好是清零)。程序的效率注意要點(diǎn)程序的時(shí)間效率是指運(yùn)行速度,空間效率是指程序占用內(nèi)存或者外存的狀況。全局效率是指站在整個(gè)系統(tǒng)的角度上考慮的效率,局部效率是指站在模塊或函數(shù)角度上考慮的效率?!疽?guī)則2-7-1】不要一味地追求程序的效率,應(yīng)當(dāng)在滿足正確性、可靠性、健壯性、可讀性等質(zhì)量因素的前提下,設(shè)法提高程序的效率?!疽?guī)則2-7-2】以提高程序的全局效率為主,提高局部效率為輔?!疽?guī)則2-7-3】在優(yōu)化程序的效率時(shí),應(yīng)當(dāng)先找出限制效率的“瓶頸”,不要在無(wú)關(guān)緊要之處優(yōu)化?!疽?guī)則2-7-4】先優(yōu)化數(shù)據(jù)結(jié)構(gòu)和算法,再優(yōu)化執(zhí)行代碼?!窘ㄗh2-7-5】有時(shí)候時(shí)間效率和空間效率可能對(duì)立,此時(shí)應(yīng)當(dāng)分析那個(gè)更重要,作出適當(dāng)?shù)恼壑?。例如多花費(fèi)一些內(nèi)存來(lái)提高性能?!窘ㄗh2-7-6】不要追求緊湊的代碼,因?yàn)榫o湊的代碼并不能產(chǎn)生高效的機(jī)器碼。循環(huán)語(yǔ)句的效率 C++/C循環(huán)語(yǔ)句中,for語(yǔ)句使用頻率最高,while語(yǔ)句其次,do語(yǔ)句很少用。本節(jié)重點(diǎn)論述循環(huán)體的效率。提高循環(huán)體效率的基本辦法是降低循環(huán)體的復(fù)雜性。【建議2-
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 初中化學(xué)教學(xué)的難點(diǎn)剖析及對(duì)策研究
- 陜西省藍(lán)田縣焦岱中學(xué)高中政治4.1傳統(tǒng)文化的繼承教學(xué)設(shè)計(jì)4新人教版必修3
- 公司附加合同范本
- 付款合同范例版
- 2025年證券投資服務(wù)項(xiàng)目合作計(jì)劃書
- 伴娘出租合同范例簡(jiǎn)短
- 個(gè)人原因花店轉(zhuǎn)讓合同范例
- 買樹種樹合同范例
- 鄉(xiāng)村農(nóng)家樂(lè)合同范例
- vi 招標(biāo) 合同范例
- 2022年大唐集團(tuán)招聘筆試試題及答案
- 醫(yī)療器械經(jīng)營(yíng)質(zhì)量管理規(guī)范培訓(xùn)試題及答案
- 監(jiān)理工作業(yè)務(wù)指導(dǎo)手冊(cè)(頁(yè)含圖表)
- 新大象版科學(xué)四年級(jí)下冊(cè)珍貴的淡水資源課件公開課一等獎(jiǎng)?wù)n件省賽課獲獎(jiǎng)?wù)n件
- 2023年陜西延長(zhǎng)石油(集團(tuán))有限責(zé)任公司招聘筆試題庫(kù)含答案解析
- 水稻種子生產(chǎn)技術(shù)
- 財(cái)經(jīng)紀(jì)律規(guī)范財(cái)務(wù)管理辦法
- 第四章 學(xué)習(xí)心理導(dǎo)論
- 旅游政策與法規(guī)教案
- 科創(chuàng)板開戶試題附答案
- 長(zhǎng)輸管道工序監(jiān)理作業(yè)指導(dǎo)書
評(píng)論
0/150
提交評(píng)論