如何遍历数组参数作为void指针

时间:2015-10-15 16:57:32

标签: c gcc gcc-pedantic

我有类似“通用”的过程,如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指针是一种不好的做法。 (例如Pointer arithmetic for void pointer in C

那么标准库如何像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 *)吗?

3 个答案:

答案 0 :(得分:3)

我问了类似的问题Can I do arithmetic on void * pointers in C?

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

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

出于这个原因,唯一的方法是将指针强制转换为某些东西并执行它 - 我不推荐它,除非你非常清楚指针的内容。无效指针是非常黑暗的编程。