成都信息工程學(xué)院非計算機專業(yè)C語言初學(xué)者編程規(guī)范草案_第1頁
成都信息工程學(xué)院非計算機專業(yè)C語言初學(xué)者編程規(guī)范草案_第2頁
成都信息工程學(xué)院非計算機專業(yè)C語言初學(xué)者編程規(guī)范草案_第3頁
已閱讀5頁,還剩19頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、成都信息工程學(xué)院非計算機專業(yè)C 語言初學(xué)者編程標準 學(xué)生用 成都信息工程學(xué)院計算機根底教學(xué)部 對于程序員來說,能工作的代碼并不等于“好的代碼。 “好代碼的指標很多,包括易 讀、易維護、易移植和可靠等。其中,可靠性對嵌入式系統(tǒng)非常重要,尤其是在那些對平安 性要求很高的系統(tǒng)中,如飛行器、汽車和工業(yè)控制中。這些系統(tǒng)的特點是:只要工作稍有偏 差,就有可能造成重大損失或者人員傷亡。一個不容易出錯的系統(tǒng),除了要有很好的硬件設(shè) 計如電磁兼容性 ,還要有很健壯或者說“平安的程序。然而,很少有程序員知道什么樣的程序是平安的程序。很多程序只是外表上可以干活,還存在著大量的隱患。當(dāng)然,這其中也有 C語言自身的原因。

2、因為C語言是一門難以掌握的 語言,其靈活的編程方式和語法規(guī)那么對于一個新手來說很可能會成為機關(guān)重重的陷阱。 同時, C語言的定義還并不完全,即使是國際通用的C語言標準,也還存在著很多未完全定義的地方。要求所有的嵌入式程序員都成為 C語言專家,避開所有可能帶來危險的編程方式,是不 現(xiàn)實的。最好的方法是有一個針對平安性的 C語言編程標準,告訴程序員該如何做。本標準在制定過程中,主要參考了業(yè)界比擬推崇的?華為軟件編程標準和范例?和? MISRA 2004規(guī)那么?,適合于非計算機專業(yè)的 C語言初學(xué)者使用,目的在于在教學(xué)中培養(yǎng)學(xué)生良 好的編程標準和意識、素質(zhì),促進所設(shè)計程序平安、健壯、可靠、可讀與可維護

3、程序簡單、清晰。考慮到面向的是初學(xué)者,為便于教學(xué)和課程考核操作,本標準中的要求比擬根本。事 實上,很多公司都有自己規(guī)定的代碼風(fēng)格,包括命名規(guī)那么、縮進規(guī)那么等,學(xué)生參加工作后, 應(yīng)再進一步學(xué)習(xí)和應(yīng)用公司的標準。建議學(xué)生在學(xué)習(xí)本標準的同時,花點時間閱讀本標準的參考文獻原文,特別是熟讀本規(guī) 范的參考文獻之一的?“平安第一的C語言編程標準?,深刻理解編程標準與程序平安、健 壯、可靠、可讀、可維護間的關(guān)系和作用,在學(xué)習(xí)和工作中養(yǎng)成良好的編程風(fēng)格。1 排版1.1 嚴格采用階梯層次組織程序代碼 函數(shù)或過程的開始、結(jié)構(gòu)的定義及循環(huán)、判斷等語句中的代碼都要采用縮進風(fēng)格, case 語句下的情況處理語句也要遵從

4、語句縮進要求。程序塊的分界符 如 C/C+ 語言的大括號 ' 和'應(yīng)各獨占一行并且位于同一列, 同時與引用它們的語句左對齊。在函數(shù)體的開始、類的定義、結(jié)構(gòu)的定義、枚舉的定義以及 if 、 for 、 do 、 while 、 switch 、 case 語句中的程序都要采用如上的縮進方式。各層次縮進的風(fēng)格采用TAB縮進(TAB寬度原那么上使用系統(tǒng)默認值,TC使用8空格寬度, VC使用4空格寬度)。例如:if (x is true)we do yelseif (a > b)else和:if (x = y)else if (x > y)else 注意,右括號所在的行不應(yīng)

5、當(dāng)有其它東西,除非跟隨著一個條件判斷。也就是 do-while 語句中的“ while ,象這樣:dobody of do-loop while (condition); 說明:代碼離不開縮進,縮進背后的思想是:清楚地定義一個控制塊從哪里開始,到哪 里結(jié)束。尤其是在你連續(xù)不斷的盯了 20 個小時的屏幕后,如果你有大尺寸的縮進。你將更容 易發(fā)現(xiàn)縮進的好處。關(guān)于縮進主要有兩個爭論,一個是該用空格 (Space)還是用制表符(Tab),另外一個是該 用4格縮進還是8格縮進甚至都不是。建議總是使用Tab縮進,因為幾乎所有的代碼(不僅僅 是C代碼)都在使用Tab縮進。現(xiàn)在,有些人說 8 個字符大小的縮進

6、導(dǎo)致代碼太偏右了, 并且在一個 80 字符寬的終端屏 幕上看著很不舒服。對這個問題的答復(fù)是:如果你有超過 3 個級別的縮進,你就有點犯糊涂 了,應(yīng)當(dāng)修改你的程序。簡而言之, 8 個字符的縮進使程序更易讀,而且當(dāng)你把功能隱藏的 太深時,多層次的縮進還會對此很直觀的給出警告。要留心這種警告信息。例外:對于由開發(fā)工具自動生成的代碼可以有不一致。1.2 及時折行較長的語句 (>80 字符) 要分成多行書寫,長表達式要在低優(yōu)先級操作符處劃分新行,操 作符放在新行之首,劃分出的新行要進行適當(dāng)?shù)目s進(至少1個TAB位置),使排版整齊,語句可讀。例如:report_or_not_flag = (task

7、no < MAX_ACT_TASK_NUMBER)&& (n7stat_stat_item_valid (stat_item)&& (act_task_tabletaskno.result_data != 0);循環(huán)、判斷等語句中假設(shè)有較長的表達式或語句,那么要進行適應(yīng)的劃分,長表達式要在低 優(yōu)先級操作符處劃分新行,操作符放在新行之首。例如:if (taskno < max_act_task_number)&& (n7stat_stat_item_valid (stat_item). / program codefor (i = 0,

8、 j = 0; (i < BufferKeywordword_index.word_length)&& (j < NewKeyword.word_length); i+, j+). / program codefor (i = 0, j = 0;(i < first_word_length) && (j < second_word_length);i+, j+). / program code假設(shè)函數(shù)或過程中的參數(shù)較長,那么要進行適當(dāng)?shù)膭澐帧@纾簄7stat_str_compare(BYTE *) & stat_object,(

9、BYTE *) & (act_task_tabletaskno.stat_object), sizeof (_STAT_OBJECT);n7stat_flash_act_duration( stat_item, frame_id *STAT_TASK_CHECK_NUMBER+ index, stat_object );1.3 一行只寫一條語句不允許把多個短語句寫在一行中,即一行只寫一條語句。例如,如下例子不符合標準:rect.length = 0; rect.width = 0;應(yīng)如下書寫rect.length = 0;rect.width = 0;1.4 if 、 for 、 do

10、、 while 等語句格式規(guī)定if 、 for 、do 、 while 、case 、 switch 、default 等語句自占一行,且 if 、for 、 do 、while 等語句的執(zhí)行語句局部無論多少都要加花括號 。1.5 空行(1) 變量說明之后必須加空行。(2) 相對獨立的程序塊之間應(yīng)加空行。1.6 空格 在兩個以上的關(guān)鍵字、變量、常量進行對等操作時,它們之間的操作符之前、之后或者 前后要加空格;進行非對等操作時,如果是關(guān)系密切的立即操作符 (如> ) ,后不應(yīng)加空格。 采用這種松散方式編寫代碼的目的是使代碼更加清晰。由于留空格所產(chǎn)生的清晰性是相對的,所以,在已經(jīng)非常清晰的語

11、句中沒有必要再留空 格,如果語句已足夠清晰那么括號內(nèi)側(cè) (即左括號后面和右括號前面 ) 不需要加空格,多重括號 間不必加空格,因為在C/C+語言中括號已經(jīng)是最清晰的標志了。在長語句中,如果需要加的空格非常多,那么應(yīng)該保持整體清晰,而在局部不加空格。 給操作符留空格時不要連續(xù)留兩個以上空格。(1) 逗號、分號只在后面加空格 int a, b, c;(2)比擬操作符, 賦值操作符 "="、 "+=" ,算術(shù)操作符"+"、"%",邏輯操作符 "&&"、"&"

12、 ,位域操作符 "<<" 、"A" 等雙目操作符的前后加空格。if (current_time >= MAX_TIME_VALUE) a = b + c;a *= 2;a = b A 2;(3) "!" 、""、"+"、"-" 、"&"( 地址運算符)等單目操作符前后不加空格*p = 'a'/flag = !isEmpty; / p = &mem; / i+;/ "+","-&

13、quot;內(nèi)容操作 "*" 與內(nèi)容之間 非操作 "!" 與內(nèi)容之間 地址操作 "&" 與內(nèi)容之間 與內(nèi)容之間(4) "->" 、"." 前后不加空格p->id = pid; / "->"指針前后不加空格(5) if 、for 、while 、 switch 等與后面的括號間應(yīng)加空格,使 if 等關(guān)鍵字更為突出、 明顯。if (a >= b && c > d)1.7 對變量的定義,盡量位于函數(shù)的開始位置(1) 應(yīng)防止分散定義

14、變量。(2) 同一行內(nèi)不要定義過多變量。(3) 同一類的變量在同一行內(nèi)定義,或者在相鄰行定義。(4) 數(shù)組、指針等復(fù)雜類型的定義放在定義區(qū)的最后。(5) 變量定義區(qū)不做較復(fù)雜的變量賦值。1.8 程序各局部的放置順序在較小的工程中,按如下順序組織安排程序各局部:(1) #include <C 的標準頭文件 >。(2) #include 用戶自定義的文件。(3) #define 宏定義。(4) 全局變量定義。(5) 函數(shù)原型聲明。(6) main 函數(shù)定義。(7) 用戶自定義函數(shù)。以上各局部之間、用戶自定義的函數(shù)之間應(yīng)加空行。注意,函數(shù)原型聲明統(tǒng)一集中放在 main 函數(shù)之前,不放在某

15、個函數(shù)內(nèi)部。2 注釋2.1 注釋的原那么和目的注釋的原那么是有助于對程序的閱讀理解,在該加的地方都加了,注釋不宜太多也不能太 少,注釋語言必須準確、易懂、簡潔。通過對函數(shù)或過程、變量、結(jié)構(gòu)等正確的命名以及合 理地組織代碼的結(jié)構(gòu),使代碼成為自注釋的清晰準確的函數(shù)、變量等的命名,可增加代 碼可讀性,并減少不必要的注釋過量的注釋那么是有害的。注釋的目的是解釋代碼的目的、功能和采用的方法,提供代碼以外的信息,幫助讀者理 解代碼,防止沒必要的重復(fù)注釋信息。 例如:如下注釋意義不大。/* if receive_flag is TRUE */if (receive_flag)而如下的注釋那么給出了額外有用的

16、信息。/* if mtp receive a message from links */if (receive_flag)2.2 函數(shù)頭部應(yīng)進行注釋函數(shù)頭部應(yīng)進行注釋,列出:函數(shù)的目的 / 功能、輸入?yún)?shù)、輸出參數(shù)、返回值、調(diào)用 關(guān)系 ( 函數(shù)、表 ) 等。例如 1:下面這段函數(shù)的注釋比擬標準,當(dāng)然,并不局限于此格式,但上述信息建議要 包含在內(nèi)。/*Function:/函數(shù)名稱Description/函數(shù)功能、性能等的描述Calls:/被本函數(shù)調(diào)用的函數(shù)清單Called By:/調(diào)用本函數(shù)的函數(shù)清單Input:/輸入?yún)?shù)說明,包括每個參數(shù)的作/用、取值說明及參數(shù)間關(guān)系。Output:/對輸出參

17、數(shù)的說明。Return:/函數(shù)返回值的說明Others:/其它說明*/ 對于某些函數(shù),其局部參數(shù)為傳入值,而局部參數(shù)為傳出值,所以對參數(shù)要詳細說明該 參數(shù)是入口參數(shù),還是出口參數(shù),對于某些意義不明確的參數(shù)還要做詳細說明( 例如:以角度作為參數(shù)時,要說明該角度參數(shù)是以弧度 (PI), 還是以度為單位 ), 對既是入口又是出口的變量 應(yīng)該在入口和出口處同時標明。等等。在注釋中詳細注明函數(shù)的適當(dāng)調(diào)用方法,對于返回值的處理方法等。在注釋中要強調(diào)調(diào) 用時的危險方面,可能出錯的地方。2.3 進行注釋時的考前須知(1) 建議邊寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋,以保證注釋與代碼的一致性。 不再有用的注

18、釋要刪除。(2) 注釋的內(nèi)容要清楚、明了,含義準確,防止注釋二義性。說明:錯誤的注釋不但無益 反而有害。(3) 防止在注釋中使用縮寫,特別是非常用縮寫。在使用縮寫時或之前,應(yīng)對縮寫進行必 要的說明。(4) 注釋應(yīng)與其描述的代碼相近, 對代碼的注釋應(yīng)放在其上方或右方 ( 對單條語句的注釋 ) 相鄰位置,不可放在下面。除非必要,不應(yīng)在代碼或表達中間插入注釋,否那么容易使代碼可 理解性變差。例如:如下例子不符合標準。例 1 :/* get replicate sub system index and net indicator */repssn_ind = ssn_dataindex.repssn_

19、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 net indicator */ repssn_ind = ssn_dataindex.repssn_index; repssn_ni = ssn_dataindex.ni;(5) 對

20、于所有有物理含義的變量、常量,如果其命名不是充分自注釋的,在聲明時都必須 加以注釋,說明其物理含義。變量、常量、宏的注釋應(yīng)放在其上方相鄰位置或右方。例如:/* active statistic task number */#define MAX_ACT_TASK_NUMBER 1000#define MAX_ACT_TASK_NUMBER 1000 /* active statistic task number */(6) 數(shù)據(jù)結(jié)構(gòu)聲明 ( 包括數(shù)組、結(jié)構(gòu)、類、枚舉等 ) ,如果其命名不是充分自注釋的,必 須加以注釋。對數(shù)據(jù)結(jié)構(gòu)的注釋應(yīng)放在其上方相鄰位置,不可放在下面;對結(jié)構(gòu)中的每個域 的注釋

21、放在此域的右方。例如:可按如下形式說明枚舉 / 數(shù)據(jù)/ 聯(lián)合結(jié)構(gòu)。/* sccp interface with sccp user primitive message name */enum SCCP_USER_PRIMITIVE N_UNITDATA_IND, /* sccp notify sccp user unit data come */ N_NOTICE_IND, /* sccp notify user the No.7 network can not */* transmission this message */ N_UNITDATA_REQ, /* sccp user'

22、s unit data transmission request*/;(7) 全局變量要有較詳細的注釋,包括對其功能、取值范圍、哪些函數(shù)或過程存取它以及 存取時考前須知等的說明。例如:/* The ErrorCode when SCCP translate */* Global Title failure, as follows */ / 變量作用、含義/* 0 SUCCESS 1 GT Table error */* 2 GT error Others no use */ / 變量取值范圍/* only function SCCPTranslate() in */* this modual

23、can modify it, and other */* module can visit it through call */* the function GetGTTransErrorCode() */ / 使用方法BYTE g_GTTranErrorCode;(8) 注釋與所描述內(nèi)容進行同樣的縮排,讓程序排版整齊,并方便注釋的閱讀與理解。 例如:如下例子,排版不整齊,閱讀稍感不方便。void example_fun( void )/* code one comments */CodeBlock One/* code two comments */ CodeBlock Two應(yīng)改為如下布局

