gpt4 book ai didi

c - 使用 union/结构在纯 C 中创建广义列表对象

转载 作者:太空宇宙 更新时间:2023-11-04 06:56:52 24 4
gpt4 key购买 nike

链表是许多编程问题的基本有用构建 block 。以下内容应该看起来很熟悉:

typedef struct _list {
struct _list *_next;
} list_t;

#define NULL_LIST ((list_t *)NULL)

void list_push(list_t *element, list_t **list_head);
list_t *list_pop(list_t **list_head);
list_t *list_next(list *list);
int list_length(list_t *list);

我想使用上述例程来操作其他类型的对象,假设这些对象的第一个插槽是 list_t * 链接。也就是说,我想对定义如下的其他内容使用 list_push()list_pop()list_length() 函数:

typedef struct _linked_buffer {
list_t *_next;
uint8_t _bufffer[80];
} linked_buffer_t;

typedef struct _pair {
list_t *_next;
void *_head;
} pair_t;

...等等。我保证所有这些其他“类”在第一个位置共享一个 _link 插槽。

所以我的问题是:有没有办法向 C 编译器保证 linked_buffer_tpair_t 是“一种”list_t 所以我不必每次想对它们使用列表操作时都使用强制转换?

我可以创建隐藏转换的宏:

#define LIST_PUSH(el, head) list_push((list_t *)el, (list_t **)head)

但我想知道是否有更好的方法巧妙地使用 unionstruct 结构来消除对所有内容进行强制转换的需要。

最佳答案

union 将允许一定程度的类型双关,只要其中包含的所有结构都包含相同的初始字段集。

例如:

typedef struct _generic_list {
struct _generic_list *_next;
char type;
} generic_list_t;

typedef struct _linked_buffer {
generic_list_t *_next;
char type;
uint8_t _bufffer[80];
} linked_buffer_t;

typedef struct _pair {
generic_list_t *_next;
char type;
void *_head;
} pair_t;

typedef union _list {
generic_list_t generic_list;
linked_buffer_t buffer;
pair_t pair;
}

因为 union 体的所有成员都有一个 generic_list_t * 作为第一个元素,一个 char 作为第二个元素,你可以安全地访问 union 体的任何成员中的那些元素.

type 字段是一个标志,让您知道哪些 union 成员包含对其其他字段有意义的数据。您需要按照惯例设置该字段。

关于c - 使用 union/结构在纯 C 中创建广义列表对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43214856/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com