简体   繁体   English

我可以将结构传递给一个带有void *的函数吗?

[英]Can I pass a structure into a function that takes void*?

Since this is a void* I should be able to pass a pointer of anytype right? 因为这是一个空*我应该能够传递任何类型的指针吗? Why is the compiler giving me errors? 为什么编译器会给我错误?

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;
  }
}


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_ *)'

The key is to make your compare function take void pointers as well: 关键是让你的比较函数也采用void指针:

int comp_function(void *a, void *b){
  struct word *word1 = a;
  struct word *word2 = b;
  // Use word1 and word2 as before.
}

Addendum, concerning why the compiler is giving you warnings: 附录,关于为什么编译器是给你的警告:

To quote the c99 standard which I found here 引用我在这里找到的c99标准

A pointer to void may be converted to or from a pointer to any incomplete or object type. 指向void的指针可以转换为指向任何不完整或对象类型的指针。 A pointer to any incomplete or object type may be converted to a pointer to void and back again; 指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; the result shall compare equal to the original pointer. 结果应该等于原始指针。

This means that you can have code like the following, and the compiler won't issue the warning you're seeing: 这意味着您可以拥有如下代码,编译器不会发出您所看到的警告:

void *a = NULL;
int (*f)(int a, char *b) = NULL;
a = f;
f = a;

It's tempting to extrapolate that this means the following will also work (after all, we're just substituting "void*" with "struct foo*", right?) 推测这意味着下面的内容也会起作用(毕竟,我们只是用“struct foo *”代替“void *”,对吗?)

int (*f1)(void*, void*);
int (*f2)(struct foo*, struct foo*);
f1 = f2;

However, this generates your warning since it is not trying to assign a pointer type to a pointer to void (or vice-versa) as is allowed by the standard. 但是,这会生成警告,因为它不会尝试将指针类型分配给指向void的指针(反之亦然),这是标准允许的。 Instead it is trying to assign a value of type int (*)(struct foo*, struct foo*) to a variable of type int (*)(void*, void*) . 相反,它试图将int (*)(struct foo*, struct foo*)类型的值赋给int (*)(void*, void*)类型的变量int (*)(void*, void*)

Of course, you could try to make the compiler happy with an explicit cast, which convinces the compiler that you must know what you're doing. 当然,您可以尝试使编译器对显式转换感到满意,这会使编译器相信您必须知道自己在做什么。 But in doing so you lose the privilege and safety of getting these warnings even when invoking "iffy" behavior. 但是这样做即使在调用“iffy”行为时也会失去获得这些警告的特权和安全性。

Your question does not match your code. 您的问题与您的代码不符。 Your code does not pass a structure pointer as a void pointer. 您的代码不会将结构指针作为void指针传递。 It is passing one function pointer as another. 它将一个函数指针作为另一个传递。 The function pointers are not compatible, hence the error. 函数指针不兼容,因此错误。

It is legal to pass a structure pointer where a void pointer is expected because a structure pointer can be implicitly converted to a void pointer. 传递结构指针是合法的,因为结构指针可以隐式转换为void指针,因此需要使用void指针。 It is not required to be representationally identical to a void pointer. 它不需要在表示上与void指针相同。 (There are some machines where structure pointers are not the same size as a void pointer, for example.) (例如,有些机器的结构指针与void指针的大小不同。)

By analogy consider the case of passing an int when a long is expected. 通过类比考虑在预期长时传递int的情况。 This is legal because there is an implicit conversion, but that doesn't meant that a function accepting int is interchangeable with function accepting long. 这是合法的,因为存在隐式转换,但这并不意味着接受int的函数可以与接受long的函数互换。

You need to cast the function pointer since your function prototype does not match the one the function expects: 您需要转换函数指针,因为函数原型与函数期望的函数原型不匹配:

typedef int (cmp_f)(void *, void *));
new_hash(..., ..., (cmp_f*)cmp_func_p);

Of course that typedef is not necessary, but it makes your code much more readable than without (you usually only do it without that typedef in exams where you are not allowed to use typedef for this purpose ;)) 当然,typedef不是必需的,但它使你的代码比没有你的代码更具可读性(你通常只在不允许为此目的使用typedef的考试中没有那个typedef的情况下这样做;))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以将int传递给C中的void函数吗? - Can I pass an int to a void function in C? 如何打印带有void函数的指针? - How can i print a pointer that takes a void function? 如何将结构传递给函数 - How can i pass a structure to a function 如何将 void 指针传递给 C 中的函数? - How can I pass void pointer to function in C? 为什么我不能将 void 和一个参数传递给 C 中的 function? - Why can't I pass void and a parameter to the function in C? 我怎样才能使用void **函数(void **) - how can I use void** function(void**) 我应该分配一个带有参数的函数给带空的函数指针吗? - Should I assign a function that takes arguments to function pointers that take a void? 如何将一个 cpp 文件中的 void 函数的值传递给另一个 cpp 文件中的另一个 void 函数? - How can I pass the value from void function in one cpp file to an other void function in an other cpp file? 函数采用结构的空指针,并将指向其成员的指针传递给另一个函数 - Function takes a void pointer of a structure and passes on a pointer to its member to another function C编程:void *参数是它真正指向任何东西,我可以在那里传递函数指针 - C programming: void * argument is it really pointer to anything, can I pass function pointer there
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM