C 語言類型系統看似簡單,實則蘊含豐富的組合與抽象能力。本文系統梳理從基本類型到衍生類型(指標、陣列、函式)、複雜宣告解讀、const 語意、函式指標應用,並以「泛型鏈表」與「泛型雜湊表」兩個實戰案例展示純 C 實現多型與高階函式設計模式。
右左法則複雜宣告解讀口訣:從變數名向右,再向左,遇括號優先。
int *a[] → a 是陣列,元素是 int*int (*a)[] → a 是指標,指向 int[]int (*a())[] → a 是函式,回傳指向 int[] 的指標void (*f)(void*) → f 是指標,指向參數為 void*、回傳 void 的函式sizeof 與陣列退化實證int a[3][4]; // sizeof(a) = 48 (3*4*4) int (*pa)[4]; // sizeof(pa) = 4 (指標大小) int *pa[4]; // sizeof(pa) = 16 (4個指標的陣列,64位下32) char *ppa[10]; // sizeof(ppa) = 80 (10個指標)
關鍵結論:陣列作為函式參數會退化為指標,sizeof 僅得指標大小;二維陣列參數需指定列大小 int (*a)[4]。
void *func(void *par) { ... }
void * (*f)(void *) = func; // 指標變數
f(NULL); (*f)(NULL); // 兩種呼叫等價
// 函式指標陣列
void * (*fa[5])(void *);
fa[0] = func; fa[0](NULL); // 像陣列一樣呼叫函式
核心結構:
typedef struct slist {
void *data; // void* 支援任意類型
struct slist *next;
} *pslist;
介面:slist_add_head/tail, slist_remove, slist_drop,皆接受 void* data, int len,內部用 memcpy/memcmp 操作原始記憶體,實現類型無關。
typedef struct hash {
int table_size;
struct slist **heads; // 桶陣列
int (*hash_func)(void*, int); // 使用者自訂雜湊函式
} *phash;
初始化時注入雜湊函式:hash_init(size, my_hash)。查找/插入內部呼叫 h->hash_func(data, h->table_size) 計算桶索引,結合泛型鏈表處理碰撞。結構體封裝函式指標,實現類似「類方法」的行為。
memcpy 實現值語意複製掌握類型系統深層邏輯,能讓你在嵌入式、系統級開發中靈活設計高效、可擴充的資料結構庫。