if/for/while/goto/switch 看似簡單,但許多程式設計師以隱含錯誤的方式撰寫。本章歸納正確使用規則與建議。
C/C++ 運算子數十個,優先序難記。規則 4-1-1:運算子較多時,用括號明確指定運算順序,避免仰賴預設優先序。
word = (high << 8) | low;
if ((a | b) && (a & c)) ...
如 a = b = c = 0。允許存在的理由:書寫簡潔、可提高編譯效率。但須防止濫用:
d = (a = b + c) + r 應拆為兩句)。if (a < b < c) 在 C/C++ 中意為 if ((a,非數學意義的 a。if 是最簡單也最常用的語句,但錯誤寫法層出不窮。以「與零值比較」為例:
規則 4-3-1:不可將布林變數直接與 TRUE/FALSE/1/0 比較。標準寫法:
if (flag) // flag 為真
if (!flag) // flag 為假
// 以下皆為不良風格
if (flag == TRUE) if (flag == 1) if (flag == FALSE) if (flag == 0)
原因:TRUE 定義無統一標準(VC++ 為 1,VB 為 -1)。
規則 4-3-2:應用 ==/!= 顯式與 0 比較。
if (value == 0) if (value != 0)
// 以下易讓人誤解為布林變數
if (value) if (!value)
規則 4-3-3:不可用 ==/!= 與任何數字比較。因精度限制,應轉換為 >= 或 <= 形式:
// 錯誤
if (x == 0.0)
// 正確
if ((x >= -EPSILON) && (x <= EPSILON))
規則 4-3-4:應用 ==/!= 與 NULL 比較。雖 NULL 值同 0,但語意不同:
if (p == NULL) if (p != NULL) // 強調 p 為指標
// 以下易誤解
if (p == 0) if (p) if (!p)
= 為 ==:寫成 if (NULL == p),若誤寫 if (NULL = p) 編譯器會報錯(NULL 不可被指派)。// 不良
if (condition) return x;
return y;
// 良好
if (condition) { return x; } else { return y; }
// 或更簡潔
return (condition ? x : y);
// 低效:長迴圈在外層
for (row=0; row<100; row++)
for (col=0; col<5; col++) sum += a[row][col];
// 高效:長迴圈在內層
for (col=0; col<5; col++)
for (row=0; row<100; row++) sum += a[row][col];
[0, N) 寫法:for (int x=0; x。比閉區間 [0, N-1] 更直觀,間隔即迴圈次數。 多分支選擇,優於巢狀 if。基本格式:
switch (variable) {
case value1: ... break;
case value2: ... break;
default: ... break; // 規則 4-6-2:即使不需處理也保留,防止他人誤以為遺忘
}
case 結尾別忘 break,除非有意讓多案例貫通。結構化程式設計下 goto 有爭議,但非絕對禁用:
break。{ ... { ... { ... goto error; } } }
error: ...
如樓房著火,不走樓梯改跳窗逃生。主張少用、慎用,而非禁用。