// 錯誤:char* pa, pb; → pa 是指標,pb 是 char
typedef char* PCHAR;
PCHAR pa, pb; // 正確:兩個都是 char*
// #define 無法達到同樣效果
#define DCHAR char*
DCHAR pa, pb; // 同樣錯誤
// 早期 C 需寫 struct TagName var;
struct tagPOINT1 { int x, y; };
struct tagPOINT1 p1; // 必須加 struct
// typedef 簡化
typedef struct tagPOINT { int x, y; } POINT;
POINT p1; // 直接用型別名
C++ 已不需此技巧,但維護舊代碼時需理解。
// 平台一:支援 long double
typedef long double REAL;
// 平台二:僅支援 double
typedef double REAL;
// 平台三:僅支援 float
typedef float REAL;
// 業務代碼統一使用 REAL,移植只需修改 typedef
標準庫廣泛應用(如 size_t, int32_t)。
方法:從原宣告逐步替換,保留變數名到最後。
// 1. int *(*a[5])(int, char*);
typedef int *(*pFun)(int, char*);
pFun a[5];
// 2. void (*b[10]) (void (*)());
typedef void (*pFunParam)();
typedef void (*pFunx)(pFunParam);
pFunx b[10];
// 3. double(*)() (*e)[9];
typedef double(*pFuny)();
typedef pFuny (*pFunParamy)[9];
pFunParamy e;
「右左法則」讀懂複雜宣告:從變數名出發,先右後左,遇括號反向,遞迴分析。
記住兩模式:type (*)(...) 函數指標,type (*)[] 陣列指標。
typedef char* PSTR;
const PSTR p; // 實際為 char* const(常數指標),而非 const char*(指向常數的指標)
原因:const 修飾整個 typedef 名稱,形成「指標本身為常數」。
typedef static int INT2; // 編譯錯誤:指定了一個以上的儲存類別
typedef 與 static/extern/register 互斥。
typedef 是編譯器層面的型別別名,非預處理器文字替換,具備型別語意、支援作用域、避免宏副作用。善用它簡化複雜宣告、實現跨平台移植,並警惕 const 結合語意與儲存類別衝突兩大陷阱。