規(guī)范的代碼可以促進團隊合作,一個項目大多都是由一個團隊來完成,如果沒有統(tǒng)一的代碼規(guī)范,那么每個人的代碼必定會風格迥異,等到要整合代碼的時候也有夠頭疼的了。
我認為,編碼規(guī)范,在軟件構件以及項目管理中,甚至是個人成長方面,都發(fā)揮著重要的作用,好的編碼規(guī)范是提高我們代碼質量的最有效的工具之一。
幾乎每個項目,每家公司都會定義自己的編碼規(guī)范,我們可以參考一下華為公司C/C++的編碼規(guī)范。
1、代碼排版
1、程序塊要采用縮進風格編寫,縮進的空格數(shù)為4個(說明:對于由開發(fā)工具自動生成的代碼可以有不一致)。
2、相對獨立的程序塊之間、變量說明之后必須加空行。
3、循環(huán)、判斷等語句中若有較長的表達式或語句,則要進行適應的劃分,長表達式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首。
4、若函數(shù)或過程中的參數(shù)較長,則要進行適當?shù)膭澐帧?/p>
5、不允許把多個短語句寫在一行中,即一行只寫一條語句。
6、if、for、do、while、case、switch、default等語句自占一行,且if、for、do、while等語句的執(zhí)行語句部分無論多少都要加括號{}。
7、對齊只使用空格鍵,不使用TAB鍵。8、函數(shù)或過程的開始、結構的定義及循環(huán)、判斷等語句中的代碼都要采用縮進風格,case語句下的情況處理語句也要遵從語句縮進要求。
9、程序塊的分界符(如C/C++語言的大括號‘{’ 和‘}’)應各獨占一行并且位于同一列,同時與引用它們的語句左對齊。在函數(shù)體的開始、類的定義、結構的定義、枚舉的定義以及if、for、do、while、switch、case語句中的程序都要采用如上的縮進方式。
10、在兩個以上的關鍵字、變量、常量進行對等操作時,它們之間的操作符之前、之后或者前后要加空格;進行非對等操作時,如果是關系密切的立即操作符(如-》),后不應加空格(說明:采用這種松散方式編寫代碼的目的是使代碼更加清晰)。
注意:(1)由于留空格所產(chǎn)生的清晰性是相對的,所以,在已經(jīng)非常清晰的語句中沒有必要再留空格,如果語句已足夠清晰則括號內(nèi)側(即左括號后面和右括號前面)不需要加空格,多重括號間不必加空格,因為在C/C++語言中括號已經(jīng)是最清晰的標志了。
(2)在長語句中,如果需要加的空格非常多,那么應該保持整體清晰,而在局部不加空格。給操作符留空格時,不要連續(xù)留兩個以上空格。
2、代碼注釋 1、一般情況下,源程序有效注釋量必須在20%以上(說明:注釋的原則是有助于對程序的閱讀理解,在該加的地方都加了,注釋不宜太多也不能太少,注釋語言必須準確、易懂、簡潔)。
2、說明性文件(如頭文件.h文件、.inc文件、.def文件、編譯說明文件.cfg等)頭部應進行注釋,注釋必須列出:版權說明、版本號、生成日期、作者、內(nèi)容、功能、與其它文件的關系、修改日志等,頭文件的注釋中還應有函數(shù)功能簡要說明。
3、源文件頭部應進行注釋,列出:版權說明、版本號、生成日期、作者、模塊目的/功能、主要函數(shù)及其功能、修改日志等。
4、函數(shù)頭部應進行注釋,列出:函數(shù)的目的/功能、輸入?yún)?shù)、輸出參數(shù)、返回值、調(diào)用關系(函數(shù)、表)等。
示例:
下面這段函數(shù)的注釋比較標準,當然,并不局限于此格式,但上述信息建議要包含在內(nèi)。
? Function: // 函數(shù)名稱
? Description: // 函數(shù)功能、性能等的描述
? Calls: // 被本函數(shù)調(diào)用的函數(shù)清單
? Called By: // 調(diào)用本函數(shù)的函數(shù)清單
? Table Accessed: // 被訪問的表(此項僅對于牽扯到數(shù)據(jù)庫操作的程序)
? Table Updated: // 被修改的表(此項僅對于牽扯到數(shù)據(jù)庫操作的程序)
? Input: // 輸入?yún)?shù)說明,包括每個參數(shù)的作用、取值說明及參數(shù)間關系
? Output: // 對輸出參數(shù)的說明
? Return: // 函數(shù)返回值的說明
5、邊寫代碼邊注釋,修改代碼同時修改相應的注釋,以保證注釋與代碼的一致性;不再有用的注釋要刪除。
6、注釋的內(nèi)容要清楚、明了,含義準確,防止注釋二義性。
7、避免在注釋中使用縮寫,特別是非常用縮寫。
8、注釋應與其描述的代碼相近,對代碼的注釋應放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面,如放于上方則需與其上面的代碼用空行隔開。
9、對于所有有物理含義的變量、常量,如果其命名不是充分自注釋的,在聲明時都必須加以注釋,說明其物理含義。變量、常量、宏的注釋應放在其上方相鄰位置或右方。
10、數(shù)組、結構、類、枚舉等,如果其命名不是充分自注釋的,必須加以注釋。對數(shù)據(jù)結構的注釋應放在其上方相鄰位置,不可放在下面;對結構中的每個域的注釋放在此域的右方。
11、全局變量要有較詳細的注釋,包括對其功能、取值范圍、哪些函數(shù)或過程存取它以及存取時注意事項等的說明。
12、注釋與所描述內(nèi)容進行同樣的縮排。
13、將注釋與其上面的代碼用空行隔開。
14、函數(shù)的頭部應進行注釋,列出函數(shù)的功能、目的、輸入輸出參數(shù)、返回值、調(diào)用關系(表、函數(shù))等。
15、對變量的定義和分支語句(條件分支、循環(huán)語句等)必須編寫注釋。
16、對于switch語句下的case語句,如果因為特殊情況需要處理完一個case后進入下一個case處理,必須在該case語句處理完、下一個case語句前加上明確的注釋。
3、標識符命名 1、標識符的命名要清晰、明了,有明確含義;同時,使用完整的單詞或大家基本可以理解的縮寫,避免使人產(chǎn)生誤解(說明:較短的單詞可通過去掉“元音”形成縮寫;較長的單詞可取單詞的頭幾個字母形成縮寫;一些單詞有大家公認的縮寫)。示例:如下單詞的縮寫能夠被大家基本認可:? temp可縮寫為 tmp; 臨時? flag可縮寫為 flg; 標志? statistic可縮寫為 stat ; 統(tǒng)計? increment可縮寫為 inc; 增量? message可縮寫為 msg; 消息
2、命名中若使用特殊約定或縮寫,則要有注釋說明(說明:應該在源文件的開始之處,對文件中所使用的縮寫或約定,特別是特殊的縮寫,進行必要的注釋說明)。
3、自己特有的命名風格,要自始至終保持一致,不可來回變化(說明:個人的命名風格,在符合所在項目組或產(chǎn)品組的命名規(guī)則的前提下才可使用,即命名規(guī)則中沒有規(guī)定到的地方才可有個人命名風格)。
4、對于變量命名,禁止取單個字符(如i、j、k…),建議除了要有具體含義外,還能表明其變量類型、數(shù)據(jù)類型等,但i、j、k作局部循環(huán)變量是允許的。
說明:變量,尤其是局部變量,如果用單個字符表示,很容易敲錯(如i寫成j),而編譯時又檢查不出來,有可能為了這個小小的錯誤而花費大量的查錯時間。
5、命名規(guī)范必須與所使用的系統(tǒng)風格保持一致,并在同一項目中統(tǒng)一,比如采用UNIX的全小寫加下劃線的風格或大小寫混排的方式,不要使用大小寫與下劃線混排的方式,用作特殊標識如標識成員變量或全局變量的m_ 和g_ ,其后加上大小寫混排的方式是允許的。
4、代碼可讀性1、注意運算符的優(yōu)先級,并用括號明確表達式的操作順序,避免使用默認優(yōu)先級。2、避免使用不易理解的數(shù)字,用有意義的標識來替代。涉及物理狀態(tài)或者含有物理意義的常量,不應直接使用數(shù)字,必須用有意義的枚舉或宏來代替。
5、變量、結構 1、去掉沒必要的公共變量(說明:公共變量是增大模塊間耦合的原因之一,故應減少沒必要的公共變量以降低模塊間的耦合度)。
2、仔細定義并明確公共變量的含義、作用、取值范圍及公共變量間的關系(說明:在對變量聲明的同時,應對其含義、作用及取值范圍進行注釋說明;同時,若有必要,還應說明與其它變量的關系)。
3、明確公共變量與操作此公共變量的函數(shù)或過程的關系,如訪問、修改及創(chuàng)建等(說明:明確過程操作變量的關系后,將有利于程序的進一步優(yōu)化、單元測試、系統(tǒng)聯(lián)調(diào)以及代碼維護等,這種關系的說明可在注釋或文檔中描述)。
示例:在源文件中,可按如下注釋形式說明。? RELATION System_Init Input_Rec Print_Rec Stat_Score? Student Create Modify Access Access? Score Create Modify Access Access, Modify注意:RELATION為操作關系;System_Init、Input_Rec、Print_Rec、Stat_Score為四個不同的函數(shù);Student、Score為兩個全局變量;Create表示創(chuàng)建,Modify表示修改,Access表示訪問。其中,函數(shù)Input_Rec、Stat_Score都可修改變量Score,故此變量將引起函數(shù)間較大的耦合,并可能增加代碼測試、維護的難度。
4、當向公共變量傳遞數(shù)據(jù)時,要十分小心,防止賦與不合理的值或越界等現(xiàn)象發(fā)生(說明:對公共變量賦值時,若有必要應進行合法性檢查,以提高代碼的可靠性、穩(wěn)定性)。
5、防止局部變量與公共變量同名(說明:若使用了較好的命名規(guī)則,那么此問題可自動消除)。
6、嚴禁使用未經(jīng)初始化的變量作為右值(說明:特別是在C/C++中引用未經(jīng)賦值的指針,經(jīng)常會引起系統(tǒng)崩潰)。
6、函數(shù)與過程 1、對所調(diào)用函數(shù)的錯誤返回碼要仔細、全面地處理。
2、明確函數(shù)功能,精確(而不是近似)地實現(xiàn)函數(shù)設計。
3、編寫可重入函數(shù)時,應注意局部變量的使用(如編寫C/C++語言的可重入函數(shù)時,應使用auto,即缺省態(tài)局部變量或寄存器變量)。
說明:編寫C/C++語言的可重入函數(shù)時,不應使用static局部變量,否則必須經(jīng)過特殊處理,才能使函數(shù)具有可重入性。
4、編寫可重入函數(shù)時,若使用全局變量,則應通過關中斷、信號量(即P、V操作)等手段對其加以保護。
說明:若對所使用的全局變量不加以保護,則此函數(shù)就不具有可重入性,即當多個進程調(diào)用此函數(shù)時,很有可能使有關全局變量變?yōu)椴豢芍獱顟B(tài)。
示例:
假設Exam是int型全局變量,函數(shù)Squre_Exam返回Exam平方值。那么,如下函數(shù)不具有可重入性。
unsigned int example( int para )
{
unsigned int temp;
Exam = para; // ()
temp = Square_Exam( );
return temp;
}
此函數(shù)若被多個進程調(diào)用的話,其結果可能是未知的,因為當()語句剛執(zhí)行完后,另外一個使用本函數(shù)的進程可能正好被激活,那么當新激活的進程執(zhí)行到此函數(shù)時,將使Exam賦與另一個不同的para值,所以當控制重新回到“temp = Square_Exam( )”后,計算出的temp很可能不是預想中的結果。此函數(shù)應如下改進:
unsigned int example( int para )
{
unsigned int temp;[申請信號量操作] // 若申請不到“信號量”, 說明另外的進程正處于
Exam = para; // 給Exam賦值并計算其平方過程中(即正在使用此信號), 本進程必須等待其釋放信號后, 才可繼續(xù)執(zhí)行。若申請到信號, 則可繼續(xù)執(zhí)行, 但其它進程必須等待本進程釋放信號量后, 才能再使用本信號。
temp = Square_Exam( ); // [釋放信號量操作]
return temp;
}
5、在同一項目組應明確規(guī)定對接口函數(shù)參數(shù)的合法性檢查,該由函數(shù)的調(diào)用者負責,還是由接口函數(shù)本身負責,缺省是由函數(shù)調(diào)用者負責(說明:對于模塊間接口函數(shù)的參數(shù)的合法性檢查這一問題,往往有兩個極端現(xiàn)象,即:要么是調(diào)用者和被調(diào)用者對參數(shù)均不作合法性檢查,結果就遺漏了合法性檢查這一必要的處理過程,造成問題隱患;要么就是調(diào)用者和被調(diào)用者均對參數(shù)進行合法性檢查,這種情況雖不會造成問題,但產(chǎn)生了冗余代碼,降低了效率)。
7、程序效率 1、編程時要經(jīng)常注意代碼的效率。
2、在保證軟件系統(tǒng)的正確性、可讀性、穩(wěn)定性及可測試性的前提下,提高代碼效率。
3、對模塊中函數(shù)的劃分及組織方式進行分析、優(yōu)化,改進模塊中函數(shù)的組織結構,提高程序效率。
4、編程時,要隨時留心代碼效率;優(yōu)化代碼時,要考慮周全。
5、不應花過多的時間拼命地提高調(diào)用不很頻繁的函數(shù)代碼效率。
6、要仔細地構造或直接用匯編編寫調(diào)用頻繁或性能要求極高的函數(shù)。
7、在保證程序質量的前提下,通過壓縮代碼量、去掉不必要代碼,以及減少不必要的局部和全局變量,來提高空間效率。
8、在多重循環(huán)中,應將最忙的循環(huán)放在最內(nèi)層。
9、盡量減少循環(huán)嵌套層次。
10、避免循環(huán)體內(nèi)含判斷語句,應將循環(huán)語句置于判斷語句的代碼塊之中。
11、盡量用乘法或其他的方法代替除法,特別是浮點運算中的除法。
12、不要一味追求緊湊的代碼。
最后提醒一句,“任何一個傻瓜都能寫出計算機可以理解的代碼,唯有寫出人類容易理解的代碼,才是優(yōu)秀的程序員?!敝贫ㄒ粋€符合自己公司情況的開發(fā)規(guī)范是很簡單的,重要的是我們能夠認識到規(guī)范的重要性,并堅持規(guī)范的開發(fā)習慣。
編輯:黃飛
評論
查看更多