ตัวชี้ไปยังvoidเป็นประเภทตัวชี้ "ทั่วไป" void *สามารถแปลงเป็นตัวชี้ประเภทอื่น ๆ ได้โดยไม่ต้องหล่ออย่างชัดเจน คุณไม่สามารถอ้างถึง a void *หรือ do การคำนวณทางคณิตศาสตร์ด้วย; คุณต้องแปลงเป็นตัวชี้ไปยังชนิดข้อมูลที่สมบูรณ์ก่อน
void *มักใช้ในสถานที่ที่คุณต้องทำงานกับตัวชี้ชนิดต่าง ๆ ในรหัสเดียวกัน ตัวอย่างหนึ่งที่อ้างถึงโดยทั่วไปคือฟังก์ชั่นห้องสมุดqsort:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
baseคือที่อยู่ของอาเรย์nmembคือจำนวนองค์ประกอบในอาเรย์sizeเป็นขนาดของแต่ละองค์ประกอบและcomparเป็นตัวชี้ไปยังฟังก์ชันที่เปรียบเทียบสององค์ประกอบของอาเรย์ มันถูกเรียกเช่น:
int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);
นิพจน์อาร์เรย์iArr, dArrและlArrจะถูกแปลงโดยปริยายจากประเภทอาร์เรย์ชนิดชี้ในการเรียกใช้ฟังก์ชันและแต่ละคนจะถูกแปลงโดยปริยายจาก "ชี้ไปint/ double/ long" เป็น "ตัวชี้ไปvoid"
ฟังก์ชันเปรียบเทียบจะมีลักษณะดังนี้:
int compareInt(const void *lhs, const void *rhs)
{
const int *x = lhs; // convert void * to int * by assignment
const int *y = rhs;
if (*x > *y) return 1;
if (*x == *y) return 0;
return -1;
}
โดยการยอมรับvoid *, qsortสามารถทำงานกับอาร์เรย์ของชนิดใด ๆ
ข้อเสียของการใช้void *คือคุณโยนความปลอดภัยประเภทนอกหน้าต่างและเป็นการจราจรที่กำลังจะมาถึง ไม่มีอะไรที่จะปกป้องคุณจากการใช้รูทีนการเปรียบเทียบที่ไม่ถูกต้อง:
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);
compareIntคาดว่าข้อโต้แย้งของมันจะชี้ไปที่ints แต่จริงๆแล้วทำงานกับdoubles ไม่มีทางที่จะจับปัญหานี้ในเวลารวบรวม; คุณจะจบลงด้วยอาเรย์ที่ถูกพลาด