C語(yǔ)言格式書寫規(guī)范_第1頁(yè)
C語(yǔ)言格式書寫規(guī)范_第2頁(yè)
C語(yǔ)言格式書寫規(guī)范_第3頁(yè)
C語(yǔ)言格式書寫規(guī)范_第4頁(yè)
C語(yǔ)言格式書寫規(guī)范_第5頁(yè)
已閱讀5頁(yè),還剩21頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、精品文檔C 吾言書寫規(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é)院

2、無(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ù)和類結(jié)構(gòu)聲明等。假設(shè)頭文件名稱為SCL_SPI.h,頭文件的結(jié)構(gòu)參見(jiàn)示例 1-2。【規(guī)則1-2-1 為了防止頭文件被重復(fù)引用,應(yīng)當(dāng)用 #if

3、ndef/#define/#endif結(jié)構(gòu)產(chǎn)生預(yù)處理【規(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ù)的頭文件(編譯器將從用戶的工作目錄開(kāi)始搜索)?!疽?guī)則1-2-4 #include 后面使用TABM控制排版?!疽?guī)則1-2-5】頭文件中只存放“聲明”而不存放“定義”【規(guī)則1-2-6全局變量在頭文件中聲明,在.c文件中定義.h extern in tvalue; 聲明。.c in tvalue=0x10; 定義。【規(guī)則1-2-7 局部

4、變量在.c中定義(static) unsigned in tvalue; 定義。/版權(quán)和版本聲明見(jiàn)示例1-1 ,此處省略。防止SCL_SPI.h被重復(fù)引用引用標(biāo)準(zhǔn)庫(kù)的頭文件/引用非標(biāo)準(zhǔn)庫(kù)的頭文件#ifndefSCL_SPI_H /#defineSCL_SPI_H#include<p30f6014A.h>/#include"SCL_CAN.hvoid 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)示例

5、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_SPm ” 引用頭文件 /全局變量定義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ì)頭文件的作用略作解釋:(1)通過(guò)頭文件來(lái)調(diào)用庫(kù)功能。在很多場(chǎng)合,源代碼不

6、便(或不準(zhǔn))向用戶公布,只要向用 戶提供頭文件和二進(jìn)制的庫(kù)即可。用戶只需要按照頭文件中的接口聲明來(lái)調(diào)用庫(kù)功能,而不 必關(guān)心接口怎么實(shí)現(xiàn)的。編譯器會(huì)從庫(kù)中提取相應(yīng)的代碼。(2)頭文件能加強(qiáng)類型安全檢查。如果某個(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)有

7、必要公開(kāi)其“聲明”。為了加強(qiáng)信息隱藏,這些私有的頭文件可以和定義文件存放于同一個(gè)目錄。第2章程序的版式版式雖然不會(huì)影響程序的功能,但會(huì)影響可讀性。程序的版式追求清晰、美觀,是程序風(fēng) 格的重要構(gòu)成因素??梢园殉绦虻陌媸奖扔鳛椤皶ā薄:玫摹皶ā笨勺屓藢?duì)程序一目了然,看得興致勃 勃。差的程序“書法”如螃蟹爬行,讓人看得索然無(wú)味,更令維護(hù)者煩惱有加。請(qǐng)程序員們 學(xué)習(xí)程序的“書法”,彌補(bǔ)大學(xué)計(jì)算機(jī)教育的漏洞,實(shí)在很有必要。2.1 空行空行起著分隔程序段落的作用??招械皿w(不過(guò)多也不過(guò)少)將使程序的布局更加清 晰??招胁粫?huì)浪費(fèi)內(nèi)存,雖然打印含有空行的程序是會(huì)多消耗一些紙張,但是值得。所以不 要舍不得用

8、空行。【規(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)statementl;/空行if (condition)statement2; elsestatement3;/空行statement4;示例2-1(b)函數(shù)內(nèi)部的空行2.2 代碼行【規(guī)則2-2-1】一行代碼只做一件事情,如只定義一個(gè)變量,或只寫一條語(yǔ)句。這樣的代碼容

9、易閱 讀,并且方便于寫注釋?!疽?guī)則2-2-2】if、for、while、do等語(yǔ)句自占一行,執(zhí)行語(yǔ)句不得緊跟其后。不論執(zhí)行語(yǔ)句有多 少都要加。這樣可以防止書寫失誤。示例2-2 (a)為風(fēng)格良好的代碼行,示例 2-2 (b)為風(fēng)格不良的代碼行。ntwidth;/寬度ntheight;/高度ntdepth;/深度中間使用TAB1控制距離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

