C語言編碼規(guī)范_第1頁
C語言編碼規(guī)范_第2頁
C語言編碼規(guī)范_第3頁
C語言編碼規(guī)范_第4頁
C語言編碼規(guī)范_第5頁
已閱讀5頁,還剩20頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、C語言編程規(guī)范對于程序員來說,能工作的代碼并不等于“好”的代碼。“好”代碼的指標(biāo)很多,包括易讀、易維護(hù)、易移植和可靠等。其中,可靠性對嵌入式系統(tǒng)非常重要,尤其是在那些對安全性要求很高的系統(tǒng)中,如飛行器、汽車和工業(yè)控制中。這些系統(tǒng)的特點(diǎn)是:只要工作稍有偏差,就有可能造成重大損失或者人員傷亡。一個不容易出錯的系統(tǒng),除了要有很好的硬件設(shè)計(如電磁兼容性),還要有很健壯或者說“安全”的程序。然而,很少有程序員知道什么樣的程序是安全的程序。很多程序只是表面上可以干活,還存在著大量的隱患。當(dāng)然,這其中也有C語言自身的原因。因?yàn)镃語言是一門難以掌握的語言,其靈活的編程方式和語法規(guī)則對于一個新手來說很可能會成

2、為機(jī)關(guān)重重的陷阱。同時,C語言的定義還并不完全,即使是國際通用的C語言標(biāo)準(zhǔn),也還存在著很多未完全定義的地方。要求所有的嵌入式程序員都成為C語言專家,避開所有可能帶來危險的編程方式,是不現(xiàn)實(shí)的。最好的方法是有一個針對安全性的C語言編程規(guī)范,告訴程序員該如何做。本規(guī)范在制定過程中,主要參考了業(yè)界比較推崇的華為軟件編程規(guī)范和范例和MISRA 2004規(guī)則,適合C語言初學(xué)者使用,目的在于在教學(xué)中培養(yǎng)學(xué)生良好的編程規(guī)范和意識、素質(zhì),促進(jìn)所設(shè)計程序安全、健壯、可靠、可讀與可維護(hù)(程序簡單、清晰)??紤]到面向的是初學(xué)者,為便于教學(xué)和課程考核操作,本規(guī)范中的要求比較基本。事實(shí)上,很多公司都有自己規(guī)定的代碼風(fēng)格

3、,包括命名規(guī)則、縮進(jìn)規(guī)則等,學(xué)生參加工作后,應(yīng)再進(jìn)一步學(xué)習(xí)和應(yīng)用公司的規(guī)范。建議學(xué)生在學(xué)習(xí)本規(guī)范的同時,花點(diǎn)時間閱讀本規(guī)范的參考文獻(xiàn)原文,特別是熟讀本規(guī)范的參考文獻(xiàn)之一的“安全第一”的C語言編程規(guī)范,深刻理解編程規(guī)范與程序安全、健壯、可靠、可讀、可維護(hù)間的關(guān)系和作用,在學(xué)習(xí)和工作中養(yǎng)成良好的編程風(fēng)格。1 排版1.1 嚴(yán)格采用階梯層次組織程序代碼函數(shù)或過程的開始、結(jié)構(gòu)的定義及循環(huán)、判斷等語句中的代碼都要采用縮進(jìn)風(fēng)格,case 語句下的情況處理語句也要遵從語句縮進(jìn)要求。程序塊的分界符(如C/C+ 語言的大括號 和)應(yīng)各獨(dú)占一行并且位于同一列,同時與引用它們的語句左對齊。在函數(shù)體的開始、類的定義、結(jié)

4、構(gòu)的定義、枚舉的定義以及if 、for 、do 、while 、switch 、case 語句中的程序都要采用如上的縮進(jìn)方式。各層次縮進(jìn)的風(fēng)格采用TAB縮進(jìn)(TAB寬度原則上使用系統(tǒng)默認(rèn)值,TC使用8空格寬度,VC使用4空格寬度)。示例:if (x is true)we do yelseif (a > b).else.和:if (x = y).else if (x > y).else.注意,右括號所在的行不應(yīng)當(dāng)有其它東西,除非跟隨著一個條件判斷。也就是do-while語句中的“while”,象這樣:dobody of do-loop while (condition);說明:代碼離

5、不開縮進(jìn),縮進(jìn)背后的思想是:清楚地定義一個控制塊從哪里開始,到哪里結(jié)束。尤其是在你連續(xù)不斷的盯了20個小時的屏幕后,如果你有大尺寸的縮進(jìn)。你將更容易發(fā)現(xiàn)縮進(jìn)的好處。關(guān)于縮進(jìn)主要有兩個爭論,一個是該用空格(Space)還是用制表符(Tab),另外一個是該用4格縮進(jìn)還是8格縮進(jìn)甚至都不是。建議總是使用Tab縮進(jìn),因?yàn)閹缀跛械拇a(不僅僅是C代碼)都在使用Tab縮進(jìn)。現(xiàn)在,有些人說8個字符大小的縮進(jìn)導(dǎo)致代碼太偏右了,并且在一個80字符寬的終端屏幕上看著很不舒服。對這個問題的回答是:如果你有超過3個級別的縮進(jìn),你就有點(diǎn)犯糊涂了,應(yīng)當(dāng)修改你的程序。簡而言之,8個字符的縮進(jìn)使程序更易讀,而且當(dāng)你把功能隱

6、藏的太深時,多層次的縮進(jìn)還會對此很直觀的給出警告。要留心這種警告信息。例外:對于由開發(fā)工具自動生成的代碼可以有不一致。1.2 及時折行較長的語句(>80 字符)要分成多行書寫,長表達(dá)式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首,劃分出的新行要進(jìn)行適當(dāng)?shù)目s進(jìn)(至少1個TAB位置),使排版整齊,語句可讀。示例:report_or_not_flag = (taskno < MAX_ACT_TASK_NUMBER)&& (n7stat_stat_item_valid (stat_item)&& (act_task_tabletaskno.result_

7、data != 0);循環(huán)、判斷等語句中若有較長的表達(dá)式或語句,則要進(jìn)行適應(yīng)的劃分,長表達(dá)式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首。示例:if (taskno < max_act_task_number)&& (n7stat_stat_item_valid (stat_item). / program codefor (i = 0, j = 0; (i < BufferKeywordword_index.word_length)&& (j < NewKeyword.word_length); i+, j+). / program co

8、defor (i = 0, j = 0;(i < first_word_length) && (j < second_word_length);i+, j+). / program code若函數(shù)或過程中的參數(shù)較長,則要進(jìn)行適當(dāng)?shù)膭澐?。示例:n7stat_str_compare(BYTE *) & stat_object, (BYTE *) & (act_task_tabletaskno.stat_object),sizeof (_STAT_OBJECT);n7stat_flash_act_duration( stat_item, frame_id

9、*STAT_TASK_CHECK_NUMBER+ index, stat_object );1.3 一行只寫一條語句不允許把多個短語句寫在一行中,即一行只寫一條語句。示例,如下例子不符合規(guī)范:rect.length = 0; rect.width = 0;應(yīng)如下書寫rect.length = 0;rect.width = 0;1.4 if、for、do、while等語句格式規(guī)定if 、for 、do 、while 、case 、switch 、default 等語句自占一行,且if 、for 、do 、while 等語句的執(zhí)行語句部分無論多少都要加花括號。1.5 空行(1)變量說明之后必須加空

10、行。(2)相對獨(dú)立的程序塊之間應(yīng)加空行。1.6 空格在兩個以上的關(guān)鍵字、變量、常量進(jìn)行對等操作時,它們之間的操作符之前、之后或者前后要加空格;進(jìn)行非對等操作時,如果是關(guān)系密切的立即操作符(如> ),后不應(yīng)加空格。采用這種松散方式編寫代碼的目的是使代碼更加清晰。由于留空格所產(chǎn)生的清晰性是相對的,所以,在已經(jīng)非常清晰的語句中沒有必要再留空格,如果語句已足夠清晰則括號內(nèi)側(cè)(即左括號后面和右括號前面)不需要加空格,多重括號間不必加空格,因?yàn)樵贑/C+語言中括號已經(jīng)是最清晰的標(biāo)志了。在長語句中,如果需要加的空格非常多,那么應(yīng)該保持整體清晰,而在局部不加空格。給操作符留空格時不要連續(xù)留兩個以上空格。

11、(1)逗號、分號只在后面加空格。int a, b, c;(2)比較操作符, 賦值操作符"="、 "+=",算術(shù)操作符"+"、"%",邏輯操作符"&&"、"&",位域操作符"<<"、""等雙目操作符的前后加空格。if (current_time >= MAX_TIME_VALUE)a = b + c;a *= 2;a = b 2;(3)"!"、""、&quo

12、t;+"、"-"、"&"(地址運(yùn)算符)等單目操作符前后不加空格。*p = 'a' / 內(nèi)容操作"*"與內(nèi)容之間flag = !isEmpty; / 非操作"!"與內(nèi)容之間p = &mem; / 地址操作"&" 與內(nèi)容之間i+; / "+","-"與內(nèi)容之間(4)"->"、"."前后不加空格。p->id = pid; / "->"指

13、針前后不加空格(5) if、for、while、switch等與后面的括號間應(yīng)加空格,使if等關(guān)鍵字更為突出、明顯。if (a >= b && c > d)1.7 對變量的定義,盡量位于函數(shù)的開始位置(1)應(yīng)避免分散定義變量。(2)同一行內(nèi)不要定義過多變量。 (3)同一類的變量在同一行內(nèi)定義,或者在相鄰行定義。 (4)數(shù)組、指針等復(fù)雜類型的定義放在定義區(qū)的最后。 (5)變量定義區(qū)不做較復(fù)雜的變量賦值。1.8 程序各部分的放置順序在較小的項(xiàng)目中,按如下順序組織安排程序各部分:(1)#include <C的標(biāo)準(zhǔn)頭文件>。(2)#include 用戶自定義的文

14、件。(3)#define 宏定義。(4)全局變量定義。(5)函數(shù)原型聲明。(6)main函數(shù)定義。(7)用戶自定義函數(shù)。以上各部分之間、用戶自定義的函數(shù)之間應(yīng)加空行。注意,函數(shù)原型聲明統(tǒng)一集中放在main函數(shù)之前,不放在某個函數(shù)內(nèi)部。2 注釋2.1 注釋的原則和目的注釋的原則是有助于對程序的閱讀理解,在該加的地方都加了,注釋不宜太多也不能太少,注釋語言必須準(zhǔn)確、易懂、簡潔。通過對函數(shù)或過程、變量、結(jié)構(gòu)等正確的命名以及合理地組織代碼的結(jié)構(gòu),使代碼成為自注釋的清晰準(zhǔn)確的函數(shù)、變量等的命名,可增加代碼可讀性,并減少不必要的注釋過量的注釋則是有害的。注釋的目的是解釋代碼的目的、功能和采用的方法,提供代

