




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1、C語言寫規(guī)范指南第 1 章文件結(jié)構(gòu)每個C程序通常分為兩個文件。一個文件用于保存程序的聲明( 件。另一個文件用于保存程序的實現(xiàn)( implementation ),C程序的頭文件以“ .h”為后綴,C程序的定義文件以“declaration ),稱為頭文 稱為定義( definition )文件。.c”為后綴。版權(quán)和版本的聲明版權(quán)和版本的聲明位于頭文件和定義文件的開頭(參見示例 版權(quán)信息。文件名稱,標識符,摘要。 當前版本號,作者 / 修改者,完成日期。 版本歷史信息。1-1),主要內(nèi)容有:1)2)3)4) /* *Copyright(c)2001, 吉林大學物理學院無線電*Allrightsr
2、eserved.* 文件名稱:* 文件標識:* 摘要: 簡要描述本文件的內(nèi)容* 當前版本:*作者: 輸入作者(或修改者)名字2007年7月20日*完成日期:*取代版本:*原作者*完成日期:輸入原作者(或修改者)名字2007年5月10日*/示例 1-1版權(quán)和版本的聲明1-1 )。1-2?!疽?guī)則1-2-1】【規(guī)則1-2-2】 索)?!疽?guī)則1-2-3】 始搜索)?!疽?guī)則1-2-4】#ifndef/#define/#endif結(jié)構(gòu)產(chǎn)生預處理塊。為了防止頭文件被重復引用,應當用<>格式來引用標準庫的頭文件(編譯器將從標準庫目錄開始搜用 #include用 #include“格式來引用非標準庫
3、的頭文件(編譯器將從用戶的工作目錄開#include后面使用TAB鍵控制排版。頭文件的結(jié)構(gòu)頭文件由三部分內(nèi)容組成:(1) 頭文件開頭處的版權(quán)和版本聲明(參見示例(2) 預處理塊。(3) 函數(shù)和類結(jié)構(gòu)聲明等。假設頭文件名稱為,頭文件的結(jié)構(gòu)參見示例頭文件中只存放“聲明”而不存放“定義” 全局變量在頭文件中聲明,在.c文件中定義“->”這類操作符前后不加空格?!窘ㄗh2-3-1】對于表達式比較長的for語句和if語句,為了緊湊起見可以適當?shù)厝サ粢恍┛?格,女0 for(i=0;i<10;i+)和 if(a<=b)&&(c<=d)【規(guī)則1-2-5】【規(guī)則1-2-6
4、】.h extern in tvalue; 聲明。.c in tvalue=0x10; 定義?!疽?guī)則1-2-7】局部變量在.c中定義(static) unsigned in tvalue;定義。void Fun c1(i nt x,i nt y,i nt z);Function。; b-> Function。;從左至右!+-(類型)sizeof+ - * &從右至左* / %從左至右+ -從左至右<< >>從左至右< <= > >=從左至右= !=從左至右&從左至右A從左至右|從左至右&&從左至右II從右至左
5、:從右至左= += -= *= /= %= &= A=|= <<= >>=從左至右表4-1運算符的優(yōu)先級與結(jié)合律【規(guī)則4-1-1】如果代碼行中的運算符比較多,用括號確定表達式的操作順序,避免使用默認的 優(yōu)先級。由于將表4-1熟記是比較困難的,為了防止產(chǎn)生歧義并提高可讀性,應當用括號確定表達式 的操作順序。例如:word = (high<<8)|low復合表達式如a=b=c=0這樣的表達式稱為復合表達式。允許復合表達式存在的理由是:(1)書寫簡潔;(2)可以提高編譯效率。但要防止濫用復合表達式?!疽?guī)則4-2-1】不要編寫太復雜的復合表達式。例如:i=a
6、>=b&&c<d&&c+f<=g+h;/復合表達式過于復雜【規(guī)則4-2-2】不要有多用途的復合表達式。例如:d=(a=b+c)+r;該表達式既求a值又求d值。應該拆分為兩個獨立的語句:a = b + c;d = a + r;【規(guī)則4-2-3】不要把程序中的復合表達式與“真正的數(shù)學表達式”混淆。例如:if(a<b<c)/a<b<c是數(shù)學表達式而不是程序表達式并不表示if (a<b)&&(b<c) 而是成了令人費解的if(a<b)<c)語句if語句是C語言中最簡單、最常用的語句,然而很
7、多程序員用隱含錯誤的方式 寫if語句。本節(jié)以“與零值比較”為例,展開討論。布爾變量與零值比較【規(guī)則4-3-1】不可將布爾變量直接與 TRUE FALSER者1、0進行比較。根據(jù)布爾類型的語義,零值為“假”(記為 FALSE,任何非零值都是“真”(記為 TRUE。TRUE勺值究竟是什么并沒有統(tǒng)一的標準。例如VisualC+將TRUE定義為1,而VisualBasic則將TRUE定義為-1。假設布爾變量名字為flag,它與零值比較的標準if語句如下:if (flag)/ 表示 flag 為真 if (flag)/ 表示 flag為假其它的用法都屬于不良風格,例如:if(flag=TRUE) if(
8、flag=1) if(flag=FALSE) if(flag=0)整型變量與零值比較【規(guī)則 4-3-2】應當將整型變量用“ =”或“! =”直接與 0比較。假設整型 變量的名字為value,它與零值比較的標準if語句如下:if(value=0) if(value!=0)不可模仿布爾變量的風格而寫成if(value)/會讓人誤解value是布爾變量 if(!value)浮點變量與零值比較【規(guī)則 4-3-3】不可將浮點變量用“ =”或“! =”與任何數(shù)字比較。千萬要留意,無論是float還是double類型的變量,都有精度限制。所以一定要避免將浮點變 量用“ =”或“! =”與數(shù)字比較,應該設法轉(zhuǎn)
9、化成“>=”或“ <=”形式。假設浮點變量的名字為 X,應當將 if(x=/ 隱含錯誤的比較轉(zhuǎn)化為 if(X>=-EPSINON)&&(X<=EPSINON) 其中EPSINOr是允許的誤差(即精度)。指針變量與零值比較【規(guī)則 4-3-4】應當將指針變量用“ 指針變量的零值是 指針變量的名字為 p,if(p=NULL)=”或"!=”與NULL比較?!翱铡?記為NULL)。盡管NULL的值與0相同,但是兩者意義不同。假設它與零值比較的標準if語句如下:/p與NULL顯式比較,強調(diào)P是指針變量if(p!=NULL)不要寫成if(p=0)/容易讓人誤
10、解P是整型變量if(p!=0)或者if(p)/容易讓人誤解P是布爾變量if(!P)對 if 語句的補充說明有時候我們可能會看到if(NULL=P)這樣古怪的格式。不是程序?qū)戝e了,是程序員為了防止將if(p=NULL)誤寫成if(p=NULL),而有意把p和NULL顛倒。編譯器認為if(p=NULL)是 合法的,但是會指出if(NULL=P)是錯誤的,因為NULL不能被賦值。程序中有時會遇到 if/else/return 的組合,應該將如下不良風格的程序if(condition)returnx;returny;改寫為if(condition)returnx;elsereturny;或者改寫成更加
11、簡練的return(conditionx:y);循環(huán)語句的效率C循環(huán)語句中,for語句使用頻率最高,while語句其次,do語句很少用。本節(jié)重點論述循環(huán) 體的效率。提高循環(huán)體效率的基本辦法是降低循環(huán)體的復雜性?!窘ㄗh 4-4-1】在多重循環(huán)中,如果有可能,應當將最長的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層,以減少 CPU夸切循環(huán)層的次數(shù)。例如示例4-4(b)的效率比示例4-4(a)的高。for (row=0; row<100; row+)for (col=0; col<5; col+)fum = sum+arowcol;示例4-4(a)低效率:長循環(huán)在最外層for (col=0; c
12、ol<5; col+)for (row=0; row<100; row+)fum = sum+arowcol;示例4-4(b)高效率:長循環(huán)在最內(nèi)層【建議 4-4-2 】如果循環(huán)體內(nèi)存在邏輯判斷,并且循環(huán)次數(shù)很大,宜將邏輯判斷移到循環(huán)體 的外面。示例4-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
13、; i<N; i+)if (conditionDoSomething();elseDoOtherthing();表4-4(c)效率低但程序簡潔if(condition)for(i=0;i<N;i+)DoSomething();elsefor(i=0;i<N;i+)DoOtherthing();表4-4(d)效率高但程序不簡潔語句的循環(huán)控制變量【規(guī)則4-5-1】不可在for循環(huán)體內(nèi)修改循環(huán)變量,防止 for循環(huán)失去控制?!窘ㄗh 4-5-1 】建議 for 語句的循環(huán)控制變量的取值采用“半開半閉區(qū)間”寫法。示例4-5(a)中的X值屬于半開半閉區(qū)間“ 0=<x<N”,起
14、點到終點的間隔為 N,循環(huán)次數(shù)為N。 示例4-5(b)中的X值屬于閉區(qū)間“ 0=<x<=N-T,起點到終點的間隔為 N-1,循環(huán)次數(shù)為N。 相比之下,示例4-5(a)的寫法更加直觀,盡管兩者的功能是相同的。for(intx=0;x<N;x+)示例4-5(a)循環(huán)變量屬于半開半閉區(qū)間 for(intx=0;x<=N-1;x+)示例4-5(b)循環(huán)變量屬于閉區(qū)間語句switch是多分支選擇語句,而if語句只有兩個分支可供選擇。雖然可以用嵌套的if語句來實現(xiàn)多分支選擇,但那樣的程序冗長難讀。這是switch語句存在的理由。switch語句的基本格式是:switch(varia
15、ble)casevalue1:break;casevalue2:break;default:break;【規(guī)則4-6-1】每個case語句的結(jié)尾不要忘了加 break,否則將導致多個分支重疊(除 非有意使多個分支重疊)?!疽?guī)則4-6-2】不要忘記最后那個default分支。即使程序真的不需要default處理,也應該保留語句defaultbreak;這樣做并非多此一舉,而是為了防止別人誤以為你忘了default處理。語句自從提倡結(jié)構(gòu)化設計以來,goto就成了有爭議的語句。首先,由于goto語句可以靈活跳轉(zhuǎn),如果不加限制,它的確會破壞結(jié)構(gòu)化設計風格。其次,goto語句經(jīng)常帶來錯誤或隱患。它可能跳
16、過了某些對象的構(gòu)造、變量的初始化、重要的計算等語句,例如:goto String intstate;s1,s2; / 被 goto 跳過 sum = 0;/ 被 goto 跳過state:如果編譯器不能發(fā)覺此類錯誤,每用一次goto語句都可能留下隱患。很多人建議廢除C的goto語句,以絕后患。但實事求是地說,錯誤是程序員自己造成的, 不是goto的過錯。goto語句至少有一處可顯神通,它能從多重循環(huán)體中咻地一下子跳到外 面,用不著寫很多次的 break 語句 ;例如gotoerror;error:就象樓房著火了,來不及從樓梯一級一級往下走,可從窗口跳出火坑。所以我們主張少 用、慎用 goto
17、語句,而不是禁用。第 5 章常量常量是一種標識符,它的值在運行期間恒定不變。C語言用#define來定義常量(稱為宏常量)。C+語言除了 #defi ne外還可以用const來定義常量(稱為con st常量)。為什么需要常量1)2)3)如果不使用常量,直接在程序中填寫數(shù)字或字符串,將會有什么麻煩程序的可讀性(可理解性)變差。程序員自己會忘記那些數(shù)字或字符串是什么意思,用 戶則更加不知它們從何處來、表示什么。在程序的很多地方輸入同樣的數(shù)字或字符串,難保不發(fā)生書寫錯誤。如果要修改數(shù)字或字符串,則會在很多地方改動,既麻煩又容易出錯?!疽?guī)則 5-1-1 】例如:#define constint con
18、stfloat盡量使用含義直觀的常量來表示那些將在程序中多次出現(xiàn)的數(shù)字或字符串。MAX 100/*C語言的宏常量*/MAX=100;/C+語言的 const常量Pl=;/C+語言的const常量與 #define的比較C+語言可以用 點:(1)const來定義常量,也可以用 #define來定義常量。但是前者比后者有更多的優(yōu)con st常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型。編譯器可以對前者進行類型安全檢 查。而對后者只進行字符替換,沒有類型安全檢查,并且在字符替換可能會產(chǎn)生意 料不到的錯誤(邊際效應)。2)有些集成化的調(diào)試工具可以對con st常量進行調(diào)試,但是不能對宏常量進行調(diào)試?!疽?guī)則5-
19、2-1】在C+程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。常量定義規(guī)則【規(guī)則 5-3-1】需要對外公開的常量放在頭文件中,不需要對外公開的常量放在定義文件的頭 部。為便于管理,可以把不同模塊的常量集中存放在一個公共的頭文件中?!疽?guī)則 5-3-2 】如果某一常量與其它常量密切相關(guān),應在定義中包含這種關(guān)系,而不應給出一些孤立的值。例如:const floatRADIUS=100;const floatDIAMETER=RADIUS*2;第 6 章函數(shù)設計函數(shù)是C程序的基本功能單元,其重要性不言而喻。函數(shù)設計的細微缺點很容易導致該函數(shù)被錯用,所以光使函數(shù)的功能正確是不夠
20、的。本章重點論述函數(shù)的接口設計和內(nèi)部實現(xiàn)的一些規(guī)則。函數(shù)接口的兩個要素是參數(shù)和返回值。C語言中,函數(shù)的參數(shù)和返回值的傳遞方式有兩種:值傳遞(P assbyvalue)和指針傳遞(passby pointer)。C+語言中多了引用傳遞(passbyrefere nee)。由于引用傳遞的性質(zhì)象指針傳遞,而使用方式卻象值傳遞,初學者常 常迷惑不解,容易引起混亂,請先閱讀節(jié)“引用與指針的比較”。參數(shù)的規(guī)則【規(guī)則 6-1-1】參數(shù)的書寫要完整,不要貪圖省事只寫參數(shù)的類型而省略參數(shù)名字。如果函 數(shù)沒有參數(shù),則用 void 填充。例如:void SetValue(int width, int height)
21、;/ 良好的風格/ 不良的風格/ 良好的風格/ 不良的風格void SetValue(int,int);float GetValue(void);float GetValue();順序要合理?!疽?guī)則 6-1-2】參數(shù)命名要恰當,例如編寫字符串拷貝函數(shù)StringCopy,它有兩個參數(shù)。如果把參數(shù)名字起為str1和str2,例如void StringCopy(char *str1,char *str2);那么我們很難搞清楚究竟是把str1拷貝到str2中,還是剛好倒過來??梢园褏?shù)名字起得更有意義,如叫strSource和strDestination。這樣從名字上就可以看出應該把 strSour
22、ce 拷貝到 strDestination。還有一個問題,這兩個參數(shù)那一個該在前那一個該在后參數(shù)的順序要遵循程序員的習慣。 一般地,應將目的參數(shù)放在前面,源參數(shù)放在后面。如果將函數(shù)聲明為:void StringCopy(char *strSource,char *strDestination); 別人在使用時可能會不假思索地寫成如下形式:char str20;StringCopy(str,“ HelloWorld ”);/ 參數(shù)順序顛倒const ,以防止該指針在函const& ”方式來傳遞,【規(guī)則 6-1-3 】如果參數(shù)是指針,且僅作輸入用,則應在類型前加 數(shù)體內(nèi)被意外修改。例如:v
23、oid StringCopy(char *strDestination , const char *strSource);【規(guī)則 6-1-4 】如果輸入?yún)?shù)以值傳遞的方式傳遞對象,則宜改用“ 這樣可以省去臨時對象的構(gòu)造和析構(gòu)過程,從而提高效率。【建議 6-1-1】避免函數(shù)有太多的參數(shù),參數(shù)個數(shù)盡量控制在5個以內(nèi)。如果參數(shù)太多,在使用時容易將參數(shù)類型或順序搞錯?!窘ㄗh 6-1-2 】盡量不要使用類型和數(shù)目不確定的參數(shù)。C標準庫函數(shù)printf是采用不確定參數(shù)的典型代表,其原型為:int pnntf(const ehat *format,argument );這種風格的函數(shù)在編譯時喪失了嚴格的類型
24、安全檢查。返回值的規(guī)則【規(guī)則 6-2-1 】不要省略返回值的類型。C語言中,凡不加類型說明的函數(shù),一律自動按整型處理。這樣做不會有什么好處,卻容易 被誤解為void類型。C+語言有很嚴格的類型安全檢查,不允許上述情況發(fā)生。由于C+程序可以調(diào)用C函數(shù),為了避免混亂,規(guī)定任何C+/C函數(shù)都必須有類型。如果函數(shù)沒有返回值,那么應聲明為void類型?!疽?guī)則 6-2-2】函數(shù)名字與返回值類型在語義上不可沖突。違反 這條規(guī)則的典型代表是 C標準庫函數(shù)getchar。例如:charc;c=getchar();if(c=EOF)按照getchar名字的意思,將變量c聲明為char類型是很自然的事情。但不幸的是
25、 getchar的確不是char類型,而是int類型,其原型如下:int getchar(void);由于C是char類型,取值范圍是-128,127,如果宏EOF勺值在char的取值范圍之外,那 么if語句將總是失敗,這種“危險”人們一般哪里料得到!導致本例錯誤的責任并不在用 戶,是函數(shù)getchar誤導了使用者。【規(guī)則 6-2-3 】不要將正常值和錯誤標志混在一起返回。正常值用輸出參數(shù)獲得,而錯誤標 志用 return 語句返回。回顧上例,C標準庫函數(shù)的設計者為什么要將getchar聲明為令人迷糊的int類型呢他會那么傻嗎getchar碰到文件結(jié)束標志或發(fā)生讀錯 只好將EOF定義為負數(shù)在正
26、常情況下,getchar的確返回單個字符。但如果 誤,它必須返回一個標志 EOF。為了區(qū)別于正常的字符,為了避免出現(xiàn)誤解,我們應該將return 語句返回。(通常為負1)。因此函數(shù)getchar就成了 int類型。 我們在實際工作中,經(jīng)常會碰到上述令人為難的問題。正常值和錯誤標志分開。即:正常值用輸出參數(shù)獲得,而錯誤標志用函數(shù) getchar可以改寫成 BOOL GetChar(char *c);雖然gechar比GetChar靈活,例如putchar(getchar();但是如果getchar用錯了,它的靈活性又 有什么用呢【建議 6-2-1】有時候函數(shù)原本不需要返回值,但為了增加靈活性如支
27、持鏈式表達,可以附 加返回值。例如字符串拷貝函數(shù)strcpy的原型:char *strcpy(char *strDest , const char *strSrc);strcpy函數(shù)將strSrc拷貝至輸出參數(shù)strDest中,同時函數(shù)的返回值又是strDest。這樣做并非多此一舉,可以獲得如下靈活性:charstr20;HelloWorld ” );int length=strlen(strcpy(str,建議 6-2-2】如果函數(shù)的返回值是一個對象,有些場合用“引用傳遞”替換“值傳遞”可以提高效率。而有些場合只能用“值傳遞”而不能用“引用傳遞”,否則會出錯。 例如:class String
28、/ 賦值函數(shù)String &operate=(const String &other);/ 相加函數(shù),如果沒有 friend 修飾則只許有一個右側(cè)參數(shù)friend String operate+(const String &s1,const String &s2);private:char*m_data;String 的賦值函數(shù) operate= 的實現(xiàn)如下:String &String:operate=(const String &other)if(this=&other)return*this;deletem_data;m_data=
29、newcharstrlen+1;strcpy(m_data,;return*this;/ 返回的是 *this 的引用,無需拷貝過程對于賦值函數(shù),應當用“引用傳遞”的方式返回Stri ng對象。如果用“值傳遞”的方式,雖然功能仍然正確,但由于 return 語句要把 *this 拷貝到保存返回值的外部存儲單元之 中,增加了不必要的開銷,降低了賦值函數(shù)的效率。例如:Stringa,b,c;a=b;a=b=c;/ 如果用“值傳遞”,將產(chǎn)生一次/ 如果用“值傳遞”,將產(chǎn)生兩次*this 拷貝*this 拷貝Stri ng的相加函數(shù)operate+ 的實現(xiàn)如下:String operate+(cons
30、t String &s1,const String &s2)String temp;/ 是僅含 0'的字符串=newcharstrlen+strlen+1;strcpy,;strcat,;return temp;對于相加函數(shù),應當用“值傳遞”的方式返回Stri ng對象。如果改用“引用傳遞”,那么函數(shù)返回值是一個指向局部對象temp的“引用”。由于temp在函數(shù)結(jié)束時被自動銷毀,將導致返回的“引用”無效。例如:c=a+b;此時a+b并不返回期望值,C什么也得不到,流下了隱患。函數(shù)內(nèi)部實現(xiàn)的規(guī)則不同功能的函數(shù)其內(nèi)部實現(xiàn)各不相同,看起來似乎無法就“內(nèi)部實現(xiàn)”達成一致的觀 點
31、。但根據(jù)經(jīng)驗,我們可以在函數(shù)體的“入口處”和“出口處”從嚴把關(guān),從而提高函數(shù)的 質(zhì)量?!疽?guī)則 6-3-1 】在函數(shù)體的“入口處”,對參數(shù)的有效性進行檢查。assert)來防很多程序錯誤是由非法參數(shù)引起的,我們應該充分理解并正確使用“斷言”( 止此類錯誤。詳見節(jié)“使用斷言”?!疽?guī)則 6-3-2】在函數(shù)體的“出口處”,對 return 語句的正確性和效率進行檢查。如果函數(shù)有返回值,那么函數(shù)的“出口處”是return語句。我們不要輕視return語句。如果return 語句寫得不好,函數(shù)要么出錯,要么效率低下。注意事項如下:(1) return 語句不可返回指向“棧內(nèi)存”的“指針”或者“引用”,因為
32、該內(nèi)存在函數(shù)體結(jié)束 時被自動銷毀。例如char *Func(void) return String(s1+s2);char str="helloworld的內(nèi)存位于棧上return str;/將導致錯誤2) 要搞清楚返回的究竟是3) 如果函數(shù)返回值是一個對象,值”、“指針”還是“引用”。要考慮 return 語句的效率。例如這是臨時對象的語法,表示“創(chuàng)建一個臨時對象并返回它”。不要以為它與“先創(chuàng)建一個 局部對象 temp 并返回它的結(jié)果”是等價的,如String temp(s1+s2);return temp;實質(zhì)不然,上述代碼將發(fā)生三件事。首先, temp 對象被創(chuàng)建,同時完成初始
33、化;然后拷 貝構(gòu)造函數(shù)把temp拷貝到保存返回值的外部存儲單元中;最后,temp在函數(shù)結(jié)束時被銷毀(調(diào)用析構(gòu)函數(shù))。然而“創(chuàng)建一個臨時對象并返回它”的過程是不同的,編譯器直接把臨 時對象創(chuàng)建并初始化在外部存儲單元中,省去了拷貝和析構(gòu)的化費,提高了效率。類似地,我們不要將return int(x+y);/ 創(chuàng)建一個臨時變量并返回它寫成int temp=x+y;return temp;由于內(nèi)部數(shù)據(jù)類型如 int,float,double 的變量不存在構(gòu)造函數(shù)與析構(gòu)函數(shù),雖然該“臨時變量 的語法”不會提高多少效率,但是程序更加簡潔易讀。函數(shù)的功能要單一,不要設計多用途的函數(shù)。 函數(shù)體的規(guī)模要小,盡量
34、控制在50行代碼之內(nèi)。盡量避免函數(shù)帶有“記憶”功能。相同的輸入應當產(chǎn)生相同的輸出。帶有“記其它建議【建議 6-4-1 】【建議 6-4-2 】【建議 6-4-3 】 憶”功能的函數(shù),其行為可能是不可預測的,因為它的行為可能取決于某種“記憶狀態(tài)”。這樣的函數(shù)既不易理解又不利于測試和維護。在C/C+語言中,函數(shù)的static局部變量是函數(shù)的“記憶”存儲器。建議盡量少用static局部變量,除非必需?!窘ㄗh 6-4-4】不僅要檢查輸入?yún)?shù)的有效性,還要檢查通過其它途徑進入函數(shù)體內(nèi)的變量 的有效性,例如全局變量、文件句柄等?!窘ㄗh 6-4-5】用于出錯處理的返回值一定要清楚,讓使用者不容易忽視或誤解錯
35、誤情況。使用斷言程序一般分為Debug版本和Release版本,Debug版本用于內(nèi)部調(diào)試,Release版本發(fā)行給用 戶使用。斷言assert是僅在Debug版本起作用的宏,它用于檢查“不應該”發(fā)生的情況。示 例6-5是一個內(nèi)存復制函數(shù)。在運行過程中,如果assert的參數(shù)為假,那么程序就會中止(一般assert)。void地還會出現(xiàn)提示對話,說明在什么地方引發(fā)了*memcpy(void *pvTo,const void *pvFrom,size_t size)assert(pvTo!=NULL)&&(pvFrom!=NULL);/ 使用斷言/防止改變pvTo的地址/防止改變
36、 pvFrom 的地址byte*pbTo=(byte*)pvTo;byte*pbFrom=(byte*)pvFrom;while(size->0)*pbTo+=*pbFrom+;returnpvTo;示例 6-5復制不重疊的內(nèi)存塊assert不是一個倉促拼湊起來的宏。為了不在程序的Debug版本和Release版本引起差另h assert不應該產(chǎn)生任何副作用。所以assert不是函數(shù),而是宏。程序員可以把assert看成一個在任何系統(tǒng)狀態(tài)下都可以安全使用的無害測試手段。如果程序在assert處終止了,并不是說含有該assert的函數(shù)有錯誤,而是調(diào)用者出了差錯,assert可以幫助我們找到
37、發(fā)生錯誤的原因。很少有比跟蹤到程序的斷言,卻不知道該斷言的作用更讓人沮喪的事了。你化了很多時間,不是為了排除錯誤,而只是為了弄清楚這個錯誤到底是什么。有的時候,程序員偶爾還會設計出 有錯誤的斷言。所以如果搞不清楚斷言檢查的是什么,就很難判斷錯誤是出現(xiàn)在程序中,還是 出現(xiàn)在斷言中。幸運的是這個問題很好解決,只要加上清晰的注釋即可。這本是顯而易見的事 情,可是很少有程序員這樣做。這好比一個人在森林里,看到樹上釘著一塊“危險”的大牌 子。但危險到底是什么樹要倒有廢井有野獸除非告訴人們“危險”是什么,否則這個警告牌難 以起到積極有效的作用。難以理解的斷言常常被程序員忽略,甚至被刪除?!疽?guī)則 6-5-1 】使用斷言捕捉不應該發(fā)生的非法情況。不要混淆非法情況與錯誤情況 之間的區(qū)別,后者是必然存在的并且是一定要作出處理的?!疽?guī)則 6-5-2】在函數(shù)的入口處,使用斷言檢查參數(shù)的有效性(合法性)?!窘ㄗh 6-5-1 】在編寫函數(shù)時,要進行反復的考查,并且自問:“我打算做哪些假定”一旦 確定了的假定,就要使用斷言對假定進行檢查。【建議 6-5-2】一般教科書都鼓勵程序員們進行防錯設計,但要記住這種編程風格可能會 隱瞞錯誤。當進行防錯設計時,如果“不可能發(fā)生”的事情的確發(fā)生了,則要使用斷言 進行報警。引用與指針的比較弓I用是C+中的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 文具企業(yè)競爭力分析與提升策略考核試卷
- 搬家行業(yè)節(jié)能減排與綠色物流考核試卷
- 期貨市場交易風險監(jiān)測與預警考核試卷
- 小學生抗旱主題班會課件
- 客廳家具批發(fā)考核試卷
- 工業(yè)氣體批發(fā)考核試卷
- 2023視頻監(jiān)控及火災報警系統(tǒng)施工作業(yè)指導書
- 上海建房合同范本
- 空調(diào)技術(shù)入股合同范本
- 汽修門頭合作合同范本
- 2025年山東青島自貿(mào)發(fā)展有限公司招聘筆試參考題庫含答案解析
- 液化氣罐的使用和安全防范
- 2025年中考物理總復習《內(nèi)能》專項測試卷含有答案
- 會計法律法規(guī)答題答案
- 2024年無錫工藝職業(yè)技術(shù)學院高職單招語文歷年參考題庫含答案解析
- 劇本殺范本完整版
- 北師大版一年級語文下冊第一單元元宵節(jié)《1元宵節(jié)》
- 2024年全球協(xié)作機器人產(chǎn)業(yè)發(fā)展白皮書
- 消防設施維保過程風險及保障措施
- 智能交通系統(tǒng)概論 課件全套 朱文興 第1-10章 緒論 - 城市交通子區(qū)控制系統(tǒng)
- 一鍵自動生成spccpkmsappk數(shù)據(jù)工具
評論
0/150
提交評論