TODOLISTs 还不知道怎么用
头文件位于: sys/queue.h
该库函数全是宏定义,只需要头文件就能工作。该库不是 posix 标准的,源于 BSD

可以通过 man queue 查看详细的说明和用法指引

list 的定义

支持的操作:

  • 插入:在头部插入;在任意一个元素的后面插入
  • 删除:删除任意一个元素
  • 遍历:顺序遍历

链表结构的示意图:

  • 当前链表的结构是单向链表, le_prev 的存在方便删除节点

image.png

创建相关的操作:

  1. // 创建一个头节点
  2. #define LIST_HEAD(name, type) \
  3. struct name { \
  4. struct type *lh_first; \
  5. }
  6. // 初始化链表(头)
  7. #define LIST_INIT(head) do { \
  8. (head)->lh_first = NULL; \
  9. } while (/*CONSTCOND*/0)
  10. // 创建一个链表元素
  11. #define LIST_ENTRY(type) \
  12. struct { \
  13. struct type *le_next; \
  14. struct type **le_prev; \
  15. }

list 的使用

  1. // 链表节点的类型
  2. struct entry {
  3. ...
  4. LIST_ENTRY(entry) entries; /* List. */
  5. ...
  6. }
  7. // 创建一个头节点
  8. LIST_HEAD(listhead, entry) head;
  9. // 注:可以通过这种方式来引用头节点
  10. struct listhead *headp; /* List head. */
  11. // 创建链表节点
  12. struct entry *n1, *n2, *np;
  13. // 初始化链表(头)
  14. LIST_INIT(&head); /* Initialize the list. */
  15. // 在头部插入节点
  16. n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
  17. LIST_INSERT_HEAD(&head, n1, entries);
  18. // 在任意位置插入节点
  19. n2 = malloc(sizeof(struct entry)); /* Insert after. */
  20. LIST_INSERT_AFTER(n1, n2, entries);
  21. // 遍历
  22. for (np = head.lh_first; np != NULL; np = np->entries.le_next)
  23. np-> ...
  24. // 删除元素
  25. while (head.lh_first != NULL) /* Delete. */
  26. LIST_REMOVE(head.lh_first, entries);