3

我有类似的“通用”过程,如 qsort,它有一个 void 指针(指向一个数组)和一个函数指针参数。这个函数应该适用于任何类型的数组。

例子:

void do_something(void * array, int count, int size, void (*test)(const void*)){
    int i;
    for(i=0; i<count; i++){
        test(array + (index * size));
    }
}

然而,这给了我以下警告(gcc test.c -pedantic-errors):

error: pointer of type ‘void *’ used in arithmetic [-Wpedantic]

经过一些研究,我发现使用这样的 void 指针是一种不好的做法。(例如C 中 void 指针的指针算法

那么标准库是如何为 qsort 做这种事情的呢?查看此代码:(http://aturing.umcs.maine.edu/~sudarshan.chawathe/200801/capstone/n/qsort.c),我看到以下内容:

void
_quicksort (void *const pbase, size_t total_elems, size_t size,
        __compar_fn_t cmp)
{
  register char *base_ptr = (char *) pbase;
  ....
  char *lo = base_ptr;
  char *hi = &lo[size * (total_elems - 1)];
  ...
}

无论实际类型如何,他们都转换为 (char *) 吗?

4

3 回答 3

3

我问了类似的问题我可以在 C 中对 void * 指针进行算术运算吗?.

void * 算术未定义。将 1 添加到 void 指针是什么意思?大多数编译器(如果他们允许的话)将其视为按 sizeof(char) 递增(“下一个字节”),但会警告您。

所以正确的做法是明确地让它做你想做的事->强制转换为 char* 并增加它

于 2015-10-15T17:04:38.957 回答
1

不完整数据类型的指针运算void是不合法的,这就是编译器所抱怨的。

正如您在指针中看到的那样_quicksort(),指针是一个常量,因此您无法修改指针指向的地址。void指针上没有发生算术运算。

于 2015-10-15T17:03:17.230 回答
1

使指针无效只会带走指针的“上下文” - 也就是说,系统应该如何看待指针或指针所持有的任何内容。

因此,编译器不对 void 指针进行算术运算。为了进行指针运算,编译器需要知道指针的类型,以便它可以进行正确的转换(如果指针持有一个 int,它不会做 32 位的加法,或者至少它会让你知道有些事情出了差错!)。

出于这个原因,这样做的唯一方法是将指针转换为某些东西并执行它 - 除非您非常清楚指针得到什么,否则我不会推荐它。空指针是相当黑暗的编程。

于 2015-10-15T17:11:48.550 回答