| 我做C語言底層開發,積累了一些代碼書寫的經驗供大家參考: 1.C語言書寫規範
1.1符號命名規則 1.1.1符號名包括模組名、常量名、標號名、子程式名等。這些名字應該能反映它所代表的實際東西,具有一定的意義,使其能夠見名知義,有助於對程式功能的理解。命名採用匈牙利命名法。規則如下: (1)所有宏定義、枚舉常數和const變數,用大寫字母命名。在複合詞裡用底線隔開每個詞。 (2)複合詞中每個單詞的第一個字母大寫。除了規則5.1.1.1以外,避免使用底線。 (3)類、類型定義和枚舉型名的第一個字母大寫。 (4)函數名是複合詞的,第一個詞採用全部小寫,隨後每個單詞採用第一個字母大寫,其它字母小寫方式;如果是單個詞的,採用全部小寫方式。 (5)迴圈變數可採用i, j, k等,不受上述規則限制。 (6) 類的成員變數應採用m_開頭。 (7) 全域變數詞頭為g_ 。 (8) 臨時變數詞頭為tmp_ 。 (9) 對結構體內的變數命名, 遵循變數的具體含義命名原則 (10)用小寫字母的首碼表示變數的類型,首碼的下一個字母用大寫。 表 1 詞 頭 類 型 詞 頭 類 型 ch char l long i integer u unsigned b boolean p pointer f float lp long pointer d double s string st structure sz ASCII string by byte n short int H handle x,y 分別為x,y座標 dw DWORD fn function 表 2 詞 頭 變 量 名 詞 頭 變 量 名 task task sig signal sb binary semaphores wd watchdog sm mutual exclusion semaphores tm timer sc counting semaphores msg message pipe pipe 例: #define ARRAY_SIZE 24 /*規則5.1.1.1*/ int g_iFlag; class MyClass /*規則5.1.1.3*/ { }; void someFunc( ) /*規則5.1.1.2和5.1.1.4*/ { .2. Q/ECC/BJ 010—2001 int nArray[ARRAY_SIZE]; unsigned char uchByte; char szName[ ]; char *pszName = szName; } (11)有些詞頭(如p和u)可以和其它詞頭組合。 例:WDOG_ID wdId; WDOG_ID g_wdId; /*全域watchdog Id,故以g_開頭*/ 1.1.2名字的長度一般不要過長或過短。過長的名字會增加工作量,使程式邏輯流程變得模糊;過短的名字無法表達符號的實際意義。約定長度範圍:3-31; 1.2資料和函數說明 1.2.1資料說明次序應當正常化,使資料屬性容易尋找,也有利於測試、排錯和維護。說明的先後次序應固定,應按邏輯功能排序,邏輯功能塊內建議採用下列順序:整型說明、實型說明、字元說明、邏輯量說明。 1.2.2如果設計了一個複雜的資料結構,應當通過注釋對其變數的含義、用途進行說明。 1.2.3在函數的聲明中使用異常聲明。 如:void f() throw(toobig, toosmall, divzero); 在聲明一個函數時,將它所拋出的異常列出,便於函數的使用者瞭解可能會發生哪些異常。 1.3 程式注釋 1.3.1程式注釋是程式員與日後的程式讀者之間通訊的重要手段之一,注釋分為檔案注釋、函數注釋和功能注釋。 1.3.2正規程式的注釋應注意: ——注釋行的數量佔到整個來源程式的1/3到1/2。 1.3.3檔案注釋位於整個來源程式的最開始部分,注釋後空兩行開始程式本文。它包括: ——程式標題。 ——目的、功能說明。 ——檔案作者、最後修改日期等說明。 例: ./******************************************************************** (空一行) 標題: Demo.c 功能: 測試VxWorks的各種系統調用. 說明: 該程式測試各種VxWorks的系統調用函數。包括任務(taks)的建立、掛起及任務間通過號誌實現同步,通過訊息佇列進行通訊。 程式建立了兩個任務:一個高優先順序的任務和一個低優先順序的任務。兩個任務間通過一個二進位的號誌進行同步,通過訊息佇列進行通訊。 目前的版本: x.x 修改資訊: 2000.06.05 John, Initial Version 2000.07.05 Tom, Bug xxxx fixed **************************************************************/ (空2行,開始程式本文) 1.3.4 函數注釋通常置於每函數或過程的開頭部分,它應當給出函數或過程的整體說明對於理解程式本身具有引導作用。一般包括如下條目: ——模組標題。 ——有關本模組功能和目的的說明。 ——調用格式 ——介面說明:包括輸入、輸出、傳回值、異常。 ——演算法。如果模組中採用了一些複雜的演算法。 例: file://(注釋開頭應和上一函數空兩行) (注釋開頭與上一函數最後一行間隔兩行) /******************************************************************** 標題:assignmentComplete 功能:BSC=>MSC訊息產生函數,產生assignment_complete指配完成訊息(BSMAP訊息) . 格式: int assignmentComplete(int iCellId, int iServiceChannnelNum, char *pszMSGData) throw(exception1, exception2) 輸入: int iCellId: MS所在的小區識別 iCellId取值:0x00-——0xff .4. Q/ECC/BJ 010—2001 int iServiceChannnelNum:MS所佔的業務通道號碼 輸出: char * pszMSGData:指配完成訊息資料 傳回值: 0x00正常 異常:exception1異常情況1, exception2異常情況2 ********************************************************************/ ( 注釋後直接開始程式本文,不空行。) 1.3.5功能性注釋嵌在來源程式體中,用於描述其後的語句或程式段做什麼工作,也就是解釋下面要做什麼,或是執行了下面的語句會怎麼樣。而不要解釋下面怎麼做,因為解釋怎麼做常常與程式本身是重複的。 例: /*把 amount 加到 total中*/ total = amount + total; 這樣的注釋僅僅是重複了下面的程式,對於理解它的工作並沒有什麼作用。而下面的注釋,有助於讀者理解。 /*將每月的銷售額amount加到年銷售額total中*/ total = amount + total; 1.4 函數編寫應儘可能短小精悍,一般不超過兩屏,以便於調試和理解。 1.5語句結構 為保證語句結構的清晰和程式的可讀性,在編寫軟體程式時應注意以下幾個方面的問題: ——在一行內唯寫一條語句,並採用空格、空行和移行保證清楚的視覺效果。 ——每一個嵌套的函數塊,使用一個TAB縮排(可以設定為4個空格),大括弧必須放在條件陳述式的下一行,單獨成一行,便於匹對: 如,有一段程式如下: for(i=1;i<n-1;i++){ t=1; for(j=i+1;j<n;j++){ if(a[j]<a[t] ) t=j; if(t!=i ){work=a[t];a[t]=a[I];a[I]=work;}}} 應寫為 for( i=1; i<n-1; i++) { t=1; for(j = i+1; j<n; j++) { if(a[i]<a[j]) t=j; if(t!=1) { .5. Q/ECC/BJ 010—2001 work=a[t]; a[t]=a[i]; a[i]=work; } } } ——檔案之中不得存在無規則的空行,比如說連續十個空行。 一般來講函數與函數之間的空行為2-3行; 在函數體內部,在邏輯上獨立的兩個函數塊可適當空行,一般為1-2行。 ——程式編寫首先應考慮清晰性,不要刻意追求技巧性而使得程式難以理解。 ——每行長度盡量避免超過螢幕寬度,應不超過80個字元。 ——除非對效率有特殊要求,編寫程式要作到清晰第一,效率第二。 ——儘可能使用函數庫。 ——盡量用公用過程或子程式去代替重複的功能程式碼片段。要注意,這個代碼應具有一個獨立的功能,不要只因代碼形式一樣便將其抽出組成一個公用過程或子程式。 ——使用括弧清晰地表達算術運算式和邏輯運算式的運算順序。如將 x=a*b/c*d 寫成 x=(a*b/c)*d可避免閱讀者誤解為x=(a*b)/(c*d)。 ——避免不必要的轉移。 ——避免採用過於複雜的條件測試。 ——避免過多的迴圈嵌套和條件嵌套。 ——建議不要使用 *=,^=, /=等運算子。 ——一個函數不要超過200行。一個檔案應避免超過2000行。 ——盡量避免使用go to語句。 ——避免採用多指派陳述式,如x = y = z ; ——不鼓勵採用?:操作符,如z = (a>b)?a:b; ——不要使用空的if else 語句。如 if(cMychar >= ‘A’) if(cMychar <= ‘Z’) printf(“This is a letter /n”); else printf(“This is not a letter /n”); else到底是否定哪個if容易引起誤解。可通過加{}避免誤解。 ——盡量減少使用“否定”條件的條件陳述式。如: 把 if( !( (cMychar<’0’) || (cMychar>’9’) ) ) 改為if( (cMychar>=’0’) && (cMychar<=’9’) ) |