typedef 是 C 語言關鍵字,**為現有類型建立別名**,不創建新類型。兩大核心目的:
// 內建類型別名
typedef unsigned long ULONG;
typedef int INT32;
typedef char BYTE;
// 結構體別名(兩種寫法等價)
typedef struct { int x, y; } Point; // 匿名結構體 + 別名
typedef struct TagPoint { int x, y; } Point; // 命名結構體 + 別名
// 使用
Point p1 = {10, 20};
ULONG id = 12345;
typedef struct Node {
char *data;
Node *next; // 錯誤:Node 尚未定義完成,編譯器不認識
} Node;
| 方法 | 代碼 | 原理 |
|---|---|---|
| 1. 結構體標籤前向聲明 |
| 先 typedef 指針類型,再定義結構體內容 |
| 2. 結構體內用標籤 |
| 不依賴 typedef 名,用結構體標籤 |
| 3. 分離定義(推薦規範) |
| 結構體定義與別名分離,語義最清晰 |
typedef char *pStr;
#define pStr_macro char *
pStr s1, s2; // 兩個 char*
pStr_macro s3, s4; // s3 是 char*,s4 是 char(宏只是文本替換!)
| 特性 | typedef | #define |
|---|---|---|
| 本質 | 類型別名(編譯器處理) | 文本替換(預處理器處理) |
| 指標聲明 | `pStr a, b;` 皆為指標 | `pStr_macro a, b;` 第二個非指標 |
| const 修飾 | `const pStr p` = `char * const p`(指標常量) | `const pStr_macro p` = `const char * p`(指向常量指標) |
| 作用域 | 遵循塊作用域規則 | 無作用域,全域替換 |
| 除錯符號 | 保留類型資訊 | 無類型資訊 |
| 條件編譯 | 不支援 | 支援 #ifdef/#undef |
typedef char *pStr;
char str[] = "hello";
const pStr p1 = str; // p1 是 char * const(指標不可改)
// p1++; // 編譯錯誤:指標本身為常量
const char *p2 = str; // p2 是 const char *(指向內容不可改)
p2++; // OK
核心技巧:**在原聲明中用別名替換變數名,前加 `typedef`**。
// 原聲明:int *(*a[5])(int, char*);
typedef int *(*FuncPtr)(int, char*); // 別名替換 a
FuncPtr a[5]; // 簡潔聲明
// 原聲明:void (*b[10]) (void (*)());
typedef void (*Callback)(); // 內層函數指標
typedef void (*Handler)(Callback); // 外層函數指標
Handler b[10]; // 簡潔聲明
// 原聲明:double (*(*pa)[9])();
typedef double (*Func)(); // 函數指標類型
typedef Func (*FuncArrayPtr)[9]; // 指向 9 元素 Func 陣列的指標
FuncArrayPtr pa; // 簡潔聲明