24、。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 one comments */program code one/* code two comments */ program code two

25、(10) 對變量的定義和分支語句 ( 條件分支、循環(huán)語句等 ) 必須編寫注釋。這些語句往往是 程序?qū)崿F(xiàn)某一特定功能的關(guān)鍵,對于維護人員來說,良好的注釋幫助更好的理解程序,有時 甚至優(yōu)于看設(shè)計文檔。(11) 對于 switch 語句下的 case 語句,如果因為特殊情況需要處理完一個 case 后進入 下一個 case 處理( 即上一個 case 后無 break) ,必須在該 case 語句處理完、下一個 case 語句前加上明確的注釋, 以清楚表達程序編寫者的意圖, 有效防止無故遺漏 break 語句( 可避 免后期維護人員對此感到迷惑:原程序員是遺漏了 break 語句還是本來就不應(yīng)該有

26、) 。例如: case CMD_DOWN:ProcessDown();break;case CMD_FWD:ProcessFwd();if (.)break; else ProcessCFW_B(); / now jump into case CMD_A case CMD_A: ProcessA(); break;(12) 在程序塊的結(jié)束行右方加注釋標記,以說明某程序塊的結(jié)束。當(dāng)代碼段較長,特別 是多重嵌套時,這樣做可以使代碼更清晰,更便于閱讀。例如:參見如下例子。if (.) program code while (index < MAX_INDEX) program code /*

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

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

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

30、ows 這樣的環(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)的小寫字母的符號標識作為前綴,標識出變量 的作用域、類型等。這些符號可以多個同時使用,順序是先m_成員變量)、再指針、再簡單數(shù)據(jù)類型

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

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

33、flag->flg 、statistic->stat 、increment->inc 、message->msg 等縮寫能夠被 大家根本認可。(2) 命名中假設(shè)使用特殊約定或縮寫,那么要有注釋說明。應(yīng)該在源文件的開始之處,對文件 中所使用的縮寫或約定,特別是特殊的縮寫,進行必要的注釋說明。(3) 自己特有的命名風(fēng)格,要自始至終保持一致,不可來回變化。個人的命名風(fēng)格,在符 合所在工程組或產(chǎn)品組的命名規(guī)那么的前提下, 才可使用。 ( 即命名規(guī)那么中沒有規(guī)定到的地方才 可有個人命名風(fēng)格 ) 。(4) 對于變量命名,禁止取單個字符 (如 i 、j 、k. ) ,建議除了要有具體

34、含義外,還 能說明其變量類型、數(shù)據(jù)類型等,但 i 、j 、k 作局部循環(huán)變量是允許的。變量,尤其是局 部變量,如果用單個字符表示,很容易敲錯 ( 如 i 寫成 j) ,而編譯時又檢查不出來,有可能 為了這個小小的錯誤而花費大量的查錯時間。(5) 除非必要,不要用數(shù)字或較奇怪的字符來定義標識符。(6) 命名標準必須與所使用的系統(tǒng)風(fēng)格保持一致,并在同一工程中統(tǒng)一。(7) 在同一軟件產(chǎn)品內(nèi),應(yīng)規(guī)劃好接口局部標識符 ( 變量、結(jié)構(gòu)、函數(shù)及常量 ) 的命名,防 止編譯、鏈接時產(chǎn)生沖突。對接口局部的標識符應(yīng)該有更嚴格限制,防止沖突。如可規(guī)定接 口局部的變量與常量之前加上“模塊標識等。(8) 用正確的反義詞

35、組命名具有互斥意義的變量或相反動作的函數(shù)等。 下面是一些在軟件中常用的反義詞組add / removebegin / endinsert / delete first / last increment / decrementadd / delete min / max next / previous send / receive cut / pastelock / unlockcreate / destroy g et / release put / get open / closeold / newstart / stopsource / target show / hide source

36、/ destinationup / down例如:int min_sum;int max_sum;int add_user( BYTE *user_name ); int delete_user( BYTE *user_name );(9) 除了編譯開關(guān)/頭文件等特殊應(yīng)用,應(yīng)防止使用_EXAMPLE_TEST之類以下劃線開始 和結(jié)尾的定義。3.3 變量名的命名規(guī)那么(1) 變量的命名規(guī)那么要求用“匈牙利法那么 。即開頭字母用變量的類型,其余局部用變量 的英文意思、英文的縮寫、中文全拼或中文全拼的縮寫 , 要求單詞的第一個字母應(yīng)大寫。即: 變量名 =變量類型 +變量的英文意思 ( 或英文縮寫、中

37、文全拼、中文全拼縮寫 ) 對非通用的變量,在定義時參加注釋說明,變量定義盡量可能放在函數(shù)的開始處。見下表:bool 用 b 開頭 bFlg int 用 i 開頭 iCount short int 用 n 開頭 nStepCount long int 用 l 開頭 lSum char 用 c 開頭 cCount unsigned char 用 by 開頭 float 用 f 開頭 fAvg double 用 d 開頭 dDeta unsigned int(WORD) 用 w 開頭 wCount unsigned long int(DWORD) 用 dw 開頭 dwBroad 字符串 用 s 開頭

38、 sFileName 用 0 結(jié)尾的字符串 用 sz 開頭 szFileName(2) 指針變量命名的根本原那么為:對一重指針變量的根本原那么為:“P +變量類型前綴+ 命名,如一個float*型應(yīng)該表示為 pfStat 。對二重指針變量的根本規(guī)那么為: “pp +變量類型前綴 +命名。對三重指針變量的根本 規(guī)那么為:“ PPP +變量類型前綴 +命名。(3) 全局變量用g_開頭,如一個全局的長型變量定義為 g_IFailCount,即:變量名=g_+變 量類型+變量的英文意思 (或縮寫)。此規(guī)那么還可防止局部變量和全局變量同名而引起的問題。靜態(tài)變量用s_開頭,如一個靜態(tài)的指針變量定義為 s_

39、plPerv_lnst,即:變量名=s_+ 變量類型 +變量的英文意思 (或縮寫)(5) 對枚舉類型(enum)中的變量,要求用枚舉變量或其縮寫做前綴。并且要求用大寫。女口: enum cmEMDAYS EMDAYS_MONDAY; EMDAYS_TUESDAY;(6) 對 struct 、union 變量的命名要求定義的類型用大寫。并要加上前綴,其內(nèi)部變量的 命名規(guī)那么與變量命名規(guī)那么一致結(jié)構(gòu)一般用 S 開頭,如:struct ScmNPointint nX;/ 點的 X 位置int nY; / 點的 Y 位置;聯(lián)合體一般用U開頭,如:union UcmLPointLONG lX;LONG

40、lY;(7) 對常量 ( 包括錯誤的編碼 ) 命名,要求常量名用大寫,常量名用英文表達其意思。當(dāng)需要由多個單詞表示時,單詞與單詞之間必須采用連字符“_連接。女口: #define CM_FILE_NOT_FOUND CMMAKEHR(0X20B其中 CM表示類別。(8) 對const的變量要求在變量的命名規(guī)那么前參加c_,即:c_+變量命名規(guī)那么;例如:const char* c_szFileName;3.4 函數(shù)的命名標準(1) 函數(shù)的命名應(yīng)該盡量用英文 (或英文縮寫、中文全拼、中文全拼縮寫 )表達出函數(shù)完成的功能函數(shù)名應(yīng)準確描述函數(shù)的功能。遵循動賓結(jié)構(gòu)的命名法那么,函數(shù)名中動詞在前,并在命

41、名前參加函數(shù)的前綴,函數(shù)名的長度不得少于 8 個字母。函數(shù)名首字大寫,假設(shè)包含有 兩個單詞的每個單詞首字母大寫。如果是OOP方法,可以只有動詞(名詞是對象本身)。例如:LONG GetDeviceCount();void print_record( unsigned int rec_ind ) ;int input_record( void ) ;unsigned char get_current_color( void ) ;(2) 防止使用無意義或含義不清的動詞為函數(shù)命名。 如使用 process、handle 等為函數(shù)命 名,因為這些動詞并沒有說明要具體做什么。(3) 必須使用函數(shù)原型聲

42、明。函數(shù)原型聲明包括:引用外來函數(shù)及內(nèi)部函數(shù),外部引用必 須在右側(cè)注明函數(shù)來源: 模塊名及文件名; 內(nèi)部函數(shù),只要注釋其定義文件名和調(diào)用者 在同一文件中 (簡單程序)時不需要注釋。應(yīng)確保每個函數(shù)聲明中的參數(shù)的名稱、類型和定義中的名稱、類型一致。3.5 函數(shù)參數(shù)命名標準(1) 參數(shù)名稱的命名參照變量命名標準。(2) 為了提高程序的運行效率,減少參數(shù)占用的堆棧,傳遞大結(jié)構(gòu)的參數(shù),一律采用指針 或引用方式傳遞。(3) 為了便于其他程序員識別某個指針參數(shù)是入口參數(shù)還是出口參數(shù), 同時便于編譯器檢 查錯誤,應(yīng)該在入口參數(shù)前參加 const 標志。如:cmCopyStri ng(co nst CHAR *

43、 c_szSource, CHAR * szDest)3.6 文件名 (包括動態(tài)庫、組件、控件、工程文件等 ) 的命名標準 文件名的命名要求表達出文件的內(nèi)容,要求文件名的長度不得少于 5 個字母,嚴禁使用 象 file1,myfile 之類的文件名。4 可讀性4.1 防止使用默認的運算優(yōu)先級 注意運算符的優(yōu)先級,并用括號明確表達式的操作順序,防止使用默認優(yōu)先級,可防止 閱讀程序時產(chǎn)生誤解,防止因默認的優(yōu)先級與設(shè)計思想不符而導(dǎo)致程序出錯。例如:以下語句中的表達式word = (high << 8) | low (1)if (a | b) && (a & c)(

44、2)if (a | b) < (c & d)(3)如果書寫為 :high << 8 | low a | b && a & c a | b < c & d由于high << 8 | low = ( high << 8) | low,a | b && a & c = (a | b) && (a & c),(1) (2) 不會出錯,但語句不易理解;a | b < c & d = a | (b < c) & d,(3) 造成了判斷條件出錯。

45、4.2 使用有意義的標識,防止直接使用數(shù)字 防止使用不易理解的數(shù)字,用有意義的標識來替代。涉及物理狀態(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 (Trunkindex.trunk_state = TRUNK_IDLE)Trunkindex.trunk_state = TRUNK_BUSY;.

46、 / program code4.3 源程序中關(guān)系較為緊密的代碼應(yīng)盡可能相鄰 這樣做的好處是便于程序閱讀和查找。例如:以下代碼布局不太合理。rect.length = 10;char_poi = str;rect.width = 5;假設(shè)按如下形式書寫,可能更清晰一些。rect.length = 10;rect.width = 5; / 矩形的長與寬關(guān)系較密切,放在一起。char_poi = str;4.4 不要使用難懂的技巧性很高的語句、復(fù)雜的表達式 除非很有必要時,原那么上不要使用難懂的技巧性很高的語句和復(fù)雜的表達式高技巧 語句不等于高效率的程序,源程序占用空間的節(jié)約并不等于目標程序占用空

47、間的節(jié)約,實際 上程序的效率關(guān)鍵在于算法。(1) 如下表達式,考慮不周就可能出問題,也較難理解。* 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) 如下表達式,不同的編譯器給出的結(jié)果不一樣, bi 是否先執(zhí)行?x=bi + i+;應(yīng)改為:x = bi + i;i+;5 變量與結(jié)構(gòu)5.1 謹慎使用全局 ( 公共)變量(1) 去掉

48、沒必要的公共變量。 公共變量是增大模塊間耦合的原因之一, 故應(yīng)減少沒必要的 公共變量以降低模塊間的耦合度。(2) 仔細定義并明確公共變量的含義、作用、取值范圍及公共變量間的關(guān)系。在對變量聲 明的同時,應(yīng)對其含義、作用及取值范圍進行注釋說明,同時假設(shè)有必要還應(yīng)說明與其它變量 的關(guān)系。(3) 防止局部變量與公共變量同名通過使用較好的命名規(guī)那么來消除此問題。5.2 數(shù)據(jù)類型間的轉(zhuǎn)換(1) 編程時,要注意數(shù)據(jù)類型的強制轉(zhuǎn)換。當(dāng)進行數(shù)據(jù)類型強制轉(zhuǎn)換時,其數(shù)據(jù)的意義、 轉(zhuǎn)換后的取值等都有可能發(fā)生變化,而這些細節(jié)假設(shè)考慮不周,就很有可能留下隱患。(2) 對編譯系統(tǒng)默認的數(shù)據(jù)類型轉(zhuǎn)換,也要有充分的認識。例如:

49、如下賦值,多數(shù)編譯器 不產(chǎn)生告警,但值的含義還是稍有變化。char chr;unsigned short int exam;chr = -1;exam = chr; / 編譯器不產(chǎn)生告警,此時 exam為OxFFFF。(3) 盡量減少沒有必要的數(shù)據(jù)類型默認轉(zhuǎn)換與強制轉(zhuǎn)換。例如,所有的 unsigned 類型都 應(yīng)該有后綴“ U'以明確其類型。(4) 合理地設(shè)計數(shù)據(jù)并使用自定義數(shù)據(jù)類型,防止數(shù)據(jù)間進行不必要的類型轉(zhuǎn)換。(5) 對自定義數(shù)據(jù)類型進行恰當(dāng)命名,使它成為自描述性的,以提高代碼可讀性。注意其 命名方式在同一產(chǎn)品中的統(tǒng)一,并且保證沒有多重定義。使用自定義類型,可以彌補編程語 言提供

50、類型少、信息量缺乏的缺點,并能使程序清晰、簡潔。例如:可參考如下方式聲明自 定義數(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) 不要用八進制數(shù)整型常數(shù)以 0“開始會被認為是 8 進制。例如: code1=109code2=100code3=052code4=071如果是對總線消息初始化,會有危險。6

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

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

53、數(shù)好象沒有必要,但用函數(shù)可使功能明確化,增加程序可讀性,亦可方便維護、測試。 例如:如下語句的功能不 很明顯。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ù)暮甏孢@樣可以增加編程效率和程序的可讀性。 例

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

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

56、 = 0;Rect.width = 0; /* 初始化矩形的長與寬 */void Init_Point( void )Point.x = 10;Point.y = 10; /* 初始化“點的坐標 */(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)用對程序的測試有一定影響。故除非為

57、某些算法或功能的實現(xiàn)方便,應(yīng)減少沒必要的遞歸調(diào)用,對 于 safe-related 系統(tǒng)不能用遞歸,因為超出堆棧空間很危險。6.2 函數(shù)的返回值(1) 對于函數(shù)的返回位置, 盡量保持單一性, 即一個函數(shù)盡量做到只有一個返回位置。 (單入口單出口 )要求大家統(tǒng)一函數(shù)的返回值,所有的函數(shù)的返回值都將以編碼的方式返回 例如編碼定義如下:#define CM_POINT_IS_NULL CMMAKEHR(0X200)建議函數(shù)實現(xiàn)如下:LONG函數(shù)名(參數(shù),)LONG lResult; /保持錯誤號lResult=CM_OK;/ 如果參數(shù)有錯誤那么返回錯誤號 if( 參數(shù) =NULL) lResult=CM_POINT_

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論