C89/C90 標準定義 32 個關鍵字(C99 增加 5 個,C11 增加 7 個),本文針對**經典 32 個**進行**語義分類、核心用法、典型場景、易混淆點**四維速查,適合面試複習、代碼閱讀、教學參考。
按語義分類總覽
| 類別 | 關鍵字 | 數量 |
| 數據類型 | char, short, int, long, float, double, signed, unsigned, void | 9 |
| 類型構造 | struct, union, enum, typedef | 4 |
| 存儲類別 | auto, register, static, extern, const, volatile | 6 |
| 控制流 | if, else, switch, case, default, for, do, while, goto, continue, break, return | 12 |
| 其他 | sizeof | 1 |
合計 32 個。C99 新增:_Bool, _Complex, _Imaginary, inline, restrict;C11 新增:_Alignas, _Alignof, _Atomic, _Generic, _Noreturn, _Static_assert, _Thread_local。
逐詞速查卡片
數據類型(9)
| 關鍵字 | 含義 | 典型用法 | 注意點 |
char | 字符/最小整數 | `char c='A';` `char buf[1024];` | 是否有符號由實現定義,用 `signed char`/`unsigned char` 明確 |
short | 短整數(≥16位) | `short port = 8080;` | `%hd` 打印 |
int | 整數(自然字長) | `int count = 0;` | 最常用,循環變量首選 |
long | 長整數(≥32位) | `long ts = time(NULL);` | `%ld`;64位 Linux `long` 64位,Windows 32位 |
float | 單精度浮點(32位) | `float pi = 3.14f;` | 后綴 `f`,7 位有效數字 |
double | 雙精度浮點(64位) | `double pi = 3.1415926535;` | 默認浮點字面量類型,15 位有效數字 |
signed | 有符號修飾 | `signed char c = -128;` | `int` 默認有符號,可省略 |
unsigned | 無符號修飾 | `unsigned int u = 4000000000u;` | 后綴 `u`,配合 `long` 用 `ul`/`lu` |
void | 無類型/無返回值 | `void func();` `void *p = malloc(10);` | 不可定義 `void` 變量,指針可轉換 |
類型構造(4)
| 關鍵字 | 含義 | 典型用法 | 注意點 |
struct | 結構體,聚合異構數據 | `struct Pt {int x,y;};` | 成員內存連續,對齊導致填充 |
union | 聯合體,共享內存 | `union U {int i; float f;};` | 大小=最大成員,同一時刻只有一個活躍值 |
enum | 枚舉,命名整數常量 | `enum Color {RED, GREEN, BLUE};` | 默認從 0 遞增,可指定值,本質是 `int` |
typedef | 類型別名 | `typedef uint32_t u32;` | 不創建新類型,僅別名;指針別名慎用 |
存儲類別(6)
| 關鍵字 | 含義 | 典型用法 | 注意點 |
auto | 自動存儲(默認) | `auto int a=1;` ≡ `int a=1;` | 極少顯式使用,C++11 賦予新意(類型推導) |
register | 建議寄存器分配 | `register int i;` | 現代編譯器自動優化,不可取地址 `&i` |
static | 靜態存儲/內部鏈接 | `static int cnt;` `static void helper();` | 函數內保持值,文件級限制作用域,生命周期=程序 |
extern | 外部鏈接聲明 | `extern int g_val;` `extern void foo();` | 僅聲明不定義,跨文件共享全局變量/函數 |
const | 只讀/常量化 | `const int MAX=100;` `const int *p;` | 指針 `const` 位置決定修飾對象:`*p` vs `p` |
volatile | 易變/禁止優化 | `volatile int *reg = (int*)0x4000;` | 硬件寄存器、信號處理、多線程共享變量 |
控制流(12)
| 關鍵字 | 含義 | 典型用法 | 注意點 |
if | 條件分支 | `if (a>0) ... else ...` | 條件為標量,非零為真 |
else | 否定分支 | 見上 | 與最近的無 `else` 的 `if` 配對 |
switch | 多分支開關 | `switch(x) { case 1: ... default: ... }` | 表達式必為整數類型,`case` 必為常量 |
case | 分支標籤 | 見上 | 貫穿特性需 `break` |
default | 默認分支 | 見上 | 可放任意位置,建議最後 |
for | 計數循環 | `for(init; cond; inc) body` | 三部分均可為空,`cond` 缺省恆真 |
do | 循環體 | `do body while(cond);` | 至少執行一次 |
while | 條件循環 | `while(cond) body` | 先判後執 |
goto | 無條件跳轉 | `goto label; ... label: ;` | 僅用於錯誤處理跳出多層循環,慎用 |
continue | 跳過本輪 | `for(...) if(skip) continue;` | 跳至 `inc`/`cond`,`for` 仍執行 `inc` |
break | 跳出循環/switch | `while(1) if(done) break;` | 僅跳出最近一層 |
return | 函數返回 | `return val;` `return;` | `void` 函數可省略值 |
其他(1)
| 關鍵字 | 含義 | 典型用法 | 注意點 |
sizeof | 編譯期計算類型/表達式大小(字節) | `sizeof(int)` `sizeof arr` `sizeof a+b` | **運算符而非函數**,參數為類型需括號,表達式不求值 |
高頻易混淆組對比
| 組 | 區別 |
const int *p vs int *const p | 前者:指向常量的指針(`*p` 不可改);後者:常量指針(`p` 不可改) |
static (函數內) vs static (文件級) | 前者:靜態存儲期+無鏈接;後者:靜態存儲期+內部鏈接 |
typedef vs #define | 前者:編譯器類型系統參與,語義檢查;後者:預處理器文本替換,無類型語義 |
struct vs union | 前者:成員共存,大小≥成員和;後者:成員互斥,大小=最大成員 |
break vs continue | 前者:跳出整個循環/switch;後者:跳過本輪剩餘,進入下一輪判斷 |
面試必考三連問
- 「`const` 和 `volatile` 能否同時用?」 能。`const volatile int *port`:只讀硬件寄存器,編譯器不優化讀取,代碼不修改。
- 「`sizeof` 何時運行?」 編譯期(參數為類型/非 VLA 表達式);運行期(C99 VLA 類型)。
- 「`register` 變量能否取地址?」 不能,`®_var` 編譯錯誤,這是語言規定而非編譯器限制。
32 個關鍵字,構建了 C 語言的**完整表達能力邊界**。熟練掌握它們的語義、交互與陷阱,是寫出正確、高效、可維護 C 代碼的基石。