对于转换指针数组(例如* array []),为什么要使用(void **)而不是(void *)

时间:2014-12-26 20:46:37

标签: c kernighan-and-ritchie

以下代码段来自K& R第5-11章:指向函数的指针:

qsort((void**) lineptr, 0, nlines-1, 
   (int (*)(void *, void *)(numeric ? numcmp : strcmp));

我可以使用(void*)编译/运行代码,那么为什么lineptr会使用(void **)代替?两个演员之间是否存在任何内部差异,还是更易于阅读?是(void *)只是投射数组,而(void **)是否同时投射数组和存储的指针?

我理解**lineptr等同于*lineptr[],无效转换的原因是让编译器满意。

1 个答案:

答案 0 :(得分:2)

这很可能是不正确的。

void *是一个指向某事物的指针。我们不知道它指向的是什么。您可以将任何指针强制转换为void *。传递给qsort的比较函数必须猜测void *指向的实际类型。如果它做对了,那很好。如果它弄错了,事情就会出错 - 这就是生活和程序员的责任。

void **是指向void *数组的指针。这里有一个很大的区别:虽然你可以毫无问题地将int *转换为void *,但int *的数组绝对是而不是一个void *数组。 int *和void *可以有不同的大小! C标准非常清楚地表明哪种指针具有相同的表示形式:

  1. void *和char *的任何变化(void ** *
  2. 任何指向结构的指针
  3. 任何指向工会的指示
  4. 任何指向不同签名的原始类型的指针(如int,unsigned int)。
  5. 任何不在同一组中的指针都可以有不同的表示形式,因此强制转换可能有效,但memcpy或通过指向不同指针类型的指针读取值并不起作用。