以下代码片段来自 K&R 第 5-11 章:函数指针:
qsort((void**) lineptr, 0, nlines-1,
(int (*)(void *, void *)(numeric ? numcmp : strcmp));
我可以使用 (void*)
编译/运行代码,那么为什么 lineptr 要用 (void **)
进行转换呢?两个 Actor 之间是否存在任何内部差异,或者更多的是为了可读性? (void *)
仅转换数组,而 (void **)
转换数组和存储的指针?
我知道 **lineptr
相当于 *lineptr[]
并且 void 强制转换的原因是为了让编译器满意。
最佳答案
这很可能是错误的。
void* 是一个指向某物的指针。我们不知道它指向什么。您可以将任何指针强制转换为 void*。传递给 qsort 的比较函数必须猜测 void* 指向的实际类型是什么。如果做对了,就好了。如果出错,事情就会出错——这就是生活,也是程序员的责任。
void** 是指向 void* 数组的指针。这里有一个很大的区别:虽然您可以毫无问题地将 int* 转换为 void*,但 int* 数组绝对不是 void* 数组。 int* 和 void* 可以有不同的大小! C 标准非常清楚哪些类型的指针具有相同的表示形式:
- void* 和 char* 的任何变体(void** 不是 void* 的变体)
- 任何指向结构的指针
- 任何指向 union 的指针
- 任何指向不同符号的原始类型的指针(如 int、unsigned int)。
任何不在同一组中的指针都可以有不同的表示形式,因此强制转换可能会起作用,但 memcpy 或通过指向不同指针类型的指针读取值不起作用。
关于c - 对于转换指针数组(例如 *array[]),为什么使用 (void**) 而不是 (void*),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27661807/