每行只應(yīng)該有一條語句城丧,除非多條語句關(guān)聯(lián)特別緊密。
case FOO: oogle (zork); boogle (zork); break;
case BAR: oogle (bork); boogle (zork); break;
case BAZ: oogle (gork); boogle (bork); break;
for或while循環(huán)語句的空體應(yīng)該單獨(dú)放在一行并加上注釋,這樣可以清晰的看出空體是有意而為概作,并非遺漏代碼。
while (*dest++ = *src++)
; /* VOID */
不要對(duì)非零表達(dá)式進(jìn)行默認(rèn)測試默怨,例如:
if (f() != FAIL)
比下面的代碼更好
if (f())
即使FAIL的值可能為0(在C中0被認(rèn)為是假)讯榕。當(dāng)后續(xù)有人決定使用-1替代0作為失敗返回值時(shí),一個(gè)顯式的測試將解決你的問題匙睹。即使比較的值永遠(yuǎn)不會(huì)改變愚屁,我們也應(yīng)該使用顯式的比較;例如
if (!(bufsize % sizeof(int)))
應(yīng)該被寫成
if ((bufsize % sizeof(int)) == 0)
這樣可以反映這個(gè)測試的數(shù)值(非布爾)本質(zhì)痕檬。一個(gè)常見的錯(cuò)誤點(diǎn)是使用strcmp測試字符串是否相同霎槐,這個(gè)測試的結(jié)果永遠(yuǎn)不應(yīng)該被放棄。比較好的方法是定義一個(gè)宏STREQ梦谜。
#define STREQ(a, b) (strcmp((a), (b)) == 0)
對(duì)謂詞或滿足下面約束的表達(dá)式丘跌,非零測試經(jīng)常被放棄:
0表示假,其他都為真唁桩。
通過其命名可以看出返回真是顯而易見的闭树。
用isvalid或valid稱呼一個(gè)謂詞,不要用checkvalid荒澡。
一個(gè)非常常見的實(shí)踐就是在一個(gè)全局頭文件中聲明一個(gè)布爾類型"bool"报辱。這個(gè)特殊的名字可以極大地提高代碼可讀性。
typedef int bool;
#define FALSE 0
#define TRUE 1
或
typedef enum { NO=0, YES } bool;
即便有了這些聲明单山,也不要檢查一個(gè)布爾值與1(TRUE碍现,YES等)的相當(dāng)性;可用測試與0(FALSE米奸,NO等)的不等性替代昼接。絕大多數(shù)函數(shù)都可以保證為假的時(shí)候返回0,但為真的時(shí)候只返回非零悴晰。
if (func() == TRUE) { ...
必須被寫成
if (func() != FALSE) { ...
如果可能的話辩棒,最好為函數(shù)/變量重命名或者重寫這個(gè)表達(dá)式,這樣就可以顯而易見的知道其含義,而無需再與true或false比較了(例如一睁,重命名為isvalid())钻弄。
嵌入賦值語句也有用武之地。在一些結(jié)構(gòu)中者吁,在沒有降低代碼可讀性的前提下窘俺,沒有比這更好的方式來實(shí)現(xiàn)這個(gè)結(jié)果了。
while ((c = getchar()) != EOF) {
process the character
}
++和--操作符可算作是賦值語句复凳。這樣瘤泪,為了某些意圖,實(shí)現(xiàn)帶有副作用的功能育八。使用嵌入賦值語句也可能提高運(yùn)行時(shí)的性能对途。不過,大家應(yīng)該在提高的性能與下降的可維護(hù)性之間做好權(quán)衡髓棋。當(dāng)在一些人為的地方使用嵌入賦值語句時(shí)实檀,這種情況會(huì)發(fā)生,例如:
a = b + c;
d = a + r;
不應(yīng)該被下面代碼替代:
d = (a = b + c) + r;
即使后者可能節(jié)省一個(gè)計(jì)算周期按声。在長期運(yùn)行時(shí)膳犹,由于優(yōu)化器漸獲成熟,兩者的運(yùn)行時(shí)間差距將下降签则,而兩者在維護(hù)性方面的差異將提高须床,因?yàn)槿祟惖挠洃洉?huì)隨著時(shí)間的流逝而衰退。
在任何結(jié)構(gòu)良好的代碼中渐裂,goto語句都應(yīng)該保守地使用豺旬。使用goto帶來好處最大的地方是從switch、for和while多層嵌套中跳出柒凉,但這樣做的需求也暗示了代碼的內(nèi)層結(jié)構(gòu)應(yīng)該被抽取出來放到一個(gè)單獨(dú)的返回值為成功或失敗的函數(shù)中哈垢。
for (...) {
while (...) {
...
if (disaster)
goto error;
}
}
...
error:
clean up the mess
當(dāng)需要goto時(shí)候,其對(duì)應(yīng)的標(biāo)簽應(yīng)該被放在單獨(dú)一行扛拨,并且后續(xù)的代碼縮進(jìn)一級(jí)。使用goto語句時(shí)應(yīng)該增加注釋(可能放在代碼塊的頭)以說明它的功用和目的举塔。continue應(yīng)該保守地使用绑警,并且盡可能靠近循環(huán)的頂部。Break的麻煩比較少央渣。
非原型函數(shù)的參數(shù)有時(shí)需要被顯式做類型提升计盒。例如,如果函數(shù)期望一個(gè)32bit的長整型芽丹,但卻被傳入一個(gè)16bit的整型數(shù)北启,可能會(huì)導(dǎo)致函數(shù)棧不對(duì)齊。指針,整型和浮點(diǎn)值都會(huì)發(fā)生此問題咕村。