// 無 typedef:C 中必須寫 struct Tag
struct Student { int num; char sex; char name[50]; };
struct Student s1; // C 必須加 struct
// 有 typedef:定義類型別名 STUDENT
typedef struct Student { int num; char sex; char name[50]; } STUDENT;
STUDENT s1; // C/C++ 通用,簡潔
// 甚至可匿名結構體:
typedef struct { int num; char sex; char name[50]; } STUDENT;
// 陷阱:char* p1, p2; p1 是指針,p2 是 char!
// 解決:typedef 定義指針類型
typedef char* PCHAR;
PCHAR p1, p2; // 兩個均為 char*
// 結構體指針同理
typedef struct Student *PSTUDENT;
PSTUDENT ps1, ps2; // 兩個均為 struct Student*
// 平台 A:支持 long double,最高精度
typedef long double REAL;
// 平台 B:無 long double,用 double
typedef double REAL;
// 平台 C:僅有 float
typedef float REAL;
// 業務代碼無需修改:
REAL x = 3.14159265358979323846;
REAL y = sin(x); // 假設有對應 REAL 版本的 sin
標準庫實例:size_t、ptrdiff_t、int32_t、uintptr_t 等均為 typedef 定義,保證跨平台一致性。
// 函數指針:返回 int,參數 (int, int)
typedef int (*MathFunc)(int, int);
MathFunc func = add; // 極其清晰
// 數組指針:指向 10 個 int 的數組
typedef int (*Arr10Ptr)[10];
Arr10Ptr p = &arr;
| 場景 | typedef | #define |
|---|---|---|
| 本質 | 類型別名(編譯器語義分析階段) | 文本替換(預處理階段) |
| 指針聲明 | typedef char* P; P a,b; → 兩個 char* | #define P char* P a,b; → char* a, b; (b 是 char) |
| 類型擴展 | 不可:unsigned P 錯誤 | 可:unsigned P → unsigned char* |
| 作用域 | 遵循塊作用域 | 無作用域,全局替換 |
| 調試符號 | 保留在符號表 | 預處理後消失 |
| 語義檢查 | 編譯器理解類型含義 | 無類型語義,純文本 |
_t 後綴(如 uint32_t、PSTUDENT),區分於變量/函數。typedef int* IntPtr; 可能掩蓋指針語義,導致 const IntPtr p 被誤解為 const int* 實為 int* const。指針類型慎用 typedef。typedef struct Node { int data; struct Node *next; } Node; 結構標簽 Node 與類型名 Node 共存,C 語言不同名字空間無衝突。typedef 是 C/C++ 類型系統的擴展機制,提供語義級別的別名,而非文本替換。核心價值在於:簡化複雜聲明、統一指針聲明、跨平台類型抽象、增強代碼可讀性與可維護性。掌握其與 #define 的本質區別,避開指針 typedef 的 const 陷阱,是寫出專業級 C 代碼的關鍵。