【问题标题】:Casting from void* to struct从 void* 转换为 struct
【发布时间】:2013-03-05 10:02:12
【问题描述】:

我将 struct Person 类型的数据传递给链表,因此每个节点的数据指针都指向一个 struct Person。

struct Person {
char name[16];
char text[24];
};

我正在尝试遍历列表并通过调用打印每个节点中的名称/文本

traverse(&list, &print);

遍历的原型是:

void traverseList(struct List *list, void (*f)(void *));   

列表定义为:

struct List {
struct Node *head;
};

我的打印函数接受一个 void * 数据:

print(void *data) { .... }

我知道我必须将数据转换为 struct Person,对吗?

struct Person *person = (struct Person *)data;
printf("%s", person->name);

我知道这还不够,因为我收到“从不兼容的指针类型初始化”警告。在这种情况下,我怎样才能成功施放 void*?谢谢。

【问题讨论】:

  • traverse的原型是什么? list是哪个类型的?
  • 您可能想要检查您是如何传递列表以进行遍历的,以及您实际使用打印的方式。您显示的所有内容似乎都匹配。
  • @ValeriAtamaniouk 我已经编辑了我的问题以包含这些内容。
  • @user1889966 是按原样声明的print,还是返回void?如果声明不返回,大概是int
  • @ValeriAtamaniouk 我很抱歉没有包括在内,它被声明为静态无效。

标签: c struct void-pointers


【解决方案1】:

问题不在于演员阵容,甚至不在于您传递函数的方式。问题是您的print 声明缺少返回类型,在这种情况下通常假定int。编译器抱怨,因为您将 int (*)(void*) 传递给期望 void (*)(void*) 的函数。

这很容易解决:只需在 print 函数声明前添加 void。见:

https://gist.github.com/ods94065/5178095

【讨论】:

    【解决方案2】:

    我的打印函数接受一个 void * 数据

    我会说,通过接受 struct Person * 重写您的 print 函数。

    【讨论】:

    • 这有什么关系?在 C 中,void* 与任何指向结构的非常量指针兼容。
    • 只是因为那时不需要投射。
    • 您仍然需要转换 - 在传递函数以进行遍历时,您需要从 void (*)(struct Person*) 转换为 void (*)(void*)。我怀疑这样的便携性不太安全,而且 IMO 也不那么优雅。
    【解决方案3】:

    您的 traverseList 函数接受一个函数指针(它接受一个 void 指针),但它不接受该 void 数据的参数。看来这就是你所追求的:

    void print (void* data)
    {
        printf("%s", ((struct Person*)data)->name);
    }
    
    void traverseList (struct List *list, void(*f)(void*), void* data)
    {
        f(data);
    }
    

    然后就可以调用traverseList了:

    traverseList (&list, &print, &person);
    

    【讨论】:

    • 我认为traverse 提供给print 的参数是struct List *struct List * 参数的data 成员。列表中后面的节点。
    猜你喜欢
    • 2013-09-23
    • 2020-06-24
    • 2023-03-16
    • 2012-04-28
    • 2019-03-15
    • 2016-10-07
    • 2013-08-29
    • 2012-11-03
    • 1970-01-01
    相关资源
    最近更新 更多