15、碼以外的信息,幫助讀者理解代碼,防止沒必要的重復(fù)注釋信息。 示例:如下注釋意義不大。/* if receive_flag is TRUE */if (receive_flag)而如下的注釋則給出了額外有用的信息。/* if mtp receive a message from links */if (receive_flag)2.2 函數(shù)頭部應(yīng)進(jìn)行注釋函數(shù)頭部應(yīng)進(jìn)行注釋,列出:函數(shù)的目的/ 功能、輸入?yún)?shù)、輸出參數(shù)、返回值、調(diào)用關(guān)系(函數(shù)、表)等。示例1:下面這段函數(shù)的注釋比較標(biāo)準(zhǔn),當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。/* Function: / 函數(shù)名稱 Description

16、: / 函數(shù)功能、性能等的描述 Calls: / 被本函數(shù)調(diào)用的函數(shù)清單 Called By: / 調(diào)用本函數(shù)的函數(shù)清單 Input: / 輸入?yún)?shù)說明,包括每個參數(shù)的作 / 用、取值說明及參數(shù)間關(guān)系。 Output: / 對輸出參數(shù)的說明。 Return: / 函數(shù)返回值的說明 Others: / 其它說明*/對于某些函數(shù),其部分參數(shù)為傳入值,而部分參數(shù)為傳出值,所以對參數(shù)要詳細(xì)說明該參數(shù)是入口參數(shù),還是出口參數(shù),對于某些意義不明確的參數(shù)還要做詳細(xì)說明(例如:以角度作為參數(shù)時,要說明該角度參數(shù)是以弧度(PI),還是以度為單位),對既是入口又是出口的變量應(yīng)該在入口和出口處同時標(biāo)明。等等。在注釋

17、中詳細(xì)注明函數(shù)的適當(dāng)調(diào)用方法,對于返回值的處理方法等。在注釋中要強(qiáng)調(diào)調(diào)用時的危險方面,可能出錯的地方。2.3 進(jìn)行注釋時的注意事項(xiàng)(1)建議邊寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋,以保證注釋與代碼的一致性。不再有用的注釋要刪除。(2)注釋的內(nèi)容要清楚、明了,含義準(zhǔn)確,防止注釋二義性。說明:錯誤的注釋不但無益反而有害。(3)避免在注釋中使用縮寫,特別是非常用縮寫。在使用縮寫時或之前,應(yīng)對縮寫進(jìn)行必要的說明。(4)注釋應(yīng)與其描述的代碼相近,對代碼的注釋應(yīng)放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面。除非必要,不應(yīng)在代碼或表達(dá)中間插入注釋,否則容易使代碼可理解性變差。示例:如下例子

18、不符合規(guī)范。例1:/* get replicate sub system index and net indicator */repssn_ind = ssn_dataindex.repssn_index;repssn_ni = ssn_dataindex.ni;例2:repssn_ind = ssn_dataindex.repssn_index;repssn_ni = ssn_dataindex.ni;/* get replicate sub system index and net indicator */應(yīng)如下書寫/* get replicate sub system index and

19、 net indicator */repssn_ind = ssn_dataindex.repssn_index;repssn_ni = ssn_dataindex.ni;(5)對于所有有物理含義的變量、常量,如果其命名不是充分自注釋的,在聲明時都必須加以注釋,說明其物理含義。變量、常量、宏的注釋應(yīng)放在其上方相鄰位置或右方。示例:/* active statistic task number */#define MAX_ACT_TASK_NUMBER 1000#define MAX_ACT_TASK_NUMBER 1000 /* active statistic task number */(

20、6)數(shù)據(jù)結(jié)構(gòu)聲明( 包括數(shù)組、結(jié)構(gòu)、類、枚舉等) ,如果其命名不是充分自注釋的,必須加以注釋。對數(shù)據(jù)結(jié)構(gòu)的注釋應(yīng)放在其上方相鄰位置,不可放在下面;對結(jié)構(gòu)中的每個域的注釋放在此域的右方。示例:可按如下形式說明枚舉/數(shù)據(jù)/聯(lián)合結(jié)構(gòu)。/* sccp interface with sccp user primitive message name */enum SCCP_USER_PRIMITIVEN_UNITDATA_IND, /* sccp notify sccp user unit data come */N_NOTICE_IND, /* sccp notify user the No.7 net

21、work can not */* transmission this message */N_UNITDATA_REQ, /* sccp user's unit data transmission request*/;(7)全局變量要有較詳細(xì)的注釋,包括對其功能、取值范圍、哪些函數(shù)或過程存取它以及存取時注意事項(xiàng)等的說明。示例:/* The ErrorCode when SCCP translate */* Global Title failure, as follows */ / 變量作用、含義/* 0 SUCCESS 1 GT Table error */* 2 GT error O

