




免費(fèi)預(yù)覽已結(jié)束,剩余22頁(yè)可下載查看
下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
精選文庫(kù)C語(yǔ)言書(shū)寫(xiě)規(guī)范指南第1章文件結(jié)構(gòu)每個(gè)C程序通常分為兩個(gè)文件。一個(gè)文件用于保存程序的聲明(declaration),稱為頭文件。另一個(gè)文件用于保存程序的實(shí)現(xiàn)(implementation),稱為定義(definition)文件。C程序的頭文件以“.h”為后綴,C程序的定義文件以“.c”為后綴。1.1版權(quán)和版本的聲明版權(quán)和版本的聲明位于頭文件和定義文件的開(kāi)頭(參見(jiàn)示例1-1),主要內(nèi)容有:(1)版權(quán)信息。(2)文件名稱,標(biāo)識(shí)符,摘要。(3)當(dāng)前版本號(hào),作者/修改者,完成日期。(4)版本歷史信息。/*Copyright(c)2001,吉林大學(xué)物理學(xué)院無(wú)線電*Allrightsreserved.*文件名稱:filename.h*文件標(biāo)識(shí): *摘要:簡(jiǎn)要描述本文件的內(nèi)容*當(dāng)前版本:1.1*作者:輸入作者(或修改者)名字*完成日期:2007年7月20日*取代版本:1.0*原作者:輸入原作者(或修改者)名字*完成日期:2007年5月10日*/示例1-1版權(quán)和版本的聲明1.2頭文件的結(jié)構(gòu)頭文件由三部分內(nèi)容組成:(1)頭文件開(kāi)頭處的版權(quán)和版本聲明(參見(jiàn)示例1-1)。(2)預(yù)處理塊。(3)函數(shù)和類(lèi)結(jié)構(gòu)聲明等。假設(shè)頭文件名稱為 SCL_SPI.h,頭文件的結(jié)構(gòu)參見(jiàn)示例1-2?!疽?guī)則1-2-1】為了防止頭文件被重復(fù)引用,應(yīng)當(dāng)用 #ifndef/#define/#endif結(jié)構(gòu)產(chǎn)生預(yù)處理塊?!疽?guī)則1-2-2】用 #include格式來(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ù)的頭文件(編譯器將從用戶的工作目錄開(kāi)始搜索)。【規(guī)則1-2-4】 #include 后面使用TAB鍵控制排版 。【規(guī)則1-2-5】頭文件中只存放“聲明”而不存放“定義”【規(guī)則1-2-6】全局變量在頭文件中聲明,在.c文件中定義 .h extern in tvalue; 聲明。.c in tvalue=0x10; 定義?!疽?guī)則1-2-7】局部變量在.c中定義 (static) unsigned in tvalue; 定義。/版權(quán)和版本聲明見(jiàn)示例1-1,此處省略。 #ifndefSCL_SPI_H /防止SCL_SPI.h被重復(fù)引用#defineSCL_SPI_H#include /引用標(biāo)準(zhǔn)庫(kù)的頭文件#include“SCL_CAN.h”/引用非標(biāo)準(zhǔn)庫(kù)的頭文件void Function1();/全局函數(shù)聲明extern unsign int value;/全局變量聲明#endif示例1-2C頭文件的結(jié)構(gòu)1.3定義文件的結(jié)構(gòu)定義文件有三部分內(nèi)容:(1)定義文件開(kāi)頭處的版權(quán)和版本聲明(參見(jiàn)示例1-1)。(2)對(duì)一些頭文件的引用。(3)程序的實(shí)現(xiàn)體(包括數(shù)據(jù)和代碼)。假設(shè)定義文件的名稱為SCL_SPI.c,定義文件的結(jié)構(gòu)參見(jiàn)示例1-3。/版權(quán)和版本聲明見(jiàn)示例1-1,此處省略。#include“SCL_SPI.h”/引用頭文件/全局變量定義unsign int value = 0x10;/全局函數(shù)的實(shí)現(xiàn)體void Function1() 示例1-3C定義文件的結(jié)構(gòu)1.4頭文件的作用早期的編程語(yǔ)言如Basic、Fortran沒(méi)有頭文件的概念,C語(yǔ)言的初學(xué)者雖然會(huì)用使用頭文件,但常常不明其理。這里對(duì)頭文件的作用略作解釋?zhuān)海?)通過(guò)頭文件來(lái)調(diào)用庫(kù)功能。在很多場(chǎng)合,源代碼不便(或不準(zhǔn))向用戶公布,只要向用戶提供頭文件和二進(jìn)制的庫(kù)即可。用戶只需要按照頭文件中的接口聲明來(lái)調(diào)用庫(kù)功能,而不必關(guān)心接口怎么實(shí)現(xiàn)的。編譯器會(huì)從庫(kù)中提取相應(yīng)的代碼。(2)頭文件能加強(qiáng)類(lèi)型安全檢查。如果某個(gè)接口被實(shí)現(xiàn)或被使用時(shí),其方式與頭文件中的聲明不一致,編譯器就會(huì)指出錯(cuò)誤,這一簡(jiǎn)單的規(guī)則能大大減輕程序員調(diào)試、改錯(cuò)的負(fù)擔(dān)。 1.5目錄結(jié)構(gòu)如果一個(gè)軟件的頭文件數(shù)目比較多(如超過(guò)十個(gè)),通常應(yīng)將頭文件和定義文件分別保存于不同的目錄,以便于維護(hù)。例如可將頭文件保存于 include 目錄,將定義文件保存于 source 目錄(可以是多級(jí)目錄)。如果某些頭文件是私有的,它不會(huì)被用戶的程序直接引用,則沒(méi)有必要公開(kāi)其“聲明”。為了加強(qiáng)信息隱藏,這些私有的頭文件可以和定義文件存放于同一個(gè)目錄。 第2章程序的版式版式雖然不會(huì)影響程序的功能,但會(huì)影響可讀性。程序的版式追求清晰、美觀,是程序風(fēng)格的重要構(gòu)成因素??梢园殉绦虻陌媸奖扔鳛椤皶?shū)法”。好的“書(shū)法”可讓人對(duì)程序一目了然,看得興致勃勃。差的程序“書(shū)法”如螃蟹爬行,讓人看得索然無(wú)味,更令維護(hù)者煩惱有加。請(qǐng)程序員們學(xué)習(xí)程序的“書(shū)法”,彌補(bǔ)大學(xué)計(jì)算機(jī)教育的漏洞,實(shí)在很有必要。2.1空行空行起著分隔程序段落的作用。空行得體(不過(guò)多也不過(guò)少)將使程序的布局更加清晰。空行不會(huì)浪費(fèi)內(nèi)存,雖然打印含有空行的程序是會(huì)多消耗一些紙張,但是值得。所以不要舍不得用空行。【規(guī)則2-1-1】在每個(gè)函數(shù)定義結(jié)束之后都要加空行。參見(jiàn)示例2-1(a)【規(guī)則2-1-2】在一個(gè)函數(shù)體內(nèi),邏揖上密切相關(guān)的語(yǔ)句之間不加空行,其它地方應(yīng)加空行分隔。參見(jiàn)示例2-1(b)/空行void Function1()/空行void Function2()示例2-1(a)函數(shù)之間的空行/空行while (condition)statement1;/空行if (condition)statement2;elsestatement3;/空行statement4;示例2-1(b)函數(shù)內(nèi)部的空行 2.2代碼行【規(guī)則2-2-1】一行代碼只做一件事情,如只定義一個(gè)變量,或只寫(xiě)一條語(yǔ)句。這樣的代碼容易閱讀,并且方便于寫(xiě)注釋?!疽?guī)則2-2-2】if、for、while、do等語(yǔ)句自占一行,執(zhí)行語(yǔ)句不得緊跟其后。不論執(zhí)行語(yǔ)句有多少都要加。這樣可以防止書(shū)寫(xiě)失誤。示例2-2(a)為風(fēng)格良好的代碼行,示例2-2(b)為風(fēng)格不良的代碼行。intwidth;/寬度intheight;/高度intdepth;/深度中間使用TAB鍵控制距離intwidth,height,depth;/寬度高度深度x = a+b; /等號(hào)左右用空格控制距離y = c+d;z = e+f;x = a+b;y=c+d;z=e+f;if (width height)/左右用空格控制距離dosomething();/使用TAB鍵控制距離if(width=”、“=”、“+”、“*”、“%”、“&”、“|”、“”這類(lèi)操作符前后不加空格。【建議2-3-1】對(duì)于表達(dá)式比較長(zhǎng)的for語(yǔ)句和if語(yǔ)句,為了緊湊起見(jiàn)可以適當(dāng)?shù)厝サ粢恍┛崭?,如for(i=0;i10;i+)和if(a=b)&(c= 2000)/良好的風(fēng)格if(year=2000)/不良的風(fēng)格if (a=b) & (c=b&c=d)/不良的風(fēng)格for (i=0; i10; i+)/良好的風(fēng)格for(i=0;i10;i+)/不良的風(fēng)格for(I = 0; I 10; I+)/過(guò)多的空格x = a b ? a : b;/良好的風(fēng)格x=aFunction();/不要寫(xiě)成b - Function();示例2-3代碼行內(nèi)的空格2.4對(duì)齊【規(guī)則2-4-1】程序的分界符和應(yīng)獨(dú)占一行并且位于同一列,同時(shí)與引用它們的語(yǔ)句左對(duì)齊。【規(guī)則2-4-2】之內(nèi)的代碼塊在右邊一個(gè)TAB鍵處左對(duì)齊。示例2-4(a)為風(fēng)格良好的對(duì)齊,示例2-4(b)為風(fēng)格不良的對(duì)齊。void Function (int x)/programcodeVoid Function(intx)/programcodeif (condition)/programcodeelse/programcodeif(condition)/programcodeelse/programcodefor (initialization; condition; update)/programcodefor(initialization;condition;update)/programcodewhile (condition)/programcodewhile(condition)/programcode如果出現(xiàn)嵌套的,則使用縮進(jìn)對(duì)齊,如:示例2-4(a)風(fēng)格良好的對(duì)齊示例2-4(b)風(fēng)格不良的對(duì)齊2.5長(zhǎng)行拆分z【規(guī)則2-5-1】代碼行最大長(zhǎng)度宜控制在70至80個(gè)字符以內(nèi)。代碼行不要過(guò)長(zhǎng),否則眼睛看不過(guò)來(lái),也不便于打印。z【規(guī)則2-5-2】長(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) 使用TAB鍵控制距離&(very_longer_variable5 Draw();/類(lèi)的成員函數(shù)z【規(guī)則3-1-8】用正確的反義詞組命名具有互斥意義的變量或相反動(dòng)作的函數(shù)等。例如:intminValue;intmaxValue;intSetValue();intGetValue();【建議3-1-1】盡量避免名字中出現(xiàn)數(shù)字編號(hào),如Value1,Value2等,除非邏輯上的確需要編號(hào)。這是為了防止程序員偷懶,不肯為命名動(dòng)腦筋而導(dǎo)致產(chǎn)生無(wú)意義的名字(因?yàn)橛脭?shù)字編號(hào)最省事)。3.2簡(jiǎn)單的Windows應(yīng)用程序命名規(guī)則作者對(duì)“匈牙利”命名規(guī)則做了合理的簡(jiǎn)化,下述的命名規(guī)則簡(jiǎn)單易用,比較適合于Windows應(yīng)用軟件的開(kāi)發(fā)。z【規(guī)則3-2-1】類(lèi)名和函數(shù)名用大寫(xiě)字母開(kāi)頭的單詞組合而成。例如:classNode;/類(lèi)名classLeafNode;/類(lèi)名voidDraw(void);/函數(shù)名voidSetValue(int value);/函數(shù)名z【規(guī)則3-2-2】變量和參數(shù)用小寫(xiě)字母開(kāi)頭的單詞組合而成。例如:BOOLflag;intdrawMode;z【規(guī)則3-2-3】常量全用大寫(xiě)的字母,用下劃線分割單詞。例如:const intMAX = 100;const intMAX_LENGTH = 100;z【規(guī)則3-2-4】靜態(tài)變量加前綴s_(表示static)。例如:void Init()static ints_initValue;/靜態(tài)變量z【規(guī)則3-2-5】如果不得已需要全局變量,則使全局變量加前綴g_(表示global)。例如:intg_howManyPeople;/全局變量intg_howMuchMoney;/全局變量z【規(guī)則3-2-6】類(lèi)的數(shù)據(jù)成員加前綴m_(表示member),這樣可以避免數(shù)據(jù)成員與成員函數(shù)的參數(shù)同名。例如:Void Object:SetValue(int width, int height)m_width = width;m_height = height; z【規(guī)則3-2-7】為了防止某一軟件庫(kù)中的一些標(biāo)識(shí)符和其它軟件庫(kù)中的沖突,可以為各種標(biāo)識(shí)符加上能反映軟件性質(zhì)的前綴。例如三維圖形標(biāo)準(zhǔn)OpenGL的所有庫(kù)函數(shù)均以gl開(kāi)頭,所有常量(或宏定義)均以GL開(kāi)頭。 第4章表達(dá)式和基本語(yǔ)句表達(dá)式和語(yǔ)句都屬于C的短語(yǔ)結(jié)構(gòu)語(yǔ)法。它們看似簡(jiǎn)單,但使用時(shí)隱患比較多。本章歸納了正確使用表達(dá)式和語(yǔ)句的一些規(guī)則與建議。4.1運(yùn)算符的優(yōu)先級(jí)C語(yǔ)言的運(yùn)算符有數(shù)十個(gè),運(yùn)算符的優(yōu)先級(jí)與結(jié)合律如表4-1所示。注意一元運(yùn)算符+-*的優(yōu)先級(jí)高于對(duì)應(yīng)的二元運(yùn)算符。優(yōu)先級(jí)運(yùn)算符結(jié)合律從高到低排列()-.從左至右!+-(類(lèi)型)sizeof+-*&從右至左*/%從左至右+-從左至右從左至右=從左至右=!=從左至右&從左至右從左至右|從左至右&從左至右|從右至左?:從右至左=+=-=*=/=%=&=|=從左至右表4-1運(yùn)算符的優(yōu)先級(jí)與結(jié)合律 【規(guī)則4-1-1】如果代碼行中的運(yùn)算符比較多,用括號(hào)確定表達(dá)式的操作順序,避免使用默認(rèn)的優(yōu)先級(jí)。由于將表4-1熟記是比較困難的,為了防止產(chǎn)生歧義并提高可讀性,應(yīng)當(dāng)用括號(hào)確定表達(dá)式的操作順序。例如:word = (high=b&cd&c+f=g+h;/復(fù)合表達(dá)式過(guò)于復(fù)雜【規(guī)則4-2-2】不要有多用途的復(fù)合表達(dá)式。例如:d=(a=b+c)+r;該表達(dá)式既求a值又求d值。應(yīng)該拆分為兩個(gè)獨(dú)立的語(yǔ)句:a = b + c;d = a + r;【規(guī)則4-2-3】不要把程序中的復(fù)合表達(dá)式與“真正的數(shù)學(xué)表達(dá)式”混淆。例如:if(abc)/abc是數(shù)學(xué)表達(dá)式而不是程序表達(dá)式并不表示if (ab)&(bc)而是成了令人費(fèi)解的if(ab)=”或“=-EPSINON)&(x=EPSINON)其中EPSINON是允許的誤差(即精度)。4.3.4指針變量與零值比較z【規(guī)則4-3-4】應(yīng)當(dāng)將指針變量用“=”或“!=”與NULL比較。指針變量的零值是“空”(記為NULL)。盡管NULL的值與0相同,但是兩者意義不同。假設(shè)指針變量的名字為p,它與零值比較的標(biāo)準(zhǔn)if語(yǔ)句如下:if(p=NULL)/p與NULL顯式比較,強(qiáng)調(diào)p是指針變量if(p!=NULL)不要寫(xiě)成if(p=0)/容易讓人誤解p是整型變量if(p!=0)或者if(p)/容易讓人誤解p是布爾變量if(!p)4.3.5對(duì)if語(yǔ)句的補(bǔ)充說(shuō)明有時(shí)候我們可能會(huì)看到if(NULL=p)這樣古怪的格式。不是程序?qū)戝e(cuò)了,是程序員為了防止將if(p=NULL)誤寫(xiě)成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;改寫(xiě)為if(condition)returnx;elsereturny;或者改寫(xiě)成更加簡(jiǎn)練的return(condition?x:y);4.4循環(huán)語(yǔ)句的效率C循環(huán)語(yǔ)句中,for語(yǔ)句使用頻率最高,while語(yǔ)句其次,do語(yǔ)句很少用。本節(jié)重點(diǎn)論述循環(huán)體的效率。提高循環(huán)體效率的基本辦法是降低循環(huán)體的復(fù)雜性。z【建議4-4-1】在多重循環(huán)中,如果有可能,應(yīng)當(dāng)將最長(zhǎng)的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層,以減少CPU跨切循環(huán)層的次數(shù)。例如示例4-4(b)的效率比示例4-4(a)的高。for (row=0; row100; row+)for (col=0; col5; col+)fum = sum+arowcol;示例4-4(a)低效率:長(zhǎng)循環(huán)在最外層for (col=0; col5; col+)for (row=0; row100; row+)fum = sum+arowcol;示例4-4(b)高效率:長(zhǎng)循環(huán)在最內(nèi)層z【建議4-4-2】如果循環(huán)體內(nèi)存在邏輯判斷,并且循環(huán)次數(shù)很大,宜將邏輯判斷移到循環(huán)體的外面。示例4-4(c)的程序比示例4-4(d)多執(zhí)行了N-1次邏輯判斷。并且由于前者老要進(jìn)行邏輯判斷,打斷了循環(huán)“流水線”作業(yè),使得編譯器不能對(duì)循環(huán)進(jìn)行優(yōu)化處理,降低了效率。如果N非常大,最好采用示例4-4(d)的寫(xiě)法,可以提高效率。如果N非常小,兩者效率差別并不明顯,采用示例4-4(c)的寫(xiě)法比較好,因?yàn)槌绦蚋雍?jiǎn)潔。 for (i=0; iN; i+)if (conditionDoSomething();elseDoOtherthing();表4-4(c)效率低但程序簡(jiǎn)潔if(condition)for(i=0;iN;i+)DoSomething();elsefor(i=0;iN;i+)DoOtherthing();表4-4(d)效率高但程序不簡(jiǎn)潔4.5for語(yǔ)句的循環(huán)控制變量z【規(guī)則4-5-1】不可在for循環(huán)體內(nèi)修改循環(huán)變量,防止for循環(huán)失去控制。z【建議4-5-1】建議for語(yǔ)句的循環(huán)控制變量的取值采用“半開(kāi)半閉區(qū)間”寫(xiě)法。示例4-5(a)中的x值屬于半開(kāi)半閉區(qū)間“0=xN”,起點(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。相比之下,示例4-5(a)的寫(xiě)法更加直觀,盡管兩者的功能是相同的。for(intx=0;xN;x+)示例4-5(a)循環(huán)變量屬于半開(kāi)半閉區(qū)間for(intx=0;x=N-1;x+)示例4-5(b)循環(huán)變量屬于閉區(qū)間4.6switch語(yǔ)句switch是多分支選擇語(yǔ)句,而if語(yǔ)句只有兩個(gè)分支可供選擇。雖然可以用嵌套的if語(yǔ)句來(lái)實(shí)現(xiàn)多分支選擇,但那樣的程序冗長(zhǎng)難讀。這是switch語(yǔ)句存在的理由。switch語(yǔ)句的基本格式是:switch(variable)case value1:break;case value2:break;default:break;z【規(guī)則4-6-1】每個(gè)case語(yǔ)句的結(jié)尾不要忘了加break,否則將導(dǎo)致多個(gè)分支重疊(除非有意使多個(gè)分支重疊)。z【規(guī)則4-6-2】不要忘記最后那個(gè)default分支。即使程序真的不需要default處理,也應(yīng)該保留語(yǔ)句default:break;這樣做并非多此一舉,而是為了防止別人誤以為你忘了default處理。4.7goto語(yǔ)句自從提倡結(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ì)象的構(gòu)造、變量的初始化、重要的計(jì)算等語(yǔ)句,例如:gotostate;Strings1,s2; /被goto跳過(guò)intsum = 0;/被goto跳過(guò)state:如果編譯器不能發(fā)覺(jué)此類(lèi)錯(cuò)誤,每用一次goto語(yǔ)句都可能留下隱患。很多人建議廢除C的goto語(yǔ)句,以絕后患。但實(shí)事求是地說(shuō),錯(cuò)誤是程序員自己造成的,不是goto的過(guò)錯(cuò)。goto語(yǔ)句至少有一處可顯神通,它能從多重循環(huán)體中咻地一下子跳到外面,用不著寫(xiě)很多次的break語(yǔ)句;例如gotoerror; error:就象樓房著火了,來(lái)不及從樓梯一級(jí)一級(jí)往下走,可從窗口跳出火坑。所以我們主張少用、慎用goto語(yǔ)句,而不是禁用。 第5章常量常量是一種標(biāo)識(shí)符,它的值在運(yùn)行期間恒定不變。C語(yǔ)言用#define來(lái)定義常量(稱為宏常量)。C+語(yǔ)言除了#define外還可以用const來(lái)定義常量(稱為const常量)。 5.1為什么需要常量如果不使用常量,直接在程序中填寫(xiě)數(shù)字或字符串,將會(huì)有什么麻煩?(1)程序的可讀性(可理解性)變差。程序員自己會(huì)忘記那些數(shù)字或字符串是什么意思,用戶則更加不知它們從何處來(lái)、表示什么。(2)在程序的很多地方輸入同樣的數(shù)字或字符串,難保不發(fā)生書(shū)寫(xiě)錯(cuò)誤。(3)如果要修改數(shù)字或字符串,則會(huì)在很多地方改動(dòng),既麻煩又容易出錯(cuò)。z【規(guī)則5-1-1】盡量使用含義直觀的常量來(lái)表示那些將在程序中多次出現(xiàn)的數(shù)字或字符串。例如:#defineMAX100/*C語(yǔ)言的宏常量*/constintMAX=100;/C+語(yǔ)言的const常量constfloatPI=3.14159;/C+語(yǔ)言的const常量5.2const與#define的比較 C+語(yǔ)言可以用const來(lái)定義常量,也可以用#define來(lái)定義常量。但是前者比后者有更多的優(yōu)點(diǎn):(1)const常量有數(shù)據(jù)類(lèi)型,而宏常量沒(méi)有數(shù)據(jù)類(lèi)型。編譯器可以對(duì)前者進(jìn)行類(lèi)型安全檢查。而對(duì)后者只進(jìn)行字符替換,沒(méi)有類(lèi)型安全檢查,并且在字符替換可能會(huì)產(chǎn)生意料不到的錯(cuò)誤(邊際效應(yīng))。(2)有些集成化的調(diào)試工具可以對(duì)const常量進(jìn)行調(diào)試,但是不能對(duì)宏常量進(jìn)行調(diào)試。z【規(guī)則5-2-1】在C+程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。5.3常量定義規(guī)則z【規(guī)則5-3-1】需要對(duì)外公開(kāi)的常量放在頭文件中,不需要對(duì)外公開(kāi)的常量放在定義文件的頭部。為便于管理,可以把不同模塊的常量集中存放在一個(gè)公共的頭文件中。z【規(guī)則5-3-2】如果某一常量與其它常量密切相關(guān),應(yīng)在定義中包含這種關(guān)系,而不 應(yīng)給出一些孤立的值。例如:constfloatRADIUS=100;constfloatDIAMETER=RADIUS*2; 第6章函數(shù)設(shè)計(jì)函數(shù)是C程序的基本功能單元,其重要性不言而喻。函數(shù)設(shè)計(jì)的細(xì)微缺點(diǎn)很容易導(dǎo)致該函數(shù)被錯(cuò)用,所以光使函數(shù)的功能正確是不夠的。本章重點(diǎn)論述函數(shù)的接口設(shè)計(jì)和內(nèi)部實(shí)現(xiàn)的一些規(guī)則。函數(shù)接口的兩個(gè)要素是參數(shù)和返回值。C語(yǔ)言中,函數(shù)的參數(shù)和返回值的傳遞方式有兩種:值傳遞(passbyvalue)和指針傳遞(passbypointer)。C+語(yǔ)言中多了引用傳遞(passbyreference)。由于引用傳遞的性質(zhì)象指針傳遞,而使用方式卻象值傳遞,初學(xué)者常常迷惑不解,容易引起混亂,請(qǐng)先閱讀6.6節(jié)“引用與指針的比較”。6.1參數(shù)的規(guī)則z【規(guī)則6-1-1】參數(shù)的書(shū)寫(xiě)要完整,不要貪圖省事只寫(xiě)參數(shù)的類(lèi)型而省略參數(shù)名字。如果函數(shù)沒(méi)有參數(shù),則用void填充。例如:void SetValue(int width, int height);/良好的風(fēng)格void SetValue(int,int);/不良的風(fēng)格float GetValue(void);/良好的風(fēng)格float GetValue();/不良的風(fēng)格z【規(guī)則6-1-2】參數(shù)命名要恰當(dāng),順序要合理。例如編寫(xiě)字符串拷貝函數(shù)StringCopy,它有兩個(gè)參數(shù)。如果把參數(shù)名字起為str1和str2,例如void StringCopy(char *str1,char *str2);那么我們很難搞清楚究竟是把str1拷貝到str2中,還是剛好倒過(guò)來(lái)。可以把參數(shù)名字起得更有意義,如叫strSource和strDestination。這樣從名字上就可以看出應(yīng)該把strSource拷貝到strDestination。還有一個(gè)問(wèn)題,這兩個(gè)參數(shù)那一個(gè)該在前那一個(gè)該在后?參數(shù)的順序要遵循程序員的習(xí)慣。一般地,應(yīng)將目的參數(shù)放在前面,源參數(shù)放在后面。如果將函數(shù)聲明為:void StringCopy(char *strSource,char *strDestination);別人在使用時(shí)可能會(huì)不假思索地寫(xiě)成如下形式:char str20;StringCopy(str,“HelloWorld”);/參數(shù)順序顛倒z【規(guī)則6-1-3】如果參數(shù)是指針,且僅作輸入用,則應(yīng)在類(lèi)型前加const,以防止該指針在函數(shù)體內(nèi)被意外修改。例如: void StringCopy(char *strDestination,const char *strSource);z【規(guī)則6-1-4】如果輸入?yún)?shù)以值傳遞的方式傳遞對(duì)象,則宜改用“const&”方式來(lái)傳遞,這樣可以省去臨時(shí)對(duì)象的構(gòu)造和析構(gòu)過(guò)程,從而提高效率?!窘ㄗh6-1-1】避免函數(shù)有太多的參數(shù),參數(shù)個(gè)數(shù)盡量控制在5個(gè)以內(nèi)。如果參數(shù)太多,在使用時(shí)容易將參數(shù)類(lèi)型或順序搞錯(cuò)?!窘ㄗh6-1-2】盡量不要使用類(lèi)型和數(shù)目不確定的參數(shù)。C標(biāo)準(zhǔn)庫(kù)函數(shù)printf是采用不確定參數(shù)的典型代表,其原型為:int printf(const chat *format,argument);這種風(fēng)格的函數(shù)在編譯時(shí)喪失了嚴(yán)格的類(lèi)型安全檢查。6.2返回值的規(guī)則z【規(guī)則6-2-1】不要省略返回值的類(lèi)型。C語(yǔ)言中,凡不加類(lèi)型說(shuō)明的函數(shù),一律自動(dòng)按整型處理。這樣做不會(huì)有什么好處,卻容易被誤解為void類(lèi)型。C+語(yǔ)言有很?chē)?yán)格的類(lèi)型安全檢查,不允許上述情況發(fā)生。由于C+程序可以調(diào)用C函數(shù),為了避免混亂,規(guī)定任何C+/C函數(shù)都必須有類(lèi)型。如果函數(shù)沒(méi)有返回值,那么應(yīng)聲明為void類(lèi)型。z【規(guī)則6-2-2】函數(shù)名字與返回值類(lèi)型在語(yǔ)義上不可沖突。違反這條規(guī)則的典型代表是C標(biāo)準(zhǔn)庫(kù)函數(shù)getchar。例如:charc;c=getchar();if(c=EOF)按照getchar名字的意思,將變量c聲明為char類(lèi)型是很自然的事情。但不幸的是getchar的確不是char類(lèi)型,而是int類(lèi)型,其原型如下:int getchar(void);由于c是char類(lèi)型,取值范圍是-128,127,如果宏EOF的值在char的取值范圍之外,那么if語(yǔ)句將總是失敗,這種“危險(xiǎn)”人們一般哪里料得到!導(dǎo)致本例錯(cuò)誤的責(zé)任并不在用戶,是函數(shù)getchar誤導(dǎo)了使用者。z【規(guī)則6-2-3】不要將正常值和錯(cuò)誤標(biāo)志混在一起返回。正常值用輸出參數(shù)獲得,而錯(cuò)誤標(biāo)志用return語(yǔ)句返回?;仡櫳侠?,C標(biāo)準(zhǔn)庫(kù)函數(shù)的設(shè)計(jì)者為什么要將getchar聲明為令人迷糊的int類(lèi)型呢? 他會(huì)那么傻嗎?在正常情況下,getchar的確返回單個(gè)字符。但如果getchar碰到文件結(jié)束標(biāo)志或發(fā)生讀錯(cuò)誤,它必須返回一個(gè)標(biāo)志EOF。為了區(qū)別于正常的字符,只好將EOF定義為負(fù)數(shù)(通常為負(fù)1)。因此函數(shù)getchar就成了int類(lèi)型。我們?cè)趯?shí)際工作中,經(jīng)常會(huì)碰到上述令人為難的問(wèn)題。為了避免出現(xiàn)誤解,我們應(yīng)該將正常值和錯(cuò)誤標(biāo)志分開(kāi)。即:正常值用輸出參數(shù)獲得,而錯(cuò)誤標(biāo)志用return語(yǔ)句返回。函數(shù)getchar可以改寫(xiě)成BOOL GetChar(char *c);雖然gechar比GetChar靈活,例如putchar(getchar();但是如果getchar用錯(cuò)了,它的靈活性又有什么用呢?【建議6-2-1】有時(shí)候函數(shù)原本不需要返回值,但為了增加靈活性如支持鏈?zhǔn)奖磉_(dá),可以附加返回值。例如字符串拷貝函數(shù)strcpy的原型:char *strcpy(char *strDest,const char *strSrc);strcpy函數(shù)將strSrc拷貝至輸出參數(shù)strDest中,同時(shí)函數(shù)的返回值又是strDest。這樣做并非多此一舉,可以獲得如下靈活性:charstr20;intlength=strlen(strcpy(str,“HelloWorld”);【建議6-2-2】如果函數(shù)的返回值是一個(gè)對(duì)象,有些場(chǎng)合用“引用傳遞”替換“值傳遞”可以提高效率。而有些場(chǎng)合只能用“值傳遞”而不能用“引用傳遞”,否則會(huì)出錯(cuò)。例如:class String/賦值函數(shù)String &operate=(const String &other);/相加函數(shù),如果沒(méi)有friend修飾則只許有一個(gè)右側(cè)參數(shù)friendStringoperate+(const String &s1,const String &s2);private:char*m_data;String的賦值函數(shù)operate=的實(shí)現(xiàn)如下:String &String:operate=(const String &other)if(this=&other)return*this;deletem_data; m_data=newcharstrlen(other.data)+1;strcpy(m_data,other.data);return*this;/返回的是*this的引用,無(wú)需拷貝過(guò)程對(duì)于賦值函數(shù),應(yīng)當(dāng)用“引用傳遞”的方式返回String對(duì)象。如果用“值傳遞”的方式,雖然功能仍然正確,但由于return語(yǔ)句要把*this拷貝到保存返回值的外部存儲(chǔ)單元之中,增加了不必要的開(kāi)銷(xiāo),降低了賦值函數(shù)的效率。例如:Stringa,b,c;a=b;/如果用“值傳遞”,將產(chǎn)生一次*this拷貝a=b=c;/如果用“值傳遞”,將產(chǎn)生兩次*this拷貝String的相加函數(shù)operate+的實(shí)現(xiàn)如下:Stringoperate+(const String &s1,const String &s2)String temp;deletetemp.data;/temp.data是僅含0的字符串temp.data=newcharstrlen(s1.data)+strlen(s2.data)+1;strcpy(temp.data,s1.data);strcat(temp.data,s2.data);return temp; 對(duì)于相加函數(shù),應(yīng)當(dāng)用“值傳遞”的方式返回String對(duì)象。如果改用“
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 運(yùn)營(yíng)助理培訓(xùn)大綱
- 南京交通職業(yè)技術(shù)學(xué)院《文化與翻譯(1)》2023-2024學(xué)年第一學(xué)期期末試卷
- 四川大學(xué)《報(bào)道攝影與圖片編輯》2023-2024學(xué)年第一學(xué)期期末試卷
- 合肥經(jīng)濟(jì)學(xué)院《建筑抗震設(shè)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 鄭州師范學(xué)院《形體與舞蹈II》2023-2024學(xué)年第一學(xué)期期末試卷
- 中班健康十只小貓咪故事
- 亳州學(xué)院《朗讀學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 環(huán)境因素識(shí)別與評(píng)價(jià)培訓(xùn)
- 柳州城市職業(yè)學(xué)院《英美文學(xué)導(dǎo)讀》2023-2024學(xué)年第一學(xué)期期末試卷
- 井岡山大學(xué)《建筑節(jié)能技術(shù)》2023-2024學(xué)年第一學(xué)期期末試卷
- 2024年 黃岡市法院系統(tǒng)招聘審判輔助人員考試真題試題含答案
- 荊州中學(xué)2024-2025學(xué)年高二下學(xué)期6月月考?xì)v史試題答案
- 公司消防網(wǎng)格化管理制度
- 外科換藥拆線技術(shù)規(guī)范
- 2025至2030中國(guó)氧化鋁纖維行業(yè)供需趨勢(shì)及投資風(fēng)險(xiǎn)報(bào)告
- 2025年中考考前最后一卷化學(xué)(武漢卷)(全解全析)
- 2026屆高考語(yǔ)文復(fù)習(xí):直擊2025年語(yǔ)文高考閱讀客觀題關(guān)鍵詞比對(duì)
- 電子政務(wù)概論-形考任務(wù)5(在線測(cè)試權(quán)重20%)-國(guó)開(kāi)-參考資料
- 19S406建筑排水管道安裝-塑料管道
- 國(guó)家開(kāi)放大學(xué)《病理生理學(xué)》形考任務(wù)1-4參考答案
評(píng)論
0/150
提交評(píng)論