通用函數:可在多種情境、多位開發者專案中重複使用的函數。
核心原則:不建立在全域變數上。函數所需所有資料應透過參數傳遞(極少數情況可用 static 區域變數)。
絕大多數應用中,這些微小開銷可忽略不計,模組化效益遠大於效能損失。
唯一條件:執行速度極為關鍵的場合(如即時系統核心迴圈、高頻訊號處理、嵌入式中斷服務常式)。
函數主體不包含函數呼叫敘述,邏輯直接內嵌於呼叫點。透過:
inline 關鍵字建議(C99)#define 展開
int square(int x) { return x * x; }
void print_squares_func() {
for (int i = 1; i <= 10; i++)
printf("%d ", square(i)); // 每次迴圈呼叫函數
}
void print_squares_inline() {
for (int i = 1; i <= 10; i++)
printf("%d ", i * i); // 直接運算,無呼叫開銷
}
結果:內聯版本執行較快(省去 10 次函數呼叫開銷)。但代碼重複、維護困難,僅用於極度效能敏感路徑。
-O2/-O3)時,編譯器會自動內聯簡短函數inline 關鍵字僅為建議,編譯器可選擇忽略實務建議:優先寫清晰的函數,開啟編譯器最佳化。僅在分析器確認熱點且函數極小時,考慮手動 inline 或巨集。過早最佳化是萬惡之源。
| 原則 | 檢核項目 | 違反後果 |
|---|---|---|
| 單一職責 | 函數只做一件事 | 難以複用、測試、理解 |
| 參數化 | 無全域變數依賴 | 耦合度高、副作用難控 |
| 介面清晰 | 參數/返回值型態明確、命名語意化 | 誤用、文件成本高 |
| 錯誤處理 | 返回狀態碼或設定 errno | 失敗靜默、除錯困難 |
| 副作用最小 | 避免修改非必要外部狀態 | 並發風險、推理困難 |
| 適度內聯 | 僅熱點小函數使用 inline | 代碼膨脹、指令快取失效 |