typedef 現有類型 新類型名;
// 類比:像變數聲明,但前面加 typedef,變數名變成類型別名
慣例:自定義類型名**全大寫** 或 **`_t` 後綴** (如 `uint32_t`, `size_t`),區分標準類型。
// 標準整數類型 即大量使用此機制
typedef unsigned long UINT32; // 明確 32 位無符號
typedef signed short INT16; // 明確 16 位有符號
typedef float REAL32; // 領域特定命名
UINT32 reg_val = 0xFFFFFFFF;
INT16 sensor_data = -32768;
跨平台時,只需修改 `typedef` 所在頭檔,業務代碼零修改。
// 傳統寫法:需寫 struct Node
struct Node { int data; struct Node *next; };
struct Node n1; // 變數聲明必須帶 struct
// typedef 合併寫法 (推薦)
typedef struct Node {
int data;
struct Node *next; // 內部引用仍用標籤
} Node; // 類型名 Node
Node n2; // 直接使用,無需 struct
Node *head = NULL;
匿名結構體:`typedef struct { ... } TypeName;` (無標籤),僅能用 `TypeName` 參考,無法自我引用 (遞迴結構需標籤)。
typedef int *IntPtr; // 整數指針類型
typedef char *String; // 字串指針 (慣例:非 const 字串)
IntPtr p = malloc(sizeof(int));
String s = "Hello";
// 注意:const String s -> char *const s (常量指針),非 const char * (指向常量)
// 容易誤解,指針 typedef 謹慎使用,或改用 typedef int * IntPtr; 明確指針屬性。
// 無 typedef:難讀
int (*callback)(int, int);
// 有 typedef:清晰
typedef int (*BinaryOp)(int, int);
typedef void (*EventHandler)(int event_id, void *user_data);
BinaryOp op = add;
EventHandler handler = on_click;
// 結構體嵌入回調
typedef struct {
EventHandler on_init;
EventHandler on_exit;
} Plugin;
typedef int Matrix4x4[4][4];
typedef char LineBuf[256];
Matrix4x4 mat; // 等同 int mat[4][4];
LineBuf buffer; // 等同 char buffer[256];
void init_matrix(Matrix4x4 m) { ... } // 參數退化為指針,但語義明確
配合 `typedef` 分層拆解:
// 原始:void (*signal(int, void (*)(int)))(int); // signal 函數聲明
// 拆解:
typedef void (*SigHandler)(int); // 信號處理器類型
typedef void (*SigReturn)(int); // signal 返回類型
SigReturn signal(int signo, SigHandler handler); // 清晰可讀
| 特性 | typedef | #define |
|---|---|---|
| 處理階段 | 編譯器 (語義分析) | 預處理器 (文本替換) |
| 作用域 | 遵循 C 作用域規則 | 全域文本替換 |
| 指針語義 | `const MyPtr p` → `int *const p` | `const MY_PTR p` → `const int *p` (錯誤!) |
| 調試器可見 | 是 (類型資訊保留) | 否 (展開後無痕跡) |
| 組合聲明 | 每個變數獨立類型 | 文本替換可能導致混淆 |
結論:**永遠優先使用 `typedef` 定義類型別名**,`#define` 僅用於常數、宏函數、條件編譯。
`typedef` 不創造新類型,只創造**別名**。善用它簡化複雜聲明、封裝平台差異、建立領域語彙 (Domain Vocabulary),是編寫可讀、可維護、可移植 C 代碼的關鍵技術。