| 維度 | typedef | #define |
|---|---|---|
| 處理階段 | 編譯期 | 預處理期 |
| 類型檢查 | 有 | 無(純文本替換) |
| 作用域 | 遵循C++作用域規則 | 無作用域(全局生效) |
| 指針修飾 | 整體修飾 | 逐個替換 |
| 功能範圍 | 類型別名 | 常量、宏函數、條件編譯等 |
| 結束符 | 分號 | 無(換行結束) |
#define在預處理階段做機械文本替換,無類型檢查。經典陷阱:
#define f(x) x*x
int c = f(6)/f(2); // 展開為 6*6/2*2 = 36/2*2 = 36 (非預期9)
// 正確寫法:#define f(x) ((x)*(x))
typedef在編譯期生效,編譯器能進行類型檢查,避免此類低級錯誤。
typedef long double REAL;在不同平台分別映射為double/float)。#define MAX 100)、宏函數、條件編譯開關(#ifdef DEBUG)等。
void fun() {
#define A int // 全局生效
}
void gun() {
A x = 10; // 合法!宏無作用域
// typedef int A; // 若用typedef則gun不可見
}
typedef遵循塊作用域,#define從定義處到文件結尾(或#undef)全局可見。
typedef int *pint;
#define PINT int *
const pint p1; // 等價 int *const p1; → p1不可改,指向內容可改
const PINT p2; // 等價 const int *p2; → p2可改,指向內容不可改
pint s1, s2; // 兩個int*指針
PINT s3, s4; // s3是int*,s4是int!(展開為 int *s3, s4;)
根因:typedef創建新類型標識符,const修飾整個類型;#define純文本替換,const只修飾int。
constexpr)、跨平台條件編譯、宏函數(慎用,優先用inline函數/模板)。using別名聲明(using pint = int*;),語法更統一,支援模板別名(template using Vec = vector; ),漸進替代typedef。typedef是編譯器認可的類型系統擴展,#define是預處理器的文本操作工具。前者構建類型抽象,後者實現代碼生成元編程。認清本質,方能靈活運用、避開陷阱。