5年程序員精心總結——一起聊一下關於C語言的代碼風格

今天我們來聊輕鬆些的話題——C語言代碼風格。

7.1 什麼是 C 最好的代碼佈局風格?

17.2 用 if(!strcmp(s1, s2)) 比較兩個字符串等值,是否是個好風格?

17.3 為什麼有的人用 if (0 == x) 而不是 if (x == 0)?

17.4 原型說明 extern int func ((int, int)); 中, 那些多出來的括號和下 劃線代表了什麼?

17.5 為什麼有些代碼在每次調用 printf() 前, 加了類型轉換 (void)?

17.6 什麼是 “匈牙利標誌法” (Hungarian Notation)?是否值得用?

17.7 哪裡可以找到 “印第安山風格指南” (Indian Hill Style Guide) 及 其它編碼標準?


17.1 什麼是 C 最好的代碼佈局風格?

K&R 提供了最常被抄襲的實例, 同時他並不要求大家沿用他的風格:

大括號的位置並不重要, 儘管人們對此有著執著的熱情。我們在幾種流行的風格中選了一種。選一個適合你的風格, 然後堅持使用這一風格。

保持佈局風格對自己, 對鄰近及通用源代碼的一致比使之完美跟重要。如果你的編碼環境 (本地習慣或公司政策) 沒有建議一個風格, 你也不想發明自己的風格, 可以沿用 K&R 中的風格。各種縮進和大括號的放置之間的好與壞可以詳盡而細緻地探討, 但本文不再次重複了。可以參見《印第安山風格指南》(Indian HillStyle Guide), 問題 17.7。

“好風格” 的品質並不簡單, 它包含的內容遠遠不止代碼的佈局細節。不要把時間都花在格式上而忽略了更實質性的代碼本身的質量。


17.2 用 if(!strcmp(s1, s2)) 比較兩個字符串等值,是否是個好風格?

這並不是個很好的風格, 雖然這是個流行的習慣用法。如果兩個字符串相等,

這個測試返回為真, 但 ! (“非”) 的使用, 容易引起誤會, 以為測試不等值情況。

另一個選擇是用一個宏:

#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)

參見問題 17.8。

17.3 為什麼有的人用 if (0 == x) 而不是 if (x == 0)?

這是用來防護一個通常錯誤的小技巧:

if (x = 0)

如果你養成了把常量放在 == 前面的習慣, 當你意外的把代碼寫成了:

if (0 = x)

那編譯器就會報怨。明顯的, 一些人會覺得記住反換測試比記住輸入雙 = 號容易。當然這個技巧只對和常量比較的情況有用。


17.4 原型說明 extern int func ((int, int)); 中, 那些多出來的括號和下劃線代表了什麼?

這是為了可以在使用 ANSI 以前的編譯器時, 關掉說明中的原型部分。這是技巧的一部分。

在別的地方, 宏被定義為類似下面的代碼:

#ifdef __STDC__

#define __(proto) proto

#else

#define __(proto) ()

#endif

原型說明中額外的括號是為了讓原型列表被當作宏的單一參數。


17.5 為什麼有些代碼在每次調用 printf() 前, 加了類型轉換 (void)

printf() 確實返回一個值, 雖然極少數程序員去檢驗每次調用的返回值。由於有些編譯器和 lint 對於被丟棄的返回值會報警告, 清楚的用 (void) 作類型轉換相當於說: “我決定忽略這次調用的返回值, 請繼續對於其他忽略返回值的情況 (也許是不應該的) 提出警告。” 通常, 無值類型轉換也用於 strcpy() 和 strcat() 的調用,他們的返回值從不會令人驚訝。


17.6 什麼是 “匈牙利標誌法” (Hungarian Notation)?是否值得用?

匈牙利標誌法是一種命名約定, 由 Charles Simonyi 發明。他把變量的類型(或者它的預期使用) 等信息編碼在變量名中。在某些圈子裡, 它被高度熱愛, 而在另一些地方, 它被嚴厲地批評。它的主要優勢在於變量名就說明了它的類型或者使用。它的主要缺點在於類型信息並不值得放在變量名中。


17.7 哪裡可以找到 “印第安山風格指南” (Indian Hill Style Guide) 及其它編碼標準?


5年程序員精心總結——一起聊一下關於C語言的代碼風格


17.8 有些人說 goto 是邪惡的, 我應該永不用它。那是否太極端了?

程序設計風格, 就象寫作風格一樣, 是某種程度的藝術, 不可以被僵化的教條所束縛。雖然風格的探討經常都是圍繞著這些條例。

對於 goto 語句, 很早以前, 就被注意到, 隨意的使用 goto 會很快的導致象麵糊一樣難以維護的代碼。然而, 不經思考就簡單的禁止 goto 的使用, 並不能立即導至好程序。一個無規劃的程序員可以不用任何 goto 語句而構造出複雜難解的代碼, 也許使用奇怪的嵌套循環和布爾變量來取代 goto。

通常, 把這些程序設計風格的評論或者 “條例” 當作指導準則比當作條例要更好。當程序員理解這些指導準則所要實現的目標, 就會工作的更加之好。盲目的迴避某種構造或者死套條例而不融會貫通, 最終還會導致這些條例試圖避免的問題。

此外, 許多程序設計風格的意見只是意見。通常捲入 “風格戰爭” 是毫無意義的。某些問題 (象問題 5.3, 5.7, 9.2 和 10.5), 爭辯的雙方是不可能同意, 認同對方的不同或者是停止爭論的。


分享到:


相關文章: