統一、合理、美觀的代碼格式能顯著增強程序的可讀性和可維護性,還可以幫助預防和發現錯誤(問題越早發現代價越小)。因此將培養良好編碼風格的有關規范列于首要位置。
原則1:水平縮進每次1個制表符(tab)
?說明
其他字間填充用空格。
?例子
class Z_AbstractMutex_T
{
public :
Z_AbstractMutex_T (void); // defaault constructor
Virtual ~z_AbstractMutex_T(void); // for destruct derived obj.
virtual int lock (void)=0; // lock interface
virtual int unlock(void)=0; // unlock interface
virtual int trylock (void)=0; // trylocit interface
private : // DISALLOW USE ANYWHERE
Z_AbstractMutex_T (const Z_AbstractMutex_T&); // copy constructor
Z_AbstractMutex_T&operator= (const Z_AbstractMutex_T&); // operator=
};
原則2: 不要在引用操作符前后加空格
?說明
引用操作符指“.”“->”和“[]”。
?例子
foo.bar,pFoo->bar,foo[bar]
原則3: 不要在單目操作符和其操作對象間加空格
?例子
!foo,~foo,++foo,-foo,+foo,*pFoo,&foo,sizeof (foo),(int)foo
原則4: 在“,”“;”之后(而不是之前)加空格
?例子
for (i=0,j=0; i<10; i++,j++)
原則5: 文件中的主要部分用空行分開
原則6: 函數間要用空行分開
?例子
void function1 (void)
{
//...
}
void function2 (void)
{
//…
}
原則7: 局部變量聲明和代碼之間用空行分開
?例子
void myFunction (void)
{
int1;
char c;
for (i=0;i<LENGTH;i++)
//…
}
原則8: 用空行將代碼按邏輯片斷劃分
原則9: 函數返回語句要和其他語句用空行分開
?例子
MyClass_T&
MyC1ass_T::operator= (MyClass_T const&rhs)
{
if (this !=rhs)
{
//…
}
return (*this); // 返回語句之前加一空行
}
?例外
除非該函數過于簡單(比如只有一兩條語句)。
原則10: 每一行不超過80個字符
?說明
因為標準顯示/輸出設備(字符終端、缺省寬度的顯式窗口、打印機等)的寬度都大于等于80個字符,所以每行不超過78個字符可以保證代碼在顯示、編輯、打印等情況下都不會發生因為寬度不夠而折行的現象。
限制為78個是因為行尾還隱含一至二個回車換行符(OxOd或OxOdOa)。
原則11: 當一條語句超過78個字符時按邏輯劃分成不同行
原則12: 花括號{ }要單獨占一行
?說明
并且和其控制語句的縮進相同。有個別例外:
在do-while循環中,“}”要和while在一行。
結構(struct)和聯合Union)結尾緊跟變量定義,要和“}”放在一行。
任何“}”后緊跟分號要放在一行。
?例子
// {}單獨占一行,并且和if /for語句縮進相同
if (clearRequested)
{
for (i=0;I<LENGTH;i++)
{
//…
}
}
else
{
//…
}
// do-while例外
do
{
//…
} while (length-- > 0); // 放在一行
// 結構和聯合的例外
typedef struct
{
//…
} Message; // 放在一行
// 花括號后緊跟分號的情況
class MyClass_T
{
//…
}; // 放在一行
原則13: 花括號中沒有或只有一條語句時也不省略花括號
?例子
// 這種方式表達空循環不夠清楚
for (i=0;i<TIMEOUT;i++);
// 即便是空循環,也保留{},這樣就清楚多了
for (i=0;i<TIME0UT;i++〉
{
}
原則14: 不要在一行中放多于一條語句
?例子
// 兩條語句放在一行
if (buffer.empty()) status=ERROR_EMPTY; //error
// 這樣要清晰一些
if (buffer.empty())
{
status=ERROR_EMPTY;
}
原則15: 語句switch中的每個case各占一行
?例子
switch (debugLevel)
{
// error
case DEBUG_LEVEL_VERBOSE: case DEBUG_LEVELINF0:
//…
break;
default:
//…
}
// 應該這樣
switch (debugLeve1)
{
case DEBUG_LEVEL_VERBOSE:
case DEBUG_LEVEL_INFO:
//…
break;
default:
//…
}
原則16: 為所有switch語句提供default分支
原則17: 若某個case不需要break,一定要加注釋聲明
?說明
但case中沒有執行語句的情況除外。
?例子
switch (ch)
{
case 'a' :
case'A' :
action=Action_T::ABORT;
break;
case 'v' :
case 'v' :
verbosity++;
// Fall through
case 'd' :
//…
break;
default:
//…
}
原則18: 變量定義應集中放置、各占一行。
?說明
C++允許變量定義出現在一個代碼塊(block)的任意位置,但為了方便閱讀和維護,建議還是集中放在代碼塊的開頭。
?例子
// 不好理解每個變量的類型
int*pCount,flexPages,reflexPages;
// 這樣就清楚多了
int flexPages;
int* pCount;
int ref1exPages;
原則19: 定義指針和引用時*和&緊跟類型
?例子
int* pCount;
int& count;
原則20: 按編譯器解析順序旋轉變量聲明的修飾符
?例子
// 兩句話意思完全一樣,但后者更清楚
const char* pName;
char const *pName;
原則21: 關于函數聲明和定義的格式
?說明
函數聲明原則上放在一行。但函數定義(實現)應按下列順序放在多行中:
1)模板描述;
2)修飾符和返回值類型;
3)函數名及其參數,若需要,參數可放在多行中;
4)函數體。
?例子
// 函數聲明
int function (void);
// 函數定義(實現)
template<class KEY_T,class VALUE_T >
void
HA_CheckPointTable_T〈KEY_T,VALUE_T>::myFurlction(
const char*pStoreFileName,
size_t tablesize,
size_t syncInterval,
float perfomanceCoeff
)
{
//…
}
原則22: 函數名和左括號間不要空格
?例子
int function(int argument);
原則23: 關于字符常量
?例子
char c= 'x'; // 盡量不要用0x78、0170或120
if (c=='\b') // 用定義好的標識符號,而不是直接用值
原則24: 關于換行
?例子
someMethod(longException1, longException2, longException3,
longException4, longException5)
omeMethod1(longException1, someMethod2(longException2,
longException3))
原則25: 左括號和后一個字符之間不應該出現空格, 同樣, 右括號和前一個字符之間也不應該出現空格。
?例子
CallProc( AParameter ); // 錯誤
CallProc(AParameter); // 正確
原則26:不要在語句中使用無意義的括號. 括號只應該為達到某種目的而出現在源代碼中。
?例子
if ((I) = 42) { // 錯誤 - 括號毫無意義
if (I == 42) or (J == 42) then // 正確 - 的確需要括號
原則27: 初始化。盡量在申明局部變量的同時初始化。
?例子
int count = 0;
原則28: 所有的二元運算符,除了“.”,應該使用空格將之與操作數分開
?例子
a += c + d;
a = (a + b) / (c * d);
while (d++ = s++)
{
n++;
}
原則29: for語句中的表達式應該被空格分開
?例子
for (expr1; expr2; expr3);
原則30: 強制轉型后應該跟一個空格
?例子
myMethod((int) aNum, (int*) x);
原則31: final 類。絕對不要因為性能的原因將類定義為 final 的(除非程序的框架要求)如果一個類還沒有準備好被繼承,最好在類文檔中注明,而不要將她定義為 final 的。這是因為沒有人可以保證會不會由于什么原因需要繼承它。
- 第一章 概述
- 1.1規范制定原則
- 1.2 術語定義
- 1.3 文件命名組織
- 1.3.1文件命名
- 1.3.2文件注釋
- 第二章 編碼風格
- 第三章 注釋
- 3.1 注釋概述
- 3.2 文檔型注釋
- 3.3 類c注釋
- 3.4 單行注釋
- 3.5 注釋標簽
- 第四章 聲明
- 4.1每行聲明數
- 4.2初始化
- 4.3位置
- 4.4類和接口的聲明
- 4.5字段的聲明
- 第五章 命名規范
- 5.1命名概述
- 5.2大小寫規則
- 5.3縮寫
- 5.4命名空間
- 5.5類
- 5.6接口
- 5.7屬性 (Attribute)
- 5.8枚舉 (Enum)
- 5.9參數
- 5.10方法
- 5.11屬性 (property)
- 5.12事件
- 5.13 常量 (const)
- 5.14 字段
- 5.15 靜態字段
- 5.16 集合
- 5.17 措詞
- 第六章 語句
- 6.1每行一個語句
- 6.2 復合語句
- 6.3 return 語句
- 6.4 if、 if-else、if else-if 語句
- 6.5 for、foreach 語句
- 6.6 while 語句
- 6.7 do - while 語句
- 6.8 switch - case 語句
- 6.9 try - catch 語句
- 6.10 using 塊語句
- 6.11 goto 語句
- 第七章 函數與類
- 第八章 內存分配和釋放
- 第九章 兼容性
- 第十章 控件命名規則
- 10.1 命名方法
- 10.2 主要控件名簡寫對照表
- 附錄一: 匈牙利命名法