【发布时间】:2018-09-13 12:49:18
【问题描述】:
我在解释这个双向链表时遇到了一些麻烦:
struct _dnode {
union {
struct _dnode *head;
struct _dnode *next;
};
union {
struct _dnode *tail;
struct _dnode *prev;
};
};
typedef struct _dnode sys_dlist_t;
typedef struct _dnode sys_dnode_t;
并且在这个列表上定义了更多的函数,例如,查找给定节点是否是列表的头部:
static inline int sys_dlist_is_head(sys_dlist_t *list, sys_dnode_t *node)
{
return list->head == node;
}
现在,我的问题是 -
(i) 为什么我们需要一个联合?那也是,以这种特定的方式?
(ii) 为什么列表中的list 和node 都是相同类型的指针? (见typedef声明)
(iii) 如果我声明这种类型的列表,即。 data_node 项目将是 sys_dlist_t 类型的元素:
struct data_node{
sys_dnode_t node;
int data = 0;
} data_node[2];
我声明了一个节点:
sys_dnode_t *node = NULL;
然后如果我想遍历我的列表以检查 data_node 元素的 data 是否匹配例如数字 3。我可以通过类型转换来做到这一点 node (目前是一个指向类型的指针sys_dnode_t) 指向类型为data_node的指针?
现在,在代码中,这已经完成了,就像:
if (((struct data_node *)node)->data == 3) {
break;
}
这让我很困惑。我可能错过了一些代码来解决这个问题,所以如果您需要更多信息,请告诉我。我们可以将node 指针类型转换为指向包含node 的某个结构,然后访问该结构的其他数据吗?这是如何工作的?
编辑 1: 关于此列表的更多信息:
“列表应该被初始化,这样头和尾指针都指向列表本身。以这种方式初始化列表可以简化向列表添加和删除节点。”
初始化如下:
static inline void sys_dlist_init(sys_dlist_t *list)
{
list->head = (sys_dnode_t *)list;
list->tail = (sys_dnode_t *)list;
}
【问题讨论】:
-
对于
iii,data_node结构是在 C 中模拟继承的一种方式。 -
您确定
sys_dlist_is_head应该与tail进行比较吗? -
@freestyle 哦,你是对的。让我纠正一下
-
在循环双向链表中,这样做非常方便,因为您可以将列表结构视为伪节点。但从你的描述来看,我不明白这个列表是否是循环的。你能显示列表初始化吗?
-
@freestyle 我已经添加了初始化部分,如果我错了请纠正我,但它看起来确实像一个循环的dll
标签: c pointers doubly-linked-list