22、thers no use */ / 變量取值范圍/* only function SCCPTranslate() in */* this modual can modify it, and other */* module can visit it through call */* the function GetGTTransErrorCode() */ / 使用方法BYTE g_GTTranErrorCode;(8)注釋與所描述內(nèi)容進(jìn)行同樣的縮排,讓程序排版整齊,并方便注釋的閱讀與理解。示例:如下例子,排版不整齊,閱讀稍感不方便。void example_fun( void )/* cod

23、e one comments */CodeBlock One/* code two comments */ CodeBlock Two應(yīng)改為如下布局。void example_fun( void )/* code one comments */CodeBlock One/* code two comments */CodeBlock Two(9)將注釋與其上面的代碼用空行隔開。示例:如下例子,顯得代碼過于緊湊。/* code one comments */program code one/* code two comments */program code two應(yīng)如下書寫/* code on

24、e comments */program code one/* code two comments */program code two(10)對變量的定義和分支語句(條件分支、循環(huán)語句等)必須編寫注釋。這些語句往往是程序?qū)崿F(xiàn)某一特定功能的關(guān)鍵,對于維護(hù)人員來說,良好的注釋幫助更好的理解程序,有時甚至優(yōu)于看設(shè)計文檔。(11)對于switch 語句下的case 語句,如果因?yàn)樘厥馇闆r需要處理完一個case 后進(jìn)入下一個case 處理(即上一個case后無break),必須在該case 語句處理完、下一個case 語句前加上明確的注釋,以清楚表達(dá)程序編寫者的意圖,有效防止無故遺漏break語句(可

25、避免后期維護(hù)人員對此感到迷惑:原程序員是遺漏了break語句還是本來就不應(yīng)該有)。示例:case CMD_DOWN:ProcessDown();break;case CMD_FWD:ProcessFwd();if (.).break; elseProcessCFW_B(); / now jump into case CMD_Acase CMD_A:ProcessA();break;.(12)在程序塊的結(jié)束行右方加注釋標(biāo)記,以表明某程序塊的結(jié)束。當(dāng)代碼段較長,特別是多重嵌套時,這樣做可以使代碼更清晰,更便于閱讀。示例:參見如下例子。if (.)program codewhile (index &

26、lt; MAX_INDEX)program code /* end of while (index < MAX_INDEX) */ / 指明該條while語句結(jié)束 /* end of if (.)*/ / 指明是哪條if語句結(jié)束(13)在順序執(zhí)行的程序中,每隔35行語句,應(yīng)當(dāng)加一個注釋,注明這一段語句所組成的小模塊的作用。對于自己的一些比較獨(dú)特的思想要求在注釋中標(biāo)明。(14)注釋格式盡量統(tǒng)一,建議使用“/* */”。(15)注釋應(yīng)考慮程序易讀及外觀排版的因素,使用的語言若是中、英兼有的,建議多使用中文,除非能用非常流利準(zhǔn)確的英文表達(dá)注釋語言不統(tǒng)一,影響程序易讀性和外觀排版,出于對維護(hù)人員

27、的考慮,建議使用中文。3 命名規(guī)則C是一門樸素的語言,你使用的命名也應(yīng)該這樣。與Modula-2和Pascal程序員不同,C程序員不使用諸如“ThisVariableIsATemporaryCounter”這樣“聰明”的名字。C程序員應(yīng)該叫它“tmp”,這寫起來更簡單,也不會更難懂。然而,當(dāng)面對復(fù)雜情況時就有些棘手,給全局變量取一個描述性的名字是必要的。把一個全局函數(shù)叫做“foo”是一種目光短淺的行為。全局函數(shù)也一樣,如果你有一個統(tǒng)計當(dāng)前用戶個數(shù)的函數(shù),應(yīng)當(dāng)把它命名為“count_active_user()”或者簡單點(diǎn)些的類似名稱,不應(yīng)該命名為“cntusr()”。3.1 三種流行的命名法則目

28、前,業(yè)界共有四種命名法則:駝峰命名法、匈牙利命名法、帕斯卡命名法和下劃線命名法,其中前三種是較為流行的命名法。(1)駝峰命令法。正如它的名稱所表示的那樣,是指混合使用大小寫字母來構(gòu)成變量和函數(shù)的名字。例如,下面是分別用駱駝式命名法和下劃線法命名的同一個函數(shù):printEmployeePaychecks();print_employee_paychecks();第一個函數(shù)名使用了駝峰命名法,函數(shù)名中的每一個邏輯斷點(diǎn)都有一個大寫字母來標(biāo)記。第二個函數(shù)名使用了下劃線法,函數(shù)名中的每一個邏輯斷點(diǎn)都有一個下劃線來標(biāo)記。駝峰命名法近年來越來越流行了,在許多新的函數(shù)庫和Microsoft Windows這樣

29、的環(huán)境中,它使用得當(dāng)相多。另一方面,下劃線法是C出現(xiàn)后開始流行起來的,在許多舊的程序和UNIX這樣的環(huán)境中,它的使用非常普遍。(2)匈牙利命名法。廣泛應(yīng)用于象Microsoft Windows這樣的環(huán)境中。Windows 編程中用到的變量(還包括宏)的命名規(guī)則為匈牙利命名法,這種命名技術(shù)是由一位能干的 Microsoft 程序員查爾斯-西蒙尼(Charles Simonyi) 提出的。匈牙利命名法通過在變量名前面加上相應(yīng)的小寫字母的符號標(biāo)識作為前綴,標(biāo)識出變量的作用域、類型等。這些符號可以多個同時使用,順序是先m_(成員變量)、再指針、再簡單數(shù)據(jù)類型、再其它。這樣做的好處在于能增加程序的可讀性

