原文有错误,已经修改。
/*********************************
拼接两个链表:
1.如果新增的链表只有一个链表头就不做任何处理(因为链表头不包含数据)
2. (head 2 3) + (add 5 6)
==> (head 5 6 2 3) //抛弃链表头add
*********************************/
/* Join two lists. */
static inline void list_splice (list_t *add, list_t *head)
{
/* Do nothing if the list which gets added is empty. */
if (add != add->next)
{
add->next->prev = head; // 5的上一项是head
add->prev->next = head->next; // 6的下一项是2
head->next->prev = add->prev; // 2的上一项是6
head->next = add->next; // head的下一项是5
}
}
/*注意:所有使用list_head结构体的函数使用前必须对参数中list_head结构体初始化!曾经因为list_splice()中head没有初始化导致一进到这个函数就异常重启! */
#include "list.h"
#include <stdio.h>
static LIST_HEAD (head);
static LIST_HEAD (head2);
typedef struct T
{ char *name;
list_t member; // pre, next
}type;
int main(int argc, char **argv)
{
type a,b,c,d;
list_t *ptr; // 节点指针
type *t;
list_t *tmp = NULL;
a.name = "a";
b.name = "b";
c.name = "c";
d.name = "d";
list_add(&a.member, &head); // 紧挨着链表头插入新节点
list_add(&b.member, &head); // 紧挨着链表头插入新节点
list_add(&c.member, &head2); // 紧挨着链表头插入新节点
list_add(&d.member, &head2); // 紧挨着链表头插入新节点
list_splice(&head2, &head);
#if 0
//list_for_each_prev(ptr, &head) 直接就死机了 有删除必须加safe
list_for_each_prev_safe(ptr, tmp, &head)
{ t = list_entry(ptr, type, member);
printf("%s\n", t->name);
list_del(ptr);
}
#endif
/* 结果:
book@gui_hua_shu:~/test$ ./a.out
a
b
c
d
*/
#if 1
//list_for_each(ptr, &head) 直接就死机了 有删除必须加safe
list_for_each_safe(ptr, tmp, &head)
{ t = list_entry(ptr, type, member);
printf("%s\n", t->name);
list_del(ptr);
}
#endif
/* 结果:
book@gui_hua_shu:~/test$ ./a.out
d
c
b
a
*/
return 0;
}