以下代码段来自K& R第5-11章:指向函数的指针:
qsort((void**) lineptr, 0, nlines-1,
(int (*)(void *, void *)(numeric ? numcmp : strcmp));
我可以使用(void*)
编译/运行代码,那么为什么lineptr会使用(void **)
代替?两个演员之间是否存在任何内部差异,还是更易于阅读?是(void *)
只是投射数组,而(void **)
是否同时投射数组和存储的指针?
我理解**lineptr
等同于*lineptr[]
,无效转换的原因是让编译器满意。
答案 0 :(得分:2)
这很可能是不正确的。
void *是一个指向某事物的指针。我们不知道它指向的是什么。您可以将任何指针强制转换为void *。传递给qsort的比较函数必须猜测void *指向的实际类型。如果它做对了,那很好。如果它弄错了,事情就会出错 - 这就是生活和程序员的责任。
void **是指向void *数组的指针。这里有一个很大的区别:虽然你可以毫无问题地将int *转换为void *,但int *的数组绝对是而不是一个void *数组。 int *和void *可以有不同的大小! C标准非常清楚地表明哪种指针具有相同的表示形式:
任何不在同一组中的指针都可以有不同的表示形式,因此强制转换可能有效,但memcpy或通过指向不同指针类型的指针读取值并不起作用。