我有类似“通用”的过程,如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 *)吗?
答案 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位或至少它会让你知道事情出了差错!)。
出于这个原因,唯一的方法是将指针强制转换为某些东西并执行它 - 我不推荐它,除非你非常清楚指针的内容。无效指针是非常黑暗的编程。