核心哲學:可讀性第一,機靈第二
優秀的程式碼不是炫技的舞台,而是給人看的文檔。本規範蒐羅業界最佳實踐,涵蓋結構、命名、註解、錯誤處理與重用五大維度,助你寫出經得起時間考驗的專業級代碼。
一、 基本架構要求
- 單一職責:單一函數不超過 100 行,做一件事並做好。
- 拒絕垃圾碼:邏輯直白,無冗餘判斷、無死代碼、無魔術數字。
- 善用標準庫:不要重複造輪子,
STL、Boost、平台 SDK 才是生產力。
- 局部化變數:全域變數是萬惡之源,儘量縮小作用域,降低耦合。
- 括號消除歧義:複雜表達式務必加括號,別賭運算子優先序。
二、 可讀性鐵律
| 規則 | 說明 |
| 註解同步率 100% | 代碼改了,註解必須跟著改;過期註解比無註解更害人。 |
| 檔案頭/函數頭強制 | 每個檔案、每個函數須有標準化說明區塊(作者、日期、用途、參數、回傳值、修改記錄)。 |
| 關鍵變數必註解 | 結構體、類別、重要物件定義處須說明語意。 |
| 常數不可裸露 | #define MAX_RETRY 3 後必接單行註解說明用途。 |
| 階段性區塊註解 | 演算法前、複雜邏輯分支前、關鍵流程轉折點必加區塊註解。 |
| 縮進統一用 Tab | Tab 寬度定為 6 個位元組(或團隊約定 4 空格),嚴禁混用。 |
| 巢狀深度 ≤ 5 層 | 超過即重構:提煉函數、衛語句、狀態機、策略模式。 |
| 註解密度 20%~33% | 非檔案頭/函數頭的程式碼行數中,註解行佔比須達 1/5 到 1/3。 |
三、 結構化程式設計鐵則
- 禁用 GOTO:結構化控制流(if/else、switch、while/for)足以表達所有邏輯。
- 單一入口、單一出口:函數僅有一個
return;迴圈僅有一個出口,避免多重 break/continue 散落。
- 多路分支用 Switch:超過 3 個
else if 即改 switch 或查表法。
- 邏輯表達式優於條件分支:
if (a && b) return true; else return false; → return a && b;
- 拒絕條件賦值:
if (x = y) 易誤寫成 ==,分開寫。
四、 正確性與容錯防禦
- 先正確,後優美:功能驗證通過前,不討論效能優化。
- 自我審查機制:寫完代碼先自己走一遍邏輯,再提交測試。
- 修改影響分析:改 Bug 前先評估副作用,單元測試要全跑。
- 變數初始化零容忍:宣告即賦值,未初始化變數是定時炸彈。
- 所有輸入必驗證:使用者輸入、檔案讀取、網路封包、API 回傳值——統統檢查合法性。
- 浮點數不比較相等:用
fabs(a - b) < EPSILON 判斷近似相等。
- 環境依賴主動防禦:檔案鎖定、印表機在線、磁碟空間、網路連線——假設會失敗,寫好 fallback。
- 單元測試是開發一部分:未通過單測的代碼不得進入整合測試。
五、 可重用與模組化設計
- 抽象獨立功能:重複邏輯封裝為公共元件/類別,介面乾淨、職責單一。
- 封裝與低耦合:公開最小介面,內部實作細節隱藏,減少外部依賴。
- 提供使用範本:公共元件附帶範例代碼、單元測試、文檔,降低接手成本。
附錄:C++/Delphi 命名規範速查表
變數前綴(匈牙利改良版)
| 類型 | 前綴 | 範例 |
| Boolean | b | bEnable |
| char / TCHAR | ch / sz | chText, szAppName[10] |
| Class 物件 | c | cMain |
| Handle | h | hWnd, hDC, hInstance |
| int | i / n | iTmp, nCmdShow |
| 指標 | p / lp | pData, lpCmdLine |
| 字串 | str / psz | strName, pszTip |
| WORD/DWORD | w / dw | wParam, dwStart |
| 長整數 | l | lParam |
| 無符號整數 | u | uNotify |
| 浮點數 | f | fTmp |
| 類別成員 | m_ | m_nVal, m_bFlag |
| 全域變數 | g_ | g_nMsg, g_bFlag |
| 迴圈暫存 | i, j, nTemp, nResult | 慣用慣例 |
常數與巨集命名
- 全大寫 + 底線分隔:
MAX_BUFFER_SIZE、WM_USER_LOGIN
- 資源 ID 規範:選單
IDM_、位圖 IDB_、對話框 IDD_、字串 IDS_、圖示 IDR_
- 定義於
#include 之後、函數定義之前,每行必加單行註解。
函數命名
- PascalCase:
UpdateDatabase()、PrintTrackData()
- 必要時底線分隔模組:
UpdateDB_Tfgd()
- 原型宣告必註明來源模組/檔案:
// Module: r01/sdw.c
結構體命名
- 型別全大寫 + 前導底線:
_DBS_DATABASE
- 變數 PascalCase:
GdataBase
控制項前綴(表單設計)
| 控制項 | 前綴 | 範例 |
| Form/視窗 | fm / W | fmMain, WAbout |
| Button | cmd / btn | cmdOK, btnExit |
| ComboBox | cob | cobCity |
| Edit/輸入框 | txt | txtUserName |
| Label | lab | labTitle |
| Image/Picture | img / pic | imgLogo, picPhoto |
| Grid | grd | grdDataList |
| ListBox | lst | lstFiles |
註解模板標準化
檔案頭
/****************************************************************
** 檔案名:
** Copyright (c) 2024 公司名稱 技術部
** 建立人: 日期:
** 修改人: 日期:
** 描述:
** 版本:
****************************************************************/
函數頭
/****************************************************************
** 函數名:
** 輸入: 參數1---說明; 參數2---說明
** 輸出: 回傳值說明 (0: 成功, -1: 失敗)
** 功能描述:
** 全域變數:
** 呼叫模組:
** 作者: 日期:
** 修改: 日期:
** 版本:
****************************************************************/
區塊註解
/*----------------------------------------------------------*/
/* 區塊功能說明 */
/*----------------------------------------------------------*/
程式碼撰寫細節
- 大括號對齊:
{ 與 } 同欄,巢狀每層縮進一 Tab(4 空格)。
- 每行單一陳述:嚴禁一行寫多條指令。
- 關鍵呼叫必註解:硬體存取、系統 API、複雜演算法行末加單行註解說明用途。
- 版本控管紀律:修改舊代碼用
/* ... */ 封存,檔案頭與函數頭同步更新修改記錄,嚴禁直接刪除。
- 避免遞迴:除非資料結構天然遞迴(樹、圖),否則改迭代,防止堆疊溢位。
- 測試先行:寫代碼前先想測試案例,單元測試方案與產品代碼同步產出。
結語
規範不是枷鎖,而是團隊溝通的共同語言。嚴格遵循上述準則,能讓代碼庫保持整潔、可維護、可延伸,最終降低系統全生命週期成本。將此文列為專案《編碼標準》附件,代碼審查時以此為準則,久而久之,良好習慣將內化為肌肉記憶。
- 上一篇文章: 從 DOS 到 Windows:磁碟磁區讀寫與格式化的底層實作演進
- 下一篇文章: JavaScript/VBScript 陣列傳遞給 COM 元件的差異與實作全解析
Copyright ©
程式碼之家 All Rights Reserved