指向void 的指针是“通用”指针类型。 void * 可以在没有显式转换的情况下转换为任何其他指针类型。您不能取消引用 void * 或对其进行指针运算;您必须先将其转换为指向完整数据类型的指针。
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/@的指针隐式转换” 987654337@" 到 "指向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。没有办法在编译时发现这个问题;你只会得到一个错误的数组。