| 形式 | 含義 | 核心用途 |
|---|---|---|
void | 空類型(不完整類型) | 函數無返回值、函數無參數 |
void * | 通用指針(無類型指針) | 泛型編程、內存操作、回調上下文 |
(void)expr | 強制丟棄表達式值 | 消除未使用參數/返回值警告 |
// ✅ 明確無返回值 void init_device(void); // C++中void可省略,C中建議保留 // ✅ 明確無參數(C89兼容寫法) int get_version(void); // 禁止傳參:get_version(1)編譯錯誤 // ❌ 隱式int返回(舊式K&R風格,現代禁用) old_func(); // 視同 int old_func()
void *pv; int *pi = malloc(sizeof(int)); float *pf = malloc(sizeof(float)); pv = pi; // ✅ 任意指針→void* 隱式轉換(安全) pv = pf; // ✅ pi = pv; // ❌ void*→任意指針 需顯式強轉 pi = (int *)pv; // ✅ // 算術運算限制 // pv++; // ❌ ANSI C禁止:void無大小 // (char *)pv++; // ✅ 強轉為char*後按字節運算(移植性寫法)
// 內存操作:純字節級,不關心類型 void *memcpy(void *dest, const void *src, size_t n); void *memset(void *s, int c, size_t n); void *memmove(void *dest, const void *src, size_t n); // 泛型容器/回調上下文 typedef void (*Callback)(void *ctx, int event); void register_cb(Callback cb, void *user_ctx); // 用戶自定義數據透傳
void a; // ❌ 編譯錯誤:無法確定大小 void func(void a); // ❌ 參數不能是void類型 void *p = &a; // ❌ 無法取地址
本質:void是抽象類型,類比面向對象中的抽象基類——不可實例化,僅用於接口規範。
void*,通用指針用char*void*解決類型安全:char*暗示字符串語義,void*純粹表示「一塊內存」void*算術(按char*語義),但標準代碼嚴禁依賴// 任務隊列節點
typedef struct Task {
void (*execute)(void *arg); // 統一執行接口
void *arg; // 擦除類型的參數
struct Task *next;
} Task;
// 用戶代碼
void my_handler(void *arg) {
MyData *d = (MyData *)arg; // 還原類型(契約由雙方約定)
process(d->id, d->payload);
}
Task *t = malloc(sizeof(Task));
t->execute = my_handler;
t->arg = my_data; // 類型擦除
enqueue(t);
void func(void *p) { p++; } → ✅ (char *)p++void *p = malloc(0); → 實現定義行為,避免size=0free(void *)傳入非malloc指針 → 未定義行為(void)unused_param消除編譯警告,保留參數位置便於擴展