首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C/C++ void 與 void 指針深度探索:類型安全、通用指針與最佳實踐

     編輯:關於C

void 的字面含義

  • void:**無類型**、**無值**。
  • void*:**無類型指針**,可指向任意類型對象的地址。

void 的兩大核心用途

  1. 函數無返回值:void func();
  2. 函數無參數:void func(void); (C++ 中 void func(); 等價,C 中不同)

void* 的類型轉換規則

操作合法性說明
任意指針 → 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,程式員承擔類型正確性責任

五大使用規範

規則一:無返回值函數必須聲明 void

// 錯誤:舊式 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,但舊代碼庫仍存風險。

規則二:無參數函數必須聲明 void (C 語言)

// C 語言
int func();      // 參數未指定,調用時可傳任意參數(危險)
int func(void);  // 明確無參數,調用傳參將報錯

// C++ 中 int func() 等價於 int func(void)

規則三:謹慎進行 void* 算術運算

  • ANSI C:**禁止** pv++、pv += 1。
  • GNU 擴展:允許,視同 char* (步長 1 字節)。
  • **移植寫法**:(char*)pv++ 或 (char*)pv += n,符合 ANSI 且跨平台。

規則四:通用接口參數使用 void*

典型例子: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 不能代表實際變量

void a;           // 錯誤
void func(void a); // 錯誤
// void 是抽象類型,類似「抽象基類」,不可實例化

進階話題:void* 與類型安全

C++ 推薦替代方案

  1. 模板:編譯期類型安全,零開銷。
    template void copy(T* dest, const T* src, size_t n);
  2. std::any / std::variant (C++17):類型安全的「任意值」容器。
  3. 多態基類指針/引用:面向對象場景下替代 void* 回調。

不得不使用 void* 時的防護

  • 封裝薄包裝類,構造時檢查類型一致性。
  • 使用 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++ 給了我們更安全的工具,盡量少用它。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved