c - 只要它们包含“下一个”字段,是否可以在 C 中为不同的列表结构编写通用遍历函数?
问题描述
第一次问问题,但我确实环顾了谷歌和 stackoverflow,看看是否有人以前问过类似的问题。在malloc、recasting 和 free中,看起来 OP 提出了类似的问题。但情况更复杂。
我想知道是否可以在 C 中为遍历列表的列表结构创建一个通用函数,因为您知道不同类型的结构将始终具有“下一个”字段。
例如,给定这两个列表类型结构:
typedef struct _list1 {
int value;
list1 *next;
} list1;
typedef struct _list2 {
int value;
char *string;
list2 *next;
} list2;
是否可以创建一个通用void freeList((void *) list)
函数或类似下面的东西?我知道为每个单独的列表分别编写两个免费函数是一件简单的事情。
void freeList((void *) list) {
// Included this because the structs would have different sizes
// so I thought it would be possible to cast it in order to properly dereference the field.
if (sizeof *list == sizeof list1)
*list = (list1) list;
else if (sizeof *list == sizeof list2)
*list = (list2) list;
if (!list) return;
else {
free(list->next);
free(list);
}
}
到目前为止,我对上面显示的代码的实验并不顺利,因为 gcc 会抱怨取消引用void *
指针。
解决方案
制作一个异构列表可以通过使用标记的联合来实现,或者只是一个标记和强制转换:
struct list_item {
struct list_item *next;
enum datatype type;
void *contents;
};
或者
struct list_item {
struct list_item *next;
enum datatype type;
union {
int some_int;
char some_char;
} contents;
};
然后在遍历列表时,您只需type
在使用元素的内容之前验证存储的类型。
本次检查:
if (sizeof *list == sizeof list1)
*list = (list1) list;
else if (sizeof *list == sizeof list2)
*list = (list2) list;
不起作用,因为sizeof
它是一个静态构造:它的值是在编译时定义的。你只是要求sizeof void
.
推荐阅读
- java - 使用 java 流比较两个字符串列表
- agda - 用不相关的术语来证明不相关的事情
- python - 在 Chrome Web 浏览器的 Selenium Python 代码中向 send_keys 发送 UTF-8 消息
- php - 我通过cdn使用了CKEditor,但我无法将数据发送到数据库
- swift - 按下 SwiftUI 时更新按钮 UI
- java - 在终端上使用 -classpath 不起作用
- c++ - 如何正确释放一组指针?
- android - 我可以期望我的应用程序的构造函数在调用我的服务方法之前完全执行吗?
- c# - MVVM RaisePropertyChanged 抛出 InvalidCastException
- python - 熊猫组六个月