10、(); / 使用 TAB®控制距離 if(width<height)dosomething();for (initialization; condition; update)dosomething(); / 使用 TAB!控制距離 /空行other();for(initialization;condition;update)dosomething();other();示例2-2(a)風(fēng)格良好的代碼行示例2-2(b)風(fēng)格不良的代碼行【建議2-2-1盡可能在定義變量的同時(shí)初始化該變量(就近原則)如果變量的引用處和其定義處相隔比較遠(yuǎn),變量的初始化很容易被忘記。如果引用了未被初 始化的

11、變量,可能會(huì)導(dǎo)致程序錯(cuò)誤。本建議可以減少隱患。例如intwidth=10;/定義并初紿化widthintheight=10;/定義并初紿化heightintdepth=10;/定義并初紿化depth使用TAB1控制距離2.3 代碼行內(nèi)的空格【規(guī)則2-3-1 關(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-3-2】函數(shù)名之后不要留空格,緊跟左括號(hào)(,以與關(guān)鍵字區(qū)別?!疽?guī)則2-3-3】,(/向后緊跟,)、,、;向前緊跟,緊跟處

12、不留空格。【規(guī)則2-3-4 '之后要留空格,如 Function(x,y,z)。如果;不是一行的結(jié)束符 號(hào),其后要留空格,如 for (initialization; condition; update)。【規(guī)則2-3-5賦值操作符、比較操作符、算術(shù)操作符、邏輯操作符、位域操作符,如“="、"+ = ”">="、“<="、" +”、“ *”、"'、" &&'、" | "、“<<”,"人等二元操作符的前后應(yīng)當(dāng)加空格?!疽?guī)則2

13、-3-61一元操作符如“ ! ”、“ ”、“ +”、“ - "、“ &” (地址運(yùn)算符)等前 后不加空格?!疽?guī)則2-3-7】象“ 口”、" . ”、“ ->”這類操作符前后不加空格。【建議2-3-1 對(duì)于表達(dá)式比較長(zhǎng)的for語(yǔ)句和if語(yǔ)句,為了緊湊起見(jiàn)可以適當(dāng)?shù)厝サ粢恍┛崭瘢?for(i=0;i<10;i+) 和 if(a<=b)&&(c<=d)void Func1(int x,int y,int z);void Func1 (int x,int y,int z);/良好的風(fēng)格/不良的風(fēng)格if (year >= 200

14、0) if(year>=2000) if (a>=b) && (c<=d) if(a>=b&&c<=d)/良好的風(fēng)格/不良的風(fēng)格/良好的風(fēng)格/不良的風(fēng)格for (i=0; i<10; i+) for(i=0;i<10;i+) for(I = 0; I < 10; I+)/良好的風(fēng)格/不良的風(fēng)格/過(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)格array5 = 0;/ 不要寫成 ar

15、ray 5 = 0;a.Function();/ /、要寫成 a . Function。;b->Function();/ /、要寫成 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è)TABM處左對(duì)齊。示例2-4 (a)為風(fēng)格良好的對(duì)齊,示例 2-4 (b)為風(fēng)格不良的對(duì)齊。void Function (int x)/programcodeVoid Function(intx)/programcodeif (c

16、ondition)/programcode else/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)行拆分【規(guī)則

17、2-5-1 代碼行最大長(zhǎng)度宜控制在70至80個(gè)字符以內(nèi)。代碼行不要過(guò)長(zhǎng),否則眼睛看不過(guò)來(lái),也不便于打印?!疽?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 <= v

18、ery_longer_variable16)dosomething();Virtual CMatrixCMultiplyMatrix (CMatrixleftMatrix,CMatrixrightMatrix);使用 TAB® 控制距離For (very_longer_initialization; very_longer_condition;使用 TAB® 控制距離very_longer_update) dosomething();示例2-5長(zhǎng)行的拆分2.6 修飾符的位置修飾符*和&應(yīng)該靠近數(shù)據(jù)類型還是該靠近變量名,是個(gè)有爭(zhēng)議的活題。若將修飾符*靠近數(shù)據(jù)類型,例如

