【问题标题】:Handling void pointers in C在 C 中处理 void 指针
【发布时间】:2021-12-24 06:04:09
【问题描述】:

我正在编写一个 C 代码来处理稀疏矩阵,并且我想最大限度地模块化我的代码。

我注意到有几次我需要遍历直到找到前一个节点(哦,我正在使用链表来构建矩阵),并且我想创建一个可重用的函数.

我的代码中有 4 个结构,它们都有变量 firstlastnext,如果是没有标头角色的子结构。

我想到了这样的代码:

void *iterateUntilNext(void *header, void *child)
{
    void *walker = header->first;
    while (walker->next != child)
    {
        walker = walker->next;
    }
    return walker;
}

但我收到了这个错误:expression must have pointer-to-struct-or-union type but it has type "void *"

有什么办法可以使这项工作发挥作用还是我做梦太多了?

【问题讨论】:

  • 将其转换为预期指向的类型的指针。或者一直使用这种类型而不是 void*
  • 指向无类型的指针如何拥有成员。 Muy 的建议 - 不要试图太普遍。它永远不会起作用。
  • header 指向一个未知类型,编译器怎么知道这个first 字段是什么?
  • 创建“通用”数据类型的常用模式是在创建数据结构时提供访问和其他操作。但它是一个相对广泛的主题,需要在 cmets 中涵盖。也许有人会把它写成答案......
  • @0___________ 如果我的问题对社区没有帮助,我很抱歉。确实,我在 C 方面有点新。如果你们都认为这个问题必须关闭,我会关闭它。但请注意,没有一个人天生无所不知。还要记住,你最后的评论不是那么礼貌。但是感谢您的反馈:)

标签: c pointers data-structures void-pointers


【解决方案1】:

面向对象

定义一个类似的基本结构

#define list_item_interface \
  list_item *first; \
  list_item *next;

typedef struct list_item {
    list_item_interface
} list_item;

并“派生”您的自定义项目,例如

typedef struct custom_list_item {
    list_item_interface //needs to be the first entry
    //other members/fields
} custom_list_item;

然后定义您的“通用”函数,例如

list_item* iterate(list_item *header, list_item *child) { /*...*/ }

这样称呼

custom_list_item *header, *child;
iterate((list_item*) header, (list_item*) child);

GCC - 扩展

接受任何类型,提供相同类型的字段firstnext

#define LIST_ITEM_ITERATE(HEADER, CHILD) ({ \
    __auto_type HEADER_ = (HEADER); \
    __auto_type CHILD_  = (CHILD); \
    __auto_type WALKER  = HEADER_->first; \
    while (WALKER->next != CHILD_) \
        WALKER = WALKER->next; \
    WALKER; \
)}

【讨论】:

  • UB - 严格的别名规则。
  • @0___________ C11 标准如何,第 6.5 节表达式,第 7 段:在其成员中包含上述类型之一的聚合或联合类型(递归地,包括子聚合的成员或包含联合)。喜欢:struct custom_list_item { list_item *base; /*...*/ };
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 2011-04-01
  • 2013-07-09
  • 2017-09-10
相关资源
最近更新 更多