不同功能函式內部實作各異,但可在函式體「入口」與「出口」嚴把關,提升品質。
許多錯誤源於非法參數。善用斷言防範。詳見 6.5 節。
有回傳值的函式,「出口」即 return。切勿輕視:
char* Func() {
char str[] = "hello world"; // 位於堆疊
return str; // 錯誤!
}
// 臨時物件語法:編譯器直接在外部儲存單元建構並初始化,省去複製與解構
return String(s1 + s2);
// 等價寫法但效率較低:
String temp(s1 + s2);
return temp; // 發生三事:1.建構temp 2.複製建構到外部儲存 3.temp解構
內建型別同理:return int(x+y); 優於 int t=x+y; return t;,雖效率差異微小但程式碼更簡潔。
static 區域變數是函式的「記憶體」,盡量少用除非必要。程式分 Debug(內部測試)與 Release(發行用戶)版本。assert 是僅在 Debug 版本生效的巨集,用於檢查「不應該」發生的情況。
void* memcpy(void* pvTo, const void* pvFrom, size_t size) {
assert((pvTo != NULL) && (pvFrom != NULL)); // 使用斷言
byte* pbTo = (byte*)pvTo;
byte* pbFrom = (byte*)pvFrom;
while (size-- > 0) *pbTo++ = *pbFrom++;
return pvTo;
}
若 assert 條件為假,程式中止(通常彈出對話框指示位置)。
assert **不應產生任何副作用** → 實作為巨集而非函式。assert 處終止,不代表含該 assert 的函式有錯,而是**呼叫者出錯**;assert 幫助定位錯誤源頭。追蹤到 assert 卻不知其意圖極令人沮喪。解決方法簡單:**加上清晰註解**說明檢查什麼、為什麼檢查。這本是顯而易見的道理,卻常被忽略。