30、,便于對程序的理解和維護(hù)。例如:m_lpszStr, 表示指向一個以0字符結(jié)尾的字符串的長指針成員變量。匈牙利命名法關(guān)鍵是:標(biāo)識符的名字以一個或者多個小寫字母開頭作為前綴;前綴之后的是首字母大寫的一個單詞或多個單詞組合,該單詞要指明變量的用途。(3)帕斯卡(pascal)命名法。與駝峰命名法類似,二者的區(qū)別在于:駝峰命名法是首字母小寫,而帕斯卡命名法是首字母大寫,如:DisplayInfo();string UserName;二者都是采用了帕斯卡命名法。 (4)三種命名規(guī)則的小結(jié):MyData就是一個帕斯卡命名的示例;myData是一個駝峰命名法,它第一個單詞的第一個字母小寫,后面的單詞首字母

31、大寫,看起來像一個駱駝;iMyData是一個匈牙利命名法,它的小寫的i說明了它的型態(tài),后面的和帕斯卡命名相同,指示了該變量的用途。3.2 命名的基本原則(1)標(biāo)識符的命名要清晰、明了,有明確含義,同時使用完整的單詞或大家基本可以理解的縮寫,避免使人產(chǎn)生誤解盡量采用采用英文單詞或全部中文全拼表示,若出現(xiàn)英文單詞和中文混合定義時,使用連字符“_”將英文與中文割開。較短的單詞可通過去掉“元音”形成縮寫;較長的單詞可取單詞的頭幾個字母形成縮寫;一些單詞有大家公認(rèn)的縮寫。例如:temp->tmp、flag->flg、statistic->stat、increment->inc、m

32、essage->msg等縮寫能夠被大家基本認(rèn)可。(2)命名中若使用特殊約定或縮寫,則要有注釋說明。應(yīng)該在源文件的開始之處,對文件中所使用的縮寫或約定,特別是特殊的縮寫,進(jìn)行必要的注釋說明。(3)自己特有的命名風(fēng)格,要自始至終保持一致,不可來回變化。個人的命名風(fēng)格,在符合所在項(xiàng)目組或產(chǎn)品組的命名規(guī)則的前提下,才可使用。(即命名規(guī)則中沒有規(guī)定到的地方才可有個人命名風(fēng)格)。(4)對于變量命名,禁止取單個字符(如i 、j 、k. ),建議除了要有具體含義外,還能表明其變量類型、數(shù)據(jù)類型等,但i 、j 、k 作局部循環(huán)變量是允許的。變量,尤其是局部變量,如果用單個字符表示,很容易敲錯(如i寫成j)

33、,而編譯時又檢查不出來,有可能為了這個小小的錯誤而花費(fèi)大量的查錯時間。(5)除非必要,不要用數(shù)字或較奇怪的字符來定義標(biāo)識符。(6)命名規(guī)范必須與所使用的系統(tǒng)風(fēng)格保持一致,并在同一項(xiàng)目中統(tǒng)一。(7)在同一軟件產(chǎn)品內(nèi),應(yīng)規(guī)劃好接口部分標(biāo)識符(變量、結(jié)構(gòu)、函數(shù)及常量)的命名,防止編譯、鏈接時產(chǎn)生沖突。對接口部分的標(biāo)識符應(yīng)該有更嚴(yán)格限制,防止沖突。如可規(guī)定接口部分的變量與常量之前加上“模塊”標(biāo)識等。(8)用正確的反義詞組命名具有互斥意義的變量或相反動作的函數(shù)等。下面是一些在軟件中常用的反義詞組。add / remove begin / end create / destroyinsert / dele

34、te first / last g et / releaseincrement / decrement put / getadd / delete lock / unlock open / closemin / max old / new start / stopnext / previous source / target show / hidesend / receive source / destinationcut / paste up / down示例:int min_sum;int max_sum;int add_user( BYTE *user_name );int delete

35、_user( BYTE *user_name );(9)除了編譯開關(guān)/ 頭文件等特殊應(yīng)用,應(yīng)避免使用_EXAMPLE_TEST_ 之類以下劃線開始和結(jié)尾的定義。3.3 變量名的命名規(guī)則(1)變量的命名規(guī)則要求用“匈牙利法則”。即開頭字母用變量的類型,其余部分用變量的英文意思、英文的縮寫、中文全拼或中文全拼的縮寫,要求單詞的第一個字母應(yīng)大寫。即: 變量名=變量類型+變量的英文意思(或英文縮寫、中文全拼、中文全拼縮寫)對非通用的變量,在定義時加入注釋說明,變量定義盡量可能放在函數(shù)的開始處。見下表:bool 用b開頭 bFlgint 用i開頭 iCountshort int 用n開頭 nStepCo

36、untlong int 用l開頭 lSumchar 用c開頭 cCountunsigned char 用by開頭float 用f開頭 fAvgdouble 用d開頭 dDetaunsigned int(WORD) 用w開頭 wCountunsigned long int(DWORD) 用dw開頭 dwBroad字符串 用s開頭 sFileName用0結(jié)尾的字符串 用sz開頭 szFileName(2)指針變量命名的基本原則為:對一重指針變量的基本原則為:“p”+變量類型前綴+命名,如一個float*型應(yīng)該表示為pfStat。對二重指針變量的基本規(guī)則為:“pp”+變量類型前綴+命名。對三重指針變