19、:int*x;從語(yǔ)義上講此寫法比較直觀,即x是int類型的指針。上述寫法的弊端是容易引起誤解,例如: int* x,y;此處y容易被誤解為指針變量。雖然將x和y分行定義可以避免誤解,但并不是人人都愿意這樣做?!疽?guī)則2-6-1】應(yīng)當(dāng)將修飾符*和&緊靠變量名例如:char int*name;*x,y; /此處y不會(huì)被誤解為指針2.7 注釋笊言的注釋符為" /*/ : C+語(yǔ)言中,程序塊白注釋常采用" /*/ : 行注釋一般采用“”。注釋通常用于:(1)版本、版權(quán)聲明;(2)函數(shù)接口說(shuō)明;(3)重要的代碼行或段落提示。雖然注釋有助于理解代碼,但注意不可過(guò)多地使用注釋。參見(jiàn)

20、示例2-6 ?!疽?guī)則2-7-1注釋是對(duì)代碼的“提示”,而不是文檔。程序中的注釋不可喧賓奪主,注釋 太多了會(huì)讓人眼花繚亂。注釋的花樣要少?!疽?guī)則2-7-2】如果代碼本來(lái)就是清楚的,則不必加注釋。否則多此一舉,令人厭煩。例如i+;/i加1,多余的注釋【規(guī)則2-7-3 邊寫代碼邊注釋,修改代碼同時(shí)修改相應(yīng)的注釋,以保證注釋與代碼的一致 性。不再有用的注釋要?jiǎng)h除?!疽?guī)則2-7-4 注釋應(yīng)當(dāng)準(zhǔn)確、易懂,防止注釋有二義性。錯(cuò)誤的注釋不但無(wú)益反而有害?!疽?guī)則2-7-5盡量避免在注釋中使用縮寫,特別是不常用縮寫。【規(guī)則2-7-6注釋的位置應(yīng)與被描述的代碼相鄰,可以放在代碼的上方或右方,不可放在 下方?!疽?guī)則2

21、-7-8】當(dāng)代碼比較長(zhǎng),特別是有多重嵌套時(shí),應(yīng)當(dāng)在一些段落的結(jié)束處加注釋,便 于閱讀。/* 函數(shù)介紹:* 輸入?yún)?shù):* 輸出參數(shù):* 返回值 :* /Void Function(floatx, floaty, floatz) if() while(endofwhile/endofif示例2-6程序的注釋第3章命名規(guī)則比較著名的命名規(guī)則當(dāng)推 Microsoft公司的“匈牙利”法,該命名規(guī)則的主要思想是“在變量和函數(shù)名中加入前綴以增進(jìn)人們對(duì)程序的理解”。例如所有的字符變量均以ch為前綴,若是指針變量則追加前綴p。如果一個(gè)變量由ppch開(kāi)頭,則表明它是指向字符指針的指“匈牙利”法最大的缺點(diǎn)是煩瑣,例

22、如inti,j,k;floatx,y,z;倘若采用“匈牙利”命名規(guī)則,則應(yīng)當(dāng)寫成int ii, ij, ik; /前綴i表示int類型float fX, fY, fZ; /前綴f表示float類型如此煩瑣的程序會(huì)讓絕大多數(shù)程序員無(wú)法忍受。據(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í)施。絕對(duì)杜絕漢語(yǔ)拼音命名法3.1 共性規(guī)則本節(jié)論述的共性規(guī)則是被大多數(shù)程序員采納的,我們應(yīng)當(dāng)在遵循這些共性規(guī)則的前提

23、下, 再擴(kuò)充特定的規(guī)則,如 3.2節(jié)?!疽?guī)則3-1-1】標(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ī)則3-1-2 標(biāo)識(shí)符的長(zhǎng)度應(yīng)當(dāng)符合" min-length&&max-information ”原則。幾十年前老ANSIC規(guī)定名字不準(zhǔn)超過(guò)6個(gè)字符,現(xiàn)今的C不再有此限制。一般來(lái)說(shuō),長(zhǎng)名字 能更好地表達(dá)含義,所以函數(shù)名、變量名、類名長(zhǎng)達(dá)十幾個(gè)字符不足為怪。那么名字是否越 長(zhǎng)約好?不見(jiàn)

24、得!例如變量名maxval就比maxValueUntilOverflow 好用。單字符的名字也是有 用的,常見(jiàn)的如i,jKm,n,x,y,z等,它們通??捎米骱瘮?shù)內(nèi)的局部變量?!疽?guī)則3-1-3】命名規(guī)則盡量與所采用的操作系統(tǒng)或開(kāi)發(fā)工具的風(fēng)格保持一致。例如Windows應(yīng)用程序的標(biāo)識(shí)符通常采用“大小寫”混排的方式,如 AddChild 。而Unix應(yīng)用程序的標(biāo)識(shí)符通常采用“小寫加下劃線”的方式,如 add_child 。別把這兩類風(fēng)格混在 一起用?!疽?guī)則3-1-4】程序中不要出現(xiàn)僅靠大小寫區(qū)分的相似的標(biāo)識(shí)符。例如:int x, X; /變量x與矯易混淆voidfoo(intx); / 函數(shù) fo

25、o 與 FOO易混淆voidFOO(floatx);【規(guī)則3-1-5】程序中不要出現(xiàn)標(biāo)識(shí)符完全相同的局部變量和全局變量,盡管兩者的作用域 不同而不會(huì)發(fā)生語(yǔ)法錯(cuò)誤,但會(huì)使人誤解?!疽?guī)則3-1-6變量的名字應(yīng)當(dāng)使用“名詞”或者“形容詞+名詞”。例如:floatvalue;floatoldValue;floatnewValue;【規(guī)則3-1-7全局函數(shù)的名字應(yīng)當(dāng)使用“動(dòng)詞”或者“動(dòng)詞+名詞”(動(dòng)賓詞組)。類的 成員函數(shù)應(yīng)當(dāng)只使用“動(dòng)詞”,被省略掉的名詞就是對(duì)象本身。例如:DrawBox();/全局函數(shù)box->Draw();/類的成員函數(shù)【規(guī)則3-1-8 用正確的反義詞組命名具有互斥意義的變量

26、或相反動(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ā)?!疽?guī)則3-2-1】類名和函數(shù)名用大寫字母開(kāi)頭的單詞組合而成。例如:classNode;/類名classLeafNode;/類

27、名voidDraw(void);/ 函數(shù)名voidSetValue(int value);/函數(shù)名【規(guī)則3-2-2變量和參數(shù)用小寫字母開(kāi)頭的單詞組合而成。例 如:BOOLflag;intdrawMode;【規(guī)則3-2-3】常量全用大寫的字母,用下劃線分割單詞。例 如:const intMAX = 100;const intMAX_LENGTH = 100;【規(guī)則3-2-4 靜態(tài)變量加前綴s_ (表示static )。例如:void Init()static ints_initValue;靜態(tài)變量【規(guī)則3-2-5 如果不得已需要全局變量,則使全局變量加前綴g_ (表示global )。例如:in

28、tg_howManyPeople; / 全局變量intg_howMuchMoney/ 全局變量【規(guī)則3-2-6】類的數(shù)據(jù)成員加前綴 m_ (表示membe。,這樣可以避免數(shù)據(jù)成員與成員函數(shù) 的參數(shù)同名。例如:Void Object:SetValue(int width, int height)m_width = width;m_height = height;【規(guī)則3-2-7為了防止某一軟件庫(kù)中的一些標(biāo)識(shí)符和其它軟件庫(kù)中的沖突,可以為OpenG的所有庫(kù)函數(shù)均以gl開(kāi)各種標(biāo)識(shí)符加上能反映軟件性質(zhì)的前綴。例如三維圖形標(biāo)準(zhǔn) 頭,所有常量(或宏定義)均以 GI#頭。第4章表達(dá)式和基本語(yǔ)句表達(dá)式和語(yǔ)句都

29、屬于 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é)合律()->.從左至右從:! + -(類型)sizeof:從右至左高+ - *&* / %從左至右到ZrT+ -從左至右低 排<< >>從左至右列<<=> >=從左至右=!=從左至右&從左至右A從左至右|從左至右&&從左至右|從右至左?:從右至左=+= -=

30、*= /= %=&= A =從左至右|= <<=>> =表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<<8)|lowif (a|b)&&(a&c)4.2 復(fù)合表達(dá)式如a=b=c=0這樣的表達(dá)式稱為復(fù)合表達(dá)式。允許復(fù)合表達(dá)式存在的理由是: (1)書寫簡(jiǎn)潔;(2)可以提高編譯效率。但要防止濫用復(fù)合表達(dá)式?!疽?guī)則4-2-1 不

31、要編寫太復(fù)雜的復(fù)合表達(dá)式。例如: i=a>=b&&c<d&&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(a<b<c)/a<b<c是數(shù)學(xué)表達(dá)式而不是程序表達(dá)式并不表示if (a<b)&&(b<c)而是成了令人費(fèi)解的if(a<b)<c)4.3if

32、語(yǔ)句if語(yǔ)句是C吾言中最簡(jiǎn)單、最常用的語(yǔ)句,然而很多程序員用隱含錯(cuò)誤的方式 寫if語(yǔ)句。本節(jié)以“與零值比較”為例,展開(kāi)討論。4.3.1 布爾變量與零值比較【規(guī)則4-3-1不可將布爾變量直接與 TRUE FALSER者1、0進(jìn)行比較。根據(jù)布爾類型的語(yǔ)義,零值為“假”(記為FALSE),任何非零值都是“真”(記為TRUE 。 TRUE勺值究竟是什么并沒(méi)有統(tǒng)一的標(biāo)準(zhǔn)。例如 VisualC+將TRUE1義為1, 而 VisualBasic 則將 TRUE1 義為-1。假設(shè)布爾變量名字為flag ,它與零值比較的標(biāo)準(zhǔn)if語(yǔ)句如下:if (flag)/ 表示 flag 為真if (mag)/表示flag為

33、假其它的用法都屬于不良風(fēng)格,例如:if(flag=TRUE)if(flag=1)if(flag=FALSE)if(flag=0)4.3.2 整型變量與零值比較【規(guī)則4-3-2】應(yīng)當(dāng)將整型變量用“="或“!=”直接與0比較。假設(shè)整 型變量的名字為value ,它與零值比較的標(biāo)準(zhǔn)if語(yǔ)句如下:if(value=0)if(value!=0)不可模仿布爾變量的風(fēng)格而寫成if(value)/會(huì)讓人誤解value是布爾變量if(!value)4.3.3 浮點(diǎn)變量與零值比較【規(guī)則4-3-3不可將浮點(diǎn)變量用“二="或"!= ”與任何數(shù)字比較。千萬(wàn)要留意,無(wú)論是float還是dou

34、ble類型的變量,都有精度限制。所以一定要避免將浮點(diǎn) 變量用“="或"!=”與數(shù)字比較,應(yīng)該設(shè)法轉(zhuǎn)化成“>="或“ <=”形式。假設(shè)浮點(diǎn)變量的名字為 x,應(yīng)當(dāng)將if(x=0.0)/隱含錯(cuò)誤的比較轉(zhuǎn)化為if(x>=-EPSINON)&&(x<=EPSINON)其中EPSINO睡允許的誤差(即精度)。4.3.4 指針變量與零值比較【規(guī)則4-3-4應(yīng)當(dāng)將指針變量用“="或"!=”與NUL比較。指針變量的零值是“空”(記為 NULL 。盡管NULL勺值與0相同,但是兩者意義不同。假設(shè) 指針變量的名字為p,它與零值

35、比較的標(biāo)準(zhǔn)if語(yǔ)句如下:if(p=NULL)p與NULL1式比較,強(qiáng)調(diào)p是指針變量if(p!=NULL)不要寫成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)誤寫成if(p=NULL),而有意把p和NUL顛倒。編譯器認(rèn)為if(p=NULL) 是合法的,但是會(huì)指出if(NULL=p)是錯(cuò)誤的,因?yàn)镹UL卬能被賦值。程序中有時(shí)會(huì)遇到if/else/return 的組合,應(yīng)該將如下不良風(fēng)格的程序

36、if(condition)returnx;returny;改寫為if(condition)returnx;else returny;或者改寫成更加簡(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ù)雜性?!窘ㄗh4-4-1 在多重循環(huán)中,如果有可能,應(yīng)當(dāng)將最長(zhǎng)的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層,以減少CPUT切循環(huán)層的次數(shù)。例如示例 4-4(b)的效率比示例4-4(a)的高。 for (row=0; row<100; row+)

37、for (col=0; col<5; col+)fum = sum+arowcol;示例4-4(a)低效率:長(zhǎng)循環(huán)在最外層for (col=0; col<5; col+)for (row=0; row<100; row+)fum = sum+arowcol;示例4-4(b)高效率:長(zhǎng)循環(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次邏輯判斷。并且由于前者老要進(jìn)行 邏輯判斷,打斷了循環(huán)“流水線”作業(yè),使得編譯器不能對(duì)循環(huán)進(jìn)行優(yōu)化處理,降低了效率。如果常大,最女?采用示

38、例4-4(d)的寫法,可以提高效率。如果Nt常小,兩者效率差別并不明顯,采用示例4-4(c)的寫法比較好,因?yàn)槌绦蚋雍?jiǎn)潔。for (i=0; i<N; i+)if (conditionDoSomething();elseDoOtherthing();表4-4(c)效率低但程序簡(jiǎn)潔if(condition)for(i=0;i<N;i+)DoSomething();elsefor(i=0;i<N;i+)DoOtherthing();表4-4(d)效率高但程序不簡(jiǎn)潔4.5 for語(yǔ)句的循環(huán)控制變量【規(guī)則4-5-1 不可在for循環(huán)體內(nèi)修改循環(huán)變量,防止 for循環(huán)失去控制?!窘ㄗh

39、4-5-1】建議for語(yǔ)句的循環(huán)控制變量的取值采用“半開(kāi)半閉區(qū)間”寫法。示例4-5(a)中的x值屬于半開(kāi)半閉區(qū)間" 0=<x<N",起點(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)的寫法更加直觀,盡管兩者的功能是相同的。for(intx=0;x<N;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ǔ)句swi

40、tch是多分支選擇語(yǔ)句,而if語(yǔ)句只有兩個(gè)分支可供選擇。雖然可以用嵌套的if語(yǔ)句來(lái)實(shí)現(xiàn)多分支選擇,但那樣的程序冗長(zhǎng)難讀。這是 switch語(yǔ)句存在的理由。switch語(yǔ)句的基本格式是:switch(variable) case valuel: break; case value2: break; default:break; 【規(guī)則4-6-1 每個(gè)case語(yǔ)句的結(jié)尾不要忘了加 break ,否則將導(dǎo)致多個(gè)分支重疊(除 非有意使多個(gè)分支重疊)。【規(guī)則4-6-2 不要忘記最后那個(gè) default分支。即使程序真的不需要default處理,也應(yīng)該保留語(yǔ)句default:break;這樣做并非多此一舉

41、,而是為了防止別人誤以為你忘了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é)此類錯(cuò)誤,每用一次goto語(yǔ)句都可能留下隱患。很多人建議廢除C白goto語(yǔ)句,以絕后患。但實(shí)事求是地說(shuō),錯(cuò)誤是程序員自己造成的, 不是goto的過(guò)錯(cuò)。goto語(yǔ)句

42、至少有一處可顯神通,它能從多重循環(huán)體中咻地一下子跳到外 面,用不著寫很多次的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為什么需要常量如果不使用常量,直接在程序中填寫數(shù)字或字符串,將會(huì)有什么麻煩?(1)程序的可讀性(可理解性)變差。程序員自己會(huì)忘記那些數(shù)字或字符串是什么意思,用 戶則更加不

43、知它們從何處來(lái)、表示什么。(2)在程序的很多地方輸入同樣的數(shù)字或字符串,難保不發(fā)生書寫錯(cuò)誤。(3)如果要修改數(shù)字或字符串,則會(huì)在很多地方改動(dòng),既麻煩又容易出錯(cuò)?!疽?guī)則5-1-1盡量使用含義直觀的常量來(lái)表示那些將在程序中多次出現(xiàn)的數(shù)字或字符 串。例如:#defineMAX 100/*C語(yǔ)言的宏常量*/constintMAX=100;/ C+ 語(yǔ)言的 const 常量constfloat PI=3.14159;/C+言的 const 常量5.2const與#3初3的比較C+鐳言可以用const來(lái)定義常量,也可以用 #define來(lái)定義常量。但是前者比后者有更多的優(yōu)八、(1) const常量有數(shù)據(jù)類

