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

C/C++ void 指針深度解析:泛型編程的基石

     編輯:關於C語言

什麼是 void 指針?

void * 是「無類型指針」,可指向任意類型的數據地址。它不攜帶類型信息,因此不能直接解引用或進行指針算術運算,但能與任意對象指針隱式轉換(C語言中),是實現泛型編程、內存操作、回調接口的核心工具。

核心特性

  • 通用性:可接收任意類型指針(int*、char*、結構體指針等)。
  • 無類型安全:編譯器不檢查指向對象類型,使用時需開發者強制轉換回正確類型。
  • 無法解引用:*void_ptr 非法,必須先轉型 *(int*)void_ptr。
  • 無法算術運算:void_ptr + 1 非法,因不知元素大小;需轉為 char* 做字節偏移。

典型應用場景

1. 通用內存拷貝

void my_memcpy(void *dest, const void *src, size_t n) {
    char *d = (char*)dest;
    const char *s = (const char*)src;
    while (n--) *d++ = *s++;
}

2. 回調函數傳遞上下文

typedef void (*callback_t)(void *ctx, int event);
void register_callback(callback_t cb, void *user_data); // user_data 可攜帶任意結構體

3. 容器/數據結構節點

struct ListNode {
    void *data;           // 存任意類型
    struct ListNode *next;
};

實戰代碼分析

原文提供的測試代碼演示了多級指針與 void 指針的轉換:

#include <stdio.h>
int main() {
    int a1 = 10;
    int *px = &a1;
    int **py = &px;
    int a[] = {1,2,3,4,5};
    int *b[] = {a, a+1, a+2, a+3, a+4};

    // 關鍵:void* 保存二級指針地址,再通過強轉取值
    void *p1 = &py;                 // p1 指向 py (int***)
    void *p2 = &b;                  // p2 指向 b (int**)
    void *p3 = b;                   // p3 指向 b[0] (int*)

    printf("%d\n", **(int***)p1);   // 10
    printf("%d\n", **(int***)p2);   // 1 (a[0])
    printf("%d\n", *(int*)p3);      // 1 (a[0])
    return 0;
}

輸出結果:
運行結果

最佳實踐建議

  1. 盡量縮小 void* 作用域,轉型緊鄰使用點。
  2. 配合 sizeof 傳遞類型大小,實現類型安全的泛型函數。
  3. C++ 中優先使用模板,僅在 C 接口、底層內存管理處使用 void*。
  4. 嚴禁將 void* 轉為 函數指針(標準未定義行為),需用 union 或平台特定轉換。

雖然 void* 看似簡單,但它是 C 語言靈活性與危險性的雙刃劍,掌握其本質與規範用法,方能寫出健壯的系統級代碼。

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