37、量的基本規(guī)則為:“ppp”+變量類型前綴+命名。(3)全局變量用g_開頭,如一個全局的長型變量定義為g_lFailCount,即:變量名=g_+變量類型+變量的英文意思(或縮寫)。此規(guī)則還可避免局部變量和全局變量同名而引起的問題。(4)靜態(tài)變量用s_開頭,如一個靜態(tài)的指針變量定義為s_plPerv_Inst,即: 變量名=s_+變量類型+變量的英文意思(或縮寫)(5)對枚舉類型(enum)中的變量,要求用枚舉變量或其縮寫做前綴。并且要求用大寫。如:enum cmEMDAYSEMDAYS_MONDAY;EMDAYS_TUESDAY;(6)對struct、union變量的命名要求定義的類型用大寫。

38、并要加上前綴,其內(nèi)部變量的命名規(guī)則與變量命名規(guī)則一致。結(jié)構(gòu)一般用S開頭,如:struct ScmNPointint nX;/點(diǎn)的X位置int nY; /點(diǎn)的Y位置;聯(lián)合體一般用U開頭,如:union UcmLPointLONG lX;LONG lY;(7)對常量(包括錯誤的編碼)命名,要求常量名用大寫,常量名用英文表達(dá)其意思。當(dāng)需要由多個單詞表示時,單詞與單詞之間必須采用連字符“_”連接。如:#define CM_FILE_NOT_FOUND CMMAKEHR(0X20B) 其中CM表示類別。(8)對const 的變量要求在變量的命名規(guī)則前加入c_,即:c_+變量命名規(guī)則;示例:const c

39、har* c_szFileName;3.4 函數(shù)的命名規(guī)范(1)函數(shù)的命名應(yīng)該盡量用英文(或英文縮寫、中文全拼、中文全拼縮寫)表達(dá)出函數(shù)完成的功能函數(shù)名應(yīng)準(zhǔn)確描述函數(shù)的功能。遵循動賓結(jié)構(gòu)的命名法則,函數(shù)名中動詞在前,并在命名前加入函數(shù)的前綴,函數(shù)名的長度不得少于8個字母。函數(shù)名首字大寫,若包含有兩個單詞的每個單詞首字母大寫。如果是OOP 方法,可以只有動詞(名詞是對象本身)。示例:LONG GetDeviceCount();void print_record( unsigned int rec_ind ) ;int input_record( void ) ;unsigned char get

40、_current_color( void ) ;(2)避免使用無意義或含義不清的動詞為函數(shù)命名。如使用process、handle等為函數(shù)命名,因?yàn)檫@些動詞并沒有說明要具體做什么。(3)必須使用函數(shù)原型聲明。函數(shù)原型聲明包括:引用外來函數(shù)及內(nèi)部函數(shù),外部引用必須在右側(cè)注明函數(shù)來源: 模塊名及文件名;內(nèi)部函數(shù),只要注釋其定義文件名和調(diào)用者在同一文件中(簡單程序)時不需要注釋。應(yīng)確保每個函數(shù)聲明中的參數(shù)的名稱、類型和定義中的名稱、類型一致。3.5 函數(shù)參數(shù)命名規(guī)范(1)參數(shù)名稱的命名參照變量命名規(guī)范。(2)為了提高程序的運(yùn)行效率,減少參數(shù)占用的堆棧,傳遞大結(jié)構(gòu)的參數(shù),一律采用指針或引用方式傳遞。(

41、3)為了便于其他程序員識別某個指針參數(shù)是入口參數(shù)還是出口參數(shù),同時便于編譯器檢查錯誤,應(yīng)該在入口參數(shù)前加入const標(biāo)志。如:cmCopyString(const CHAR * c_szSource, CHAR * szDest)3.6 文件名(包括動態(tài)庫、組件、控件、工程文件等)的命名規(guī)范文件名的命名要求表達(dá)出文件的內(nèi)容,要求文件名的長度不得少于5個字母,嚴(yán)禁使用象file1,myfile之類的文件名。4 可讀性4.1 避免使用默認(rèn)的運(yùn)算優(yōu)先級注意運(yùn)算符的優(yōu)先級,并用括號明確表達(dá)式的操作順序,避免使用默認(rèn)優(yōu)先級,可防止閱讀程序時產(chǎn)生誤解,防止因默認(rèn)的優(yōu)先級與設(shè)計思想不符而導(dǎo)致程序出錯。示例:

42、下列語句中的表達(dá)式word = (high << 8) | low (1)if (a | b) && (a & c) (2)if (a | b) < (c & d) (3)如果書寫為:high << 8 | lowa | b && a & ca | b < c & d由于high << 8 | low = ( high << 8) | low,a | b && a & c = (a | b) && (a & c),(1)(2

43、)不會出錯,但語句不易理解;a | b < c & d = a | (b < c) & d,(3)造成了判斷條件出錯。4.2 使用有意義的標(biāo)識,避免直接使用數(shù)字避免使用不易理解的數(shù)字,用有意義的標(biāo)識來替代。涉及物理狀態(tài)或者含有物理意義的常量,不應(yīng)直接使用數(shù)字,必須用有意義的枚舉或宏來代替。示例:如下的程序可讀性差。if (Trunkindex.trunk_state = 0)Trunkindex.trunk_state = 1;. / program code應(yīng)改為如下形式。#define TRUNK_IDLE 0#define TRUNK_BUSY 1if (Tr

44、unkindex.trunk_state = TRUNK_IDLE)Trunkindex.trunk_state = TRUNK_BUSY;. / program code4.3 源程序中關(guān)系較為緊密的代碼應(yīng)盡可能相鄰這樣做的好處是便于程序閱讀和查找。示例:以下代碼布局不太合理。rect.length = 10;char_poi = str;rect.width = 5;若按如下形式書寫,可能更清晰一些。rect.length = 10;rect.width = 5; / 矩形的長與寬關(guān)系較密切,放在一起。char_poi = str;4.4 不要使用難懂的技巧性很高的語句、復(fù)雜的表達(dá)式除非很

45、有必要時,原則上不要使用難懂的技巧性很高的語句和復(fù)雜的表達(dá)式高技巧語句不等于高效率的程序,源程序占用空間的節(jié)約并不等于目標(biāo)程序占用空間的節(jié)約,實(shí)際上程序的效率關(guān)鍵在于算法。(1)如下表達(dá)式,考慮不周就可能出問題,也較難理解。* stat_poi + += 1;* + stat_poi += 1;應(yīng)分別改為如下:*stat_poi += 1;stat_poi+; / 此二語句功能相當(dāng)于“ * stat_poi + += 1; ”+ stat_poi;*stat_poi += 1; / 此二語句功能相當(dāng)于“ * + stat_poi += 1; ”(2)如下表達(dá)式,不同的編譯器給出的結(jié)果不一樣,b

46、i是否先執(zhí)行?x=bi + i+;應(yīng)改為:x = bi + i;i+;5 變量與結(jié)構(gòu)5.1 謹(jǐn)慎使用全局(公共)變量(1)去掉沒必要的公共變量。公共變量是增大模塊間耦合的原因之一,故應(yīng)減少沒必要的公共變量以降低模塊間的耦合度。(2)仔細(xì)定義并明確公共變量的含義、作用、取值范圍及公共變量間的關(guān)系。在對變量聲明的同時,應(yīng)對其含義、作用及取值范圍進(jìn)行注釋說明,同時若有必要還應(yīng)說明與其它變量的關(guān)系。(3)防止局部變量與公共變量同名通過使用較好的命名規(guī)則來消除此問題。5.2 數(shù)據(jù)類型間的轉(zhuǎn)換(1)編程時,要注意數(shù)據(jù)類型的強(qiáng)制轉(zhuǎn)換。當(dāng)進(jìn)行數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)換時,其數(shù)據(jù)的意義、轉(zhuǎn)換后的取值等都有可能發(fā)生變化,而

47、這些細(xì)節(jié)若考慮不周,就很有可能留下隱患。(2)對編譯系統(tǒng)默認(rèn)的數(shù)據(jù)類型轉(zhuǎn)換,也要有充分的認(rèn)識。示例:如下賦值,多數(shù)編譯器不產(chǎn)生告警,但值的含義還是稍有變化。char chr;unsigned short int exam;chr = -1;exam = chr; / 編譯器不產(chǎn)生告警,此時exam為0xFFFF。(3)盡量減少沒有必要的數(shù)據(jù)類型默認(rèn)轉(zhuǎn)換與強(qiáng)制轉(zhuǎn)換。例如,所有的 unsigned類型都應(yīng)該有后綴“U”以明確其類型。(4)合理地設(shè)計數(shù)據(jù)并使用自定義數(shù)據(jù)類型,避免數(shù)據(jù)間進(jìn)行不必要的類型轉(zhuǎn)換。(5)對自定義數(shù)據(jù)類型進(jìn)行恰當(dāng)命名,使它成為自描述性的,以提高代碼可讀性。注意其命名方式在同一

48、產(chǎn)品中的統(tǒng)一,并且保證沒有多重定義。使用自定義類型,可以彌補(bǔ)編程語言提供類型少、信息量不足的缺點(diǎn),并能使程序清晰、簡潔。示例:可參考如下方式聲明自定義數(shù)據(jù)類型。下面的聲明可使數(shù)據(jù)類型的使用簡潔、明了。typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned int DWORD;下面的聲明可使數(shù)據(jù)類型具有更豐富的含義。typedef float DISTANCE;typedef float SCORE;(6)不要用八進(jìn)制數(shù)整型常數(shù)以”0“開始會被認(rèn)為是8進(jìn)制。示例:code1=109code2=100code3

49、=052code4=071如果是對總線消息初始化,會有危險。6 函數(shù)與過程6.1 函數(shù)的功能與規(guī)模設(shè)計(1)函數(shù)應(yīng)當(dāng)短而精美,而且只做一件事。不要設(shè)計多用途面面俱到的函數(shù),多功能集于一身的函數(shù),很可能使函數(shù)的理解、測試、維護(hù)等變得困難。 一個函數(shù)應(yīng)最多占滿1或2個屏幕(就象我們知道的那樣,ISO/ANSI的屏幕大小是80X24),只做一件事并且把它做好。一個函數(shù)的最大長度與它的復(fù)雜度和縮進(jìn)級別成反比。所以,如果如果你有一個概念上簡單(案,“簡單”是simple而不是easy)的函數(shù),它恰恰包含著一個很長的case語句,這樣你不得不為不同的情況準(zhǔn)備不懂的處理,那么這樣的長函數(shù)是沒問題的。然而,如

50、果你有一個復(fù)雜的函數(shù),你猜想一個并非天才的高一學(xué)生可能看不懂得這個函數(shù),你就應(yīng)當(dāng)努力把它減縮得更接近前面提到的最大函數(shù)長度限制。可以使用一些輔助函數(shù),給它們?nèi)∶枋鲂缘拿?如果你認(rèn)為這些輔助函數(shù)的調(diào)用是性能關(guān)鍵的,可以讓編譯器把它們內(nèi)聯(lián)進(jìn)來,這比在單個函數(shù)內(nèi)完成所有的事情通常要好些)。對函數(shù)還存在另一個測量標(biāo)準(zhǔn):局部變量的數(shù)目。這不該超過5到10個,否則你可能會弄錯。應(yīng)當(dāng)重新考慮這個函數(shù),把它分解成小片。人類的大腦一般能同時記住7個不同的東西,超過這個數(shù)目就會犯糊涂?;蛟S你認(rèn)為自己很聰明,那么請你理解一下從現(xiàn)在開始的2周時間你都做什么了。(2)為簡單功能編寫函數(shù)。雖然為僅用一兩行就可完成的功能

51、去編函數(shù)好象沒有必要,但用函數(shù)可使功能明確化,增加程序可讀性,亦可方便維護(hù)、測試。 示例:如下語句的功能不很明顯。value = ( a > b ) ? a : b ;改為如下就很清晰了。int max (int a, int b)return (a > b) ? a : b);value = max (a, b);或改為如下。#define MAX (a, b) (a) > (b) ? (a) : (b)value = MAX (a, b);當(dāng)一個過程(函數(shù))中對較長變量(一般是結(jié)構(gòu)的成員)有較多引用時,可以用一個意義相當(dāng)?shù)暮甏孢@樣可以增加編程效率和程序的可讀性。 示例:

52、在某過程中較多引用TheReceiveBufferFirstSocket.byDataPtr,則可以通過以下宏定義來代替:# define pSOCKDATA TheReceiveBufferFirstScoket.byDataPtr(3)防止把沒有關(guān)聯(lián)的語句放到一個函數(shù)中,防止函數(shù)或過程內(nèi)出現(xiàn)隨機(jī)內(nèi)聚。隨機(jī)內(nèi)聚是指將沒有關(guān)聯(lián)或關(guān)聯(lián)很弱的語句放到同一個函數(shù)或過程中。隨機(jī)內(nèi)聚給函數(shù)或過程的維護(hù)、測試及以后的升級等造成了不便,同時也使函數(shù)或過程的功能不明確。使用隨機(jī)內(nèi)聚函數(shù),常常容易出現(xiàn)在一種應(yīng)用場合需要改進(jìn)此函數(shù),而另一種應(yīng)用場合又不允許這種改進(jìn),從而陷入困境。在編程時,經(jīng)常遇到在不同函數(shù)中使用

53、相同的代碼,許多開發(fā)人員都愿把這些代碼提出來,并構(gòu)成一個新函數(shù)。若這些代碼關(guān)聯(lián)較大并且是完成一個功能的,那么這種構(gòu)造是合理的,否則這種構(gòu)造將產(chǎn)生隨機(jī)內(nèi)聚的函數(shù)。示例:如下函數(shù)就是一種隨機(jī)內(nèi)聚。void Init_Var( void )Rect.length = 0;Rect.width = 0; /* 初始化矩形的長與寬 */Point.x = 10;Point.y = 10; /* 初始化“點(diǎn)”的坐標(biāo) */矩形的長、寬與點(diǎn)的坐標(biāo)基本沒有任何關(guān)系,故以上函數(shù)是隨機(jī)內(nèi)聚。應(yīng)如下分為兩個函數(shù):void Init_Rect( void )Rect.length = 0;Rect.width = 0;

54、 /* 初始化矩形的長與寬 */void Init_Point( void )Point.x = 10;Point.y = 10; /* 初始化“點(diǎn)”的坐標(biāo) */(4)如果多段代碼重復(fù)做同一件事情,那么在函數(shù)的劃分上可能存在問題。若此段代碼各語句之間有實(shí)質(zhì)性關(guān)聯(lián)并且是完成同一件功能的,那么可考慮把此段代碼構(gòu)造成一個新的函數(shù)。(5)減少函數(shù)本身或函數(shù)間的遞歸調(diào)用。遞歸調(diào)用特別是函數(shù)間的遞歸調(diào)用(如A->B->C->A),影響程序的可理解性;遞歸調(diào)用一般都占用較多的系統(tǒng)資源(如棧空間);遞歸調(diào)用對程序的測試有一定影響。故除非為某些算法或功能的實(shí)現(xiàn)方便,應(yīng)減少沒必要的遞歸調(diào)用,對于

55、safe-related 系統(tǒng)不能用遞歸,因?yàn)槌龆褩?臻g很危險。6.2 函數(shù)的返回值(1)對于函數(shù)的返回位置,盡量保持單一性,即一個函數(shù)盡量做到只有一個返回位置。(單入口單出口)。要求大家統(tǒng)一函數(shù)的返回值,所有的函數(shù)的返回值都將以編碼的方式返回。例如編碼定義如下:#define CM_POINT_IS_NULL CMMAKEHR(0X200):建議函數(shù)實(shí)現(xiàn)如下:LONG 函數(shù)名(參數(shù),)LONG lResult; /保持錯誤號lResult=CM_OK;/如果參數(shù)有錯誤則返回錯誤號if(參數(shù)=NULL)lResult=CM_POINT_IS_NULL;goto END;END:return lResult;(2)除非必要,最好不要把與函數(shù)返回值類型不同的變量,以編譯系統(tǒng)默認(rèn)的轉(zhuǎn)換方式或強(qiáng)制的轉(zhuǎn)換方式作為返回值返回。(3)函數(shù)的返回值要清楚、明了,讓使用者不容易忽視錯誤情況。函數(shù)的每種出錯返回值的意義要清晰、明了、準(zhǔn)確,防止

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論