【規則1-1】遵循統一的佈局順序來書寫頭文件。 |
說明:以下內容如果某些節不需要,可以忽略。但是其它節要保持該次序。
文件註釋
#ifndef 文件名_H(全大寫)
#define 文件名_H
其它預編譯條件選項
#include(依次爲標準庫頭文件、非標準庫頭文件)
常量和全局宏定義全局宏
全局數據類型
全局變量聲明(extern)
全局函數原型
#endif
【規則1-2】遵循統一的佈局順序來書寫實現文件。 |
說明:以下內容如果某些節不需要,可以忽略。但是其它節要保持該次序。
文件註釋
#include(依次爲標準庫頭文件、非標準庫頭文件)
常量定義和文件內部使用宏的定義
文件內部使用的數據類型
全局變量定義和聲明(extern) /*不允許在新增加的實現文件中使用全局變量extern聲明 */
靜態全局變量
全局函數聲明(extern)/*不允許在新增加的實現文件中使用全局函數extern聲明 */
局部函數原型
全局函數實現
局部函數實現
【規則1-3】禁止使用TAB鍵,必須使用空格進行縮進。嵌套的條件編譯採用縮進的格式,{ }之內的代碼塊使用縮進規則對齊。縮進爲4個空格。 |
【規則1-4】if、else、else if、for、while、do、switch、case等所有條件和循環控制語句自佔一行,執行語句不得緊跟其後。不論執行語句有多少都要加 “{”、“ }”,“{”和“}”必須各佔一行。 |
正例:if (ucVal < ucIndexMax)
{
ucVal = ucIndexMax;
}
反例:if (ucVal < ucIndexMax) ucVal = ucIndexMax;
【規則1-5】定義指針類型的變量,*應放在變量前。 |
正例:float *pfBuffer = NULL;
反例:float* pfBuffer;
【規則1-6】文件名統一使用小寫。 |
-
- 註釋要求
【規則2-1】 C語言的註釋符爲“/* … */”。C++語言中,多行註釋採用“/* … */”,單行註釋採用“/*”和“*/”。 |
|
【規則2-2】一般情況下,源程序有效註釋量必須在20%以上。 |
正例:void Main()
{
if (…) /* 條件說明 */
{ /* 簡單介紹本複合語句的處理過程 */
while (…) /* 條件說明 */
{ /* 簡單介紹本複合語句的處理過程 */
…
} /* end while (條件說明) */
…
} /* end of if (條件說明) */
【規則2-3】代碼寬度不超過120列;函數體有效長度不超過200行,如果超過需要在函數頭註釋中特別說明原因。 |
【規則2-4】保證代碼和註釋的一致性。修改代碼同時修改相應的註釋,不再有用的註釋要刪除。 |
【規則2-5】在處理變更時,必須在修改代碼的地方註明變更單號和修改者. |
【規則3-1】程序中不要出現僅靠大小寫區分的相似的命名。 |
說明:變量定義:[作用域_][屬性]<變量命名>
[作用域]: [屬性]:
g_ : 全局變量 uc : unsigned char 或 byte
s_ : 靜態變量 c : char
空 : 局部變量 w : 16位無符號數
sw : 16位有符號數
dw : 32位無符號數
sdw : 32位有符號數
qw : 64位無符號數
sqw : 64位有符號數
f : 浮點數;
p : pointer
a : 數組,array of TYPE
str : 字符串
t : 結構類型,枚舉,聯合
以上前綴可以進一步組合,在進行組合時,數組和指針類型的前綴指示符必須放在變量類型前綴的首位。
【規則3-3】結構類型名、聯合類型名、枚舉類型名由後綴 _T 結尾。 |
【規則3-4】程序中局部變量不要與全局變量重名。 |
【規則3-5】儘量避免名字中出現數字編號,如Value1、Value2等,除非邏輯上的確需要編號。 |
【規則4-1】一個變量有且只有一個功能,不能把一個變量用作多種用途。 |
【規則4-2】宏定義中如果包含表達式或變量,表達式和變量必須用小括號括起來。 |
正例:#define HANDLE(A, B) (( A ) / ( B ))
反例:#define HANDLE(A, B) (A / B)
【規則4-3】使用宏定義多行語句時, 必須使用 { } 把這些語句括起來。 |
【規則4-4】實現代碼中不允許使用數值,所有用到的地方必須用宏代替. |
【規則4-5】模塊間接口如果使用簡單類型定義,則必須使用經過統一封裝定義後的BYTE,CHAR, WORD16,SWORD16,WORD32,SWORD32,WORD64,SWORD64等數據類型。在能夠使用自定義數據類型實現的前提下,禁止直接使用C語言提供的原始數據類型,如char,int,long,bool等。 |
說明:BYTE 8位無符號數 WORD16 16位無符號數
CHAR 8位有符號數 SWORD16 16位有符號數
WORD32 32位無符號數 WORD64 64位無符號數
SWORD32 32位有符號數 SWORD64 64位有符號數
【規則5-1】在表達式中使用括號和排版,使表達式的運算順序更清晰。 |
正例:if( ( (dwYear % 4 == 0) && (dwYear % 100 != 0) )
|| (dwYear % 400 == 0) )
【規則5-2】避免表達式中的附加功能,不要編寫太複雜的複合表達式。 |
反例1:
dwResult = (adwVar[1]=adwVar[2]++);/* 附加功能:對adwVar[1]賦值,adwVar[2]自增 */
反例2:
c = (a > b) ? a : b;
【規則5-3】不可將浮點變量用“==”或“!=”與任何數字比較。 |
|
【規則5-4】在switch語句中,每一個case後面如果相應功能實現代碼,分支必須使用break,最後一個分支必須是default分支。 |
反例:
switch( dat->thisState )
{
case EV_MASTER_POWER_ON:
proxyInitialize(&proxyData);
case EV_DRDYNCONFIG_NOTIFY:
mhdOnHsdbSwitchEvent(&dat,req);
break;
default:
break;
}
【規則5-5】不可在for 循環體內修改循環控制變量,防止for 循環失去控制。 |
【規則5-6】進行“==”比較時,將常量或常數放在“==”號的左邊。 |
正例:if (NULL == ptTail)
【規則6-1】本模塊向其它模塊提供的接口函數中,需要對輸入參數的正確性和有效性進行檢查。 |
【規則6-2】禁止改寫函數的入參。 |
【規則6-3】一個函數的參數之和不要超過5個。 |
【規則6-4】無論是函數或者宏函數,在使用過程中,傳遞進來的參數要求是變量或者常量,不要涉及表達式。 |
反例:#define OPERAND(a) ( (a) + (a) )
OPERAND(i++); /* 這條語句在實現中i其實被增加了兩次,增加了潛在的錯誤 */
【規則6-5】必須對所調用函數的錯誤返回值進行處理。 |
【規則6-6】一個函數內定義的局部變量的大小總和不允許超過1K,特殊情況需要說明原因。 |
【規則6-7】非void類型的函數中每個出口分支都要有返回值. |
【規則7-1】對數組、指針、內存地址等的操作,必須注意被操作內存的大小和邊界是否合適,防止內存操作讀取和寫入越界。要求先比較源和目的大小,然後取值小的進行操作。當OSS提供封裝後的內存操作函數後,要求使用封裝的函數。 |
正例:
CHAR acName[NAME_SIZE];
CHAR acOtherName[OTHER_NAME_SIZE];
if(OTHER_NAME_SIZE>NAME_SIZE )
{
memcpy(acName, acOtherName,NAME_SIZE );
}
else
{
memcpy(acName, acOtherName,OTHER_NAME_SIZE );
}
反例:
CHAR acName[NAME_SIZE];
CHAR acOtherName[OTHER_NAME_SIZE];
memcpy(acName, acOtherName,NAME_SIZE );
【規則7-3】不要忘記字符串包含一個終止符號”\0”,而該符號會佔用一個內存空間,但是strlen統計的長度並沒有將之包含在內。 |
【規則7-4】字符串操作要求使用帶長度限制的接口,比如字符串拷貝規定使用strncpy、 strncat等,禁止使用strcpy、 strcat等,字符串格式化使用snprintf或_snprintf,禁止使用sprintf等。 |
【規則8-1】指針類型變量必須初始化(NULL或者其它確定的值)。 |
【規則8-2】如果變量明確不會被修改,應該增加const屬性,以加強編譯器的檢查。 |
【規則8-3】對指針進行算術操作必須有明確註釋。 |
正例: WORD16 *pwMsg = NULL;
……
pwMsg += 5; /* 向前偏移5個元素,共10個字節 */
【規則8-4】禁止對數組名進行算術運算訪問數組元素,規定使用數組名和數組下標(所有維數)訪問數組元素。 |
反例:int aucBuf[10],ucVal;
ucVal = *(aucBuf+1);
正例 :
int aucBuf[10],ucVal;
ucVal= aucBuf[1]
【規則8-5】對指針的操作要求使用括號括起來以明確代碼的語義。 |
反例:
WORD *pwSize=NULL ;
WORD wLen = 0 ;
wLen=*pwSize+1;
正例:
WORD *pwSize=NULL ;
WORD wLen = 0 ;
wLen=*(pwSize+1);
【規則9-1】在編寫代碼之前,應預先設計好程序調試與測試的方法和手段,並設計好各種調測開關及相應測試代碼(如打印函數等)。 |
【規則10-1】整個軟件系統應該採用統一的斷言。不允許直接使用系統提供的assert,只能使用支撐提供的OSS_ASSERT,並且進行錯誤處理。對較複雜的斷言加上明確的註釋。 |