C 語言常被稱為「帶結構的組合語言」,其核心抽象能力幾乎完全仰賴指針。與 C++ 擁有「物件導向(類/繼承/虛函數)」與「泛型(模板)」兩大獨有抽象機制不同,C 僅靠指針一槌定音:
struct file_operations)掌握指針 ≠ 會用
int *p;以指針為設計語言,才是 C 程式設計師的最高境界。
| 層次 | 本質 | 典型用法 |
|---|---|---|
| 硬體映射 | 記憶體位址編號 | volatile uint32_t *GPIO_BASE = (uint32_t *)0x40020000; |
| 資料結構 | 節點連接器 | struct Node { int val; struct Node *next; }; |
| 抽象介面 | 行為封裝載體 | struct Driver { int (*init)(void); int (*read)(void *buf, size_t len); }; |
/* api.h */
struct Context; // 前向宣告,隱藏實作
typedef struct Context *ContextHandle;
ContextHandle ctx_create(void);
void ctx_destroy(ContextHandle);
int ctx_process(ContextHandle, const void *in, size_t len, void *out, size_t *out_len);
/* api.c */
struct Context { int fd; void *buffer; size_t cap; }; // 只有實作檔可見
typedef struct {
int (*open)(const char *path);
ssize_t (*read)(void *buf, size_t n);
void (*close)(void);
} FileOps;
FileOps posix_ops = { .open = open, .read = read, .close = close };
FileOps mem_ops = { .open = mem_open, .read = mem_read, .close = mem_close };
/* 執行期切換實作 */
FileOps *ops = use_memory_fs ? &mem_ops : &posix_ops;
ops->open("data.bin");
typedef struct {
void *data;
size_t elem_size;
size_t len, cap;
int (*cmp)(const void *, const void *);
void (*dtor)(void *);
} Vector;
void vec_push(Vector *v, const void *elem) { /* memcpy(v->data + v->len*v->elem_size, elem, v->elem_size) */ }
void vec_sort(Vector *v) { qsort(v->data, v->len, v->elem_size, v->cmp); }
struct list_head { struct list_head *prev, *next; };
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
/* 任意結構體嵌入 list_head 即可入鏈,無需額外分配節點 */
struct Task { int pid; struct list_head node; };
struct Task *t = container_of(pos, struct Task, node);
int * 不能訪問 float 物件(違反 UB),通用訪問請用 char * 或 uint8_t *_Alignas / alignof(C11)確保 SIMD、原子操作、硬體暫存器存取正確restrict(C99)告訴編譯器指針不重疊,啟用激進向量化優化const int *p(指向常量)vs int *const p(常量指針)vs const int *const pstruct Pkt { size_t len; uint8_t data[]; };(C99)單次分配變長結構初學者視指針為工具(傳址、動態分配);專家視指針為架構基石:
PluginOps,動態載入 .so/.dll 填充函數表struct iovec + sendmsg + 指針鏈管理緩衝區所有權ucontext_t / setjmp/longjmp + 指針保存棧幀指針是 C 語言的靈魂,記憶體位址是其肉身,類型系統是其律法。唯有洞悉三者關係,方能在「不安全」的自由中,鑄造出高效、優雅、可演進的系統級軟體。