44、型,而宏常量沒(méi)有數(shù)據(jù)類型。編譯器可以對(duì)前者進(jìn)行類型安全檢 查。而對(duì)后者只進(jìn)行字符替換,沒(méi)有類型安全檢查,并且在字符替換可能會(huì)產(chǎn)生意 料不到的錯(cuò)誤(邊際效應(yīng))。(2)有些集成化的調(diào)試工具可以對(duì)const常量進(jìn)行調(diào)試,但是不能對(duì)宏常量進(jìn)行調(diào)試。【規(guī)則5-2-1 在C+理序中只使用const常量而不使用宏常量,即 const常量完全取代宏常 量。5.3常量定義規(guī)則【規(guī)則5-3-1】需要對(duì)外公開(kāi)的常量放在頭文件中,不需要對(duì)外公開(kāi)的常量放在定義文件的 頭部。為便于管理,可以把不同模塊的常量集中存放在一個(gè)公共的頭文件中?!疽?guī)則5-3-2如果某一常量與其它常量密切相關(guān),應(yīng)在定義中包含這種關(guān)系,而不應(yīng)給出一些

45、孤立的值。例如:const floatRADIUS=100;const floatDIAMETER=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é)者常常迷惑

46、不解,容易引起混亂,請(qǐng)先閱讀 6.6節(jié)“引用與指針的比較”。6.1參數(shù)的規(guī)則【規(guī)則6-1-1參數(shù)的書寫要完整,不要貪圖省事只寫參數(shù)的類型而省略參數(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)格【規(guī)則6-1-2】參數(shù)命名要恰當(dāng),順序要合理。例如編寫字符串拷貝函數(shù)StringCopy ,它有兩個(gè)參數(shù)。如果把參數(shù)名字起為str1和str2 ,例如vo

