C 語法允許任意空白,但可讀性、可維護性、團隊協作高度依賴一致風格。Linux Kernel、Google、GNU 各有風格指南,核心原則相通。
| 場景 | 規範 | 範例 |
|---|---|---|
| 關鍵字與括號 | 間隔一空格 | if (cond)、while (1) |
| 雙目運算子 | 兩側各一空格 | a = b + c、x == y |
| 單目運算子 | 緊貼運算元 | ++i、!flag、&var |
| 後綴運算子 | 緊貼運算元 | arr[i]、func(arg)、ptr->member |
| 逗號、分號後 | 加一空格 | for (i=0; i<n; i++)、func(a, b) |
| 長行折行 | 80 欄內,續行對齊 | 運算子置行首、參數對齊 |
/* K&R 風格(Linux Kernel、本指南推薦) */
if (cond) {
do_something();
} else if (other) {
do_other();
}
/* Allman 風格(Visual Studio 預設、部分企業) */
if (cond)
{
do_something();
}
else
{
do_other();
}
K&R 省螢幕行數,Allman 視覺對齊清晰。專案內統一即可,切勿混用。
int foo(int a, int b)
{ // 左大括號獨佔一行
...
}
與控制陳述式不同,函數定義左大括號獨立一行,便於 grep ^func_name 定位。
switch (c) {
case 'A':
do_a();
break;
case 'B':
do_b();
break;
default:
do_default();
}
case 標籤與 switch 同層,內部陳述式再縮進。
int a, b;
double c;
char * str;
以 Tab 對齊類型與變數名,提升掃視效率。
| 類別 | 慣例 | 範例 |
|---|---|---|
| 巨集/常數 | 全大寫底線 | MAX_SIZE |
| 函數/變數 | 小寫底線 | get_user_name |
| 結構/型別 | PascalCase 或 _t 結尾 | Node、file_t |
| 靜態/內部 | 前綴 _ 或 模組名_ | _internal_helper |
clang-format:LLVM/Google/Kernel 風格一鍵格式化uncrustify:高度可配置「風格無絕對優劣,一致性才是王道。」