C 語言**無模組/包/命名空間/類別**等高級模組化機制,**函式是唯一的模組化單元**。
| 原則 | C 語言實踐 |
|---|---|
| 高內聚 | 每個函式只做一件事 (Single Responsibility) — `int read_int(FILE*)`、`void sort_int(int*, size_t)`、`bool write_png(const char*, const Image*)` |
| 低耦合 | 介面最小化:`.h` 只暴露必要原型、不透明型別 (`struct Foo;`)、不暴露內部結構/巨集/靜態函式 |
| 資訊隱藏 | `static` 修飾內部函式/全域變數 — 編譯單元私有,連結器不可見 |
| 介面與實作分離 | `.h` = 契約 (API),`.c` = 實現 — 多實現可替換 (如 `alloc_posix.c` / `alloc_win32.c` / `alloc_pool.c`) |
| 單一進入點 | 庫初始化/清理函式 `lib_init()`/`lib_cleanup()` — 避免全域建構子順序問題 |
my_lib/
├── CMakeLists.txt
├── include/
│ └── my_lib/
│ ├── api.h // 公開介面:型別前向宣告、函式原型、常數、錯誤碼
│ └── config.h // 編譯期配置 (可選)
├── src/
│ ├── api.c // 公開函式實作
│ ├── internal.h // 內部共用:靜態函式原型、內部結構、巨集
│ ├── module_a.c // 子模組 A 實作
│ └── module_b.c // 子模組 B 實作
├── tests/
│ ├── test_api.c
│ └── CMakeLists.txt
└── examples/
└── basic_usage.c
// include/my_lib/api.h
#ifndef MY_LIB_API_H
#define MY_LIB_API_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct MyContext MyContext; // 不透明型別:僅前向宣告,定義隱藏在 .c
// 建構/銷毀
MyContext* my_create(const char* config_path);
void my_destroy(MyContext* ctx);
// 核心功能
int my_process(MyContext* ctx, const void* input, size_t len, void** output, size_t* out_len);
// 錯誤碼
#define MY_OK 0
#define MY_EINVAL -1
#define MY_ENOMEM -2
#define MY_EIO -3
#ifdef __cplusplus
}
#endif
#endif
// src/api.c
#include "my_lib/api.h"
#include "internal.h"
struct MyContext { // 完整定義僅在 .c 可見
int fd;
void* buffer;
size_t buf_size;
Config cfg;
};
MyContext* my_create(const char* config_path) {
MyContext* ctx = calloc(1, sizeof(MyContext));
if (!ctx) return NULL;
if (load_config(config_path, &ctx->cfg) != 0) { free(ctx); return NULL; }
ctx->buf_size = ctx->cfg.buffer_size;
ctx->buffer = malloc(ctx->buf_size);
if (!ctx->buffer) { free(ctx); return NULL; }
return ctx;
}
void my_destroy(MyContext* ctx) {
if (!ctx) return;
free(ctx->buffer);
free(ctx);
}
// ...
**效果**:使用者**完全無法存取 `MyContext` 內部欄位**,只能透過 API 操作 — 修改內部結構**不需重新編譯使用者代碼**,實現真正的二進制相容 (ABI 穩定)。
C 語言模組化 = **函式 + 編譯單元 + 不透明指標 + 靜態連結/動態庫**。
掌握「`.h` 只放契約、`.c` 放實作、內部 `static`、公開不透明指標」,你就掌握了 C 語言工程級模組化的精髓。