void:**無類型**、**無值**。void*:**無類型指針**,可指向任意類型對象的地址。void func();void func(void); (C++ 中 void func(); 等價,C 中不同)| 操作 | 合法性 | 說明 |
|---|---|---|
| 任意指針 → void* | ✅ 隱式轉換 | 「無類型」可包容「有類型」 |
| void* → 任意指針 | ⚠️ 需顯式強轉 (C++) | C 允許隱式,C++ 強制顯式轉換 |
| void* 算術運算 | ❌ ANSI C 禁止 | 不知所指對象大小,無法計算位移 |
| void 變量定義 | ❌ 編譯錯誤 | 無實際大小,無法分配存儲 |
void *pv;
int *pi = &n;
pv = pi; // OK,隱式
// pi = pv; // C++ 錯誤,需 pi = (int*)pv;
pi = (int*)pv; // OK,程式員承擔類型正確性責任
// 錯誤:舊式 C 隱式 int
add(int a, int b) { return a+b; }
// 正確
void add(int a, int b) { ... } // 無返回值
int add(int a, int b) { return a+b; } // 有返回值
現代編譯器 (C99/C++11) 已禁止隱式 int,但舊代碼庫仍存風險。
// C 語言
int func(); // 參數未指定,調用時可傳任意參數(危險)
int func(void); // 明確無參數,調用傳參將報錯
// C++ 中 int func() 等價於 int func(void)
pv++、pv += 1。char* (步長 1 字節)。(char*)pv++ 或 (char*)pv += n,符合 ANSI 且跨平台。典型例子:memcpy、memset、malloc、free、qsort 比較函數、線程啟動函數 pthread_create。
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
void *malloc(size_t size);
void free(void *ptr);
體現「只操作位元組流,不關心語義類型」的設計哲學。
void a; // 錯誤
void func(void a); // 錯誤
// void 是抽象類型,類似「抽象基類」,不可實例化
template void copy(T* dest, const T* src, size_t n); static_assert 驗證大小/對齊。reinterpret_cast 而非 static_cast。| 場景 | C 做法 | C++ 現代做法 |
|---|---|---|
| 無返回值 | void func() | void func() |
| 無參數 | func(void) | func() |
| 通用指針 | void* | 模板 / any / variant / 基類* |
| 泛型算法 | void* + 函數指針 (qsort) | 模板 + 迭代器/可調用物 (std::sort) |
| 異構容器 | void* 數組 | std::variant / std::any / 智能指針基類 |
「void* 是 C 語言對類型系統的受控妥協;C++ 給了我們更安全的工具,盡量少用它。」