我正在从FreeBSD学习sys/queue.h
,我有一个问题:
在sys/queue.h
中,LIST_ENTRY
的定义如下:
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
为什么它保持上一个下一个元素的地址(struct type **le_prev
),而不仅仅是上一个元素,如struct type *le_prev
?
答案 0 :(得分:8)
如果你从一开始就读过queue.h文件,你可以 得到以下评论:
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
so list,提供O(1)插入和删除, 但只能向前遍历。要实现这一点,你只需要 引用前面的下一个指针,正是这样 实现。
答案 1 :(得分:0)
让我试着解释一下。
实际上**le_prev*
提供了由sys / queue.h定义的列表到insert_before
的列表,而转发列表却不能。与insert_before
相比,insert_after
可以在前向列表或列表中很好地实现。因此列表更具功能性。
insert_before(entry* list_elem, entry* elem, type val)
{
elem->next = list_elem;
*(list->prev) = elem;
elem->prev = *(list->prev);
list_elem->prev = elem->next;
}
insert_after(entry* list_elem, entry* elem, type val)
{
if( ((elem)->next= (list_elem)->next) != NULL ) {
(elem_list)->next->prev = &(elem)->next;
}
(list_elem)->next = elem;
elem->prev = &(list_elem)->next;
}