Lea*_*g C 6 c structure void-pointers data-structures
因为这是一个空*我应该能够传递任何类型的指针吗?为什么编译器会给我错误?
int cmp_func(void *, void *));
typedef struct word_{
char key[WORD_SIZE];
int *frequency;
} word;
Phash_table new_hash(int size, int (*hash_func)(char *), int (*cmp_func)(void *\
, void *));
int comp_function(struct word_ *word1,struct word_ *word2){
if( word1->frequency < word2->frequency){
return -1;
}
if(word1->frequency < word2->frequency){
return 1;
}
if(word1->frequency == word2->frequency){
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
project4_functions.c:47:3: warning: passing argument 3 of 'new_hash' from incompatible pointer type [enabled by default]
hash.h:38:13: note: expected 'int (*)(void *, void *)' but argument is of type 'int (*)(struct word_ *, struct word_ *)'
Run Code Online (Sandbox Code Playgroud)
关键是让你的比较函数也采用void指针:
int comp_function(void *a, void *b){
struct word *word1 = a;
struct word *word2 = b;
// Use word1 and word2 as before.
}
Run Code Online (Sandbox Code Playgroud)
附录,关于为什么编译器给你的警告:
引用我在这里找到的c99标准
指向void的指针可以转换为指向任何不完整或对象类型的指针.指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针.
这意味着您可以拥有如下代码,编译器不会发出您所看到的警告:
void *a = NULL;
int (*f)(int a, char *b) = NULL;
a = f;
f = a;
Run Code Online (Sandbox Code Playgroud)
推测这意味着下面的内容也会起作用(毕竟,我们只是用"struct foo*"代替"void*",对吗?)
int (*f1)(void*, void*);
int (*f2)(struct foo*, struct foo*);
f1 = f2;
Run Code Online (Sandbox Code Playgroud)
但是,这会生成警告,因为它不会尝试将指针类型分配给指向void的指针(反之亦然),这是标准允许的.相反,它试图将类型的值赋给类型int (*)(struct foo*, struct foo*)的变量int (*)(void*, void*).
当然,您可以尝试使编译器对显式转换感到满意,这会使编译器相信您必须知道您正在做什么.但是这样做即使在调用"iffy"行为时也会失去获得这些警告的特权和安全性.