47、id 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ì)不假思索地寫

48、成如下形式:char str20;StringCopy(str, "HelloWorld "力 / 參數(shù)順序顛倒【規(guī)則6-1-3如果參數(shù)是指針,且僅作輸入用,則應(yīng)在類型前加const ,以防止該指針在函數(shù)體內(nèi)被意外修改。例如:void StringCopy(char *strDestination, const char *strSource);【規(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ù)太多

49、,在使用時(shí)容易將參數(shù)類型或順序搞錯(cuò)?!窘ㄗh6-1-2 盡量不要使用類型和數(shù)目不確定的參數(shù)。C標(biāo)準(zhǔn)庫(kù)函數(shù)printf是采用不確定參數(shù)的典型代表,其原型為:int printf(const chat *format,argument);這種風(fēng)格的函數(shù)在編譯時(shí)喪失了嚴(yán)格的類型安全檢查。6.2返回值的規(guī)則【規(guī)則6-2-1 不要省略返回值的類型。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)聲明

50、為void類型。【規(guī)則6-2-2 函數(shù)名字與返回值類型在語(yǔ)義上不可沖突。違反這條規(guī)則的典型代表是 C標(biāo)準(zhǔn)庫(kù)函數(shù)getchar。例如:charc;c=getchar();if(c=EOF)按照getchar名字的意思,將變量 c聲明為char類型是很自然的事情。但不幸的是 getchar的確不是char類型,而是int類型,其原型如下:int getchar(void);由于c是char類型,取值范圍是-128 , 127,如果宏EOF勺值在char的取值范圍之外, 那么if語(yǔ)句將總是失敗,這種“危險(xiǎn)”人們一般哪里料得到!導(dǎo)致本例錯(cuò)誤的責(zé)任并不在用 戶,是函數(shù)getchar誤導(dǎo)了使用者。【規(guī)則6

51、-2-3 不要將正常值和錯(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)志 EOE為了區(qū)別于正常白字符,只好將EO隨義為負(fù)數(shù)(通常為負(fù)1)。因此函數(shù)getchar就成了 int類型。我們?cè)趯?shí)際工作中,經(jīng)常會(huì)碰到上述令人為難的問(wèn)題。為了避免出現(xiàn)誤解,我們應(yīng)該將正常值和錯(cuò)誤標(biāo)志分開(kāi)。即:正常值用輸出參數(shù)獲得,而錯(cuò)誤標(biāo)志用return語(yǔ)句返回。函數(shù) getch

52、ar 可以改寫成 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;int l

53、ength=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ù)friend String operate+(const String &s1,const String &s2);private:cha

54、r*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拷貝到保存返回值

55、的外部存儲(chǔ)單元之 中,增加了不必要的開(kāi)銷,降低了賦值函數(shù)的效率。例如:Stringa,b,c;a=b;/如果用“值傳遞”,將產(chǎn)生一次*thi拷貝a=b=c;/如果用“值傳遞”,將產(chǎn)生兩次舞川拷貝String的相加函數(shù)operate+的實(shí)現(xiàn)如下:String operate+(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)用“彳1傳遞”的方式返回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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論