要熟悉list.h的使用:
---
### 1. **`INIT_LIST_HEAD(head)`**
- **作用**: 初始化一个双向链表的头节点。
- **详细说明**:
- 将链表头节点 `head` 的 `next` 和 `prev` 指针都指向自己,表示链表为空。
- 这是一个宏,通常用于初始化一个空链表。
---
### 2. **`list_add(new, head)`**
- **作用**: 将新节点 `new` 插入到链表头 `head` 之后。
- **详细说明**:
- 新节点 `new` 会成为链表中的第一个节点。
- 操作步骤:
1. 将 `new->prev` 指向 `head`。
2. 将 `new->next` 指向 `head->next`(即原来的第一个节点)。
3. 更新 `head->next` 和 `new->next->prev`,使它们指向 `new`。
---
### 3. **`list_add_tail(new, head)`**
- **作用**: 将新节点 `new` 插入到链表头 `head` 之前。
- **详细说明**:
- 新节点 `new` 会成为链表中的最后一个节点。
- 操作步骤:
1. 将 `new->next` 指向 `head`。
2. 将 `new->prev` 指向 `head->prev`(即原来的最后一个节点)。
3. 更新 `head->prev` 和 `new->prev->next`,使它们指向 `new`。
---
### 4. **`list_add_order(new, head, compare)`**
- **作用**: 将新节点 `new` 按指定的顺序插入到链表中。
- **详细说明**:
- `compare` 是一个函数指针,用于比较两个节点的顺序。
- `compare` 的返回值:
- `0`: 两个节点相等。
- `>0`: 第一个节点大于第二个节点。
- `<0`: 第一个节点小于第二个节点。
- 该函数会从链表尾部向前遍历,找到合适的位置插入 `new`,以保持链表的有序性。
---
### 5. **`list_del(old)`**
- **作用**: 从链表中删除节点 `old`。
- **详细说明**:
- 操作步骤:
1. 将 `old->prev->next` 指向 `old->next`。
2. 将 `old->next->prev` 指向 `old->prev`。
- 删除后,`old` 的 `next` 和 `prev` 指针被设置为特定的魔数(`0xbabebabe` 和 `0xcafecafe`),用于调试。
---
### 6. **`list_del_init(old)`**
- **作用**: 从链表中删除节点 `old`,并初始化 `old`。
- **详细说明**:
- 操作步骤:
1. 将 `old->prev->next` 指向 `old->next`。
2. 将 `old->next->prev` 指向 `old->prev`。
- 删除后,`old` 的 `next` 和 `prev` 指针被重新指向自己,表示 `old` 不再属于任何链表。
---
### 7. **`list_move(list, head)`**
- **作用**: 将节点 `list` 从当前链表中删除,并将其插入到链表头 `head` 之后。
- **详细说明**:
- 先调用 `list_del(list)` 删除 `list`,然后调用 `list_add(list, head)` 将其插入到 `head` 之后。
---
### 8. **`list_move_tail(list, head)`**
- **作用**: 将节点 `list` 从当前链表中删除,并将其插入到链表头 `head` 之前。
- **详细说明**:
- 先调用 `list_del(list)` 删除 `list`,然后调用 `list_add_tail(list, head)` 将其插入到 `head` 之前。
---
### 9. **`list_empty(head)`**
- **作用**: 检查链表是否为空。
- **详细说明**:
- 如果链表头 `head` 的 `next` 指针指向自己,则链表为空,返回 `1`,否则返回 `0`。
---
### 10. **`__list_splice(list, head)`**
- **作用**: 将链表 `list` 插入到链表 `head` 之后。
- **详细说明**:
- 这是一个内部函数,通常由 `list_splice` 和 `list_splice_init` 调用。
- 操作步骤:
1. 将 `list->prev->next` 指向 `head->next`。
2. 将 `head->next->prev` 指向 `list->prev`。
3. 将 `head->next` 指向 `list->next`。
4. 将 `list->next->prev` 指向 `head`。
---
### 11. **`list_splice(list, head)`**
- **作用**: 将链表 `list` 插入到链表 `head` 之后。
- **详细说明**:
- 如果 `list` 为空,则不执行任何操作。
- 调用 `__list_splice(list, head)` 完成插入操作。
---
### 12. **`list_splice_init(list, head)`**
- **作用**: 将链表 `list` 插入到链表 `head` 之后,并初始化 `list`。
- **详细说明**:
- 如果 `list` 为空,则不执行任何操作。
- 调用 `__list_splice(list, head)` 完成插入操作,然后调用 `INIT_LIST_HEAD(list)` 初始化 `list`。
---
### 13. **`__list_append(list, head)`**
- **作用**: 将链表 `list` 追加到链表 `head` 的末尾。
- **详细说明**:
- 这是一个内部函数,通常由 `list_append` 和 `list_append_init` 调用。
- 操作步骤:
1. 将 `head->prev->next` 指向 `list->next`。
2. 将 `list->next->prev` 指向 `head->prev`。
3. 将 `head->prev` 指向 `list->prev`。
4. 将 `list->prev->next` 指向 `head`。
---
### 14. **`list_append(list, head)`**
- **作用**: 将链表 `list` 追加到链表 `head` 的末尾。
- **详细说明**:
- 如果 `list` 为空,则不执行任何操作。
- 调用 `__list_append(list, head)` 完成追加操作。
---
### 15. **`list_append_init(list, head)`**
- **作用**: 将链表 `list` 追加到链表 `head` 的末尾,并初始化 `list`。
- **详细说明**:
- 如果 `list` 为空,则不执行任何操作。
- 调用 `__list_append(list, head)` 完成追加操作,然后调用 `INIT_LIST_HEAD(list)` 初始化 `list`。
---
### 16. **`list_is_last(list, head)`**
- **作用**: 检查节点 `list` 是否是链表 `head` 中的最后一个节点。
- **详细说明**:
- 如果 `list->next` 等于 `head`,则 `list` 是最后一个节点,返回 `1`,否则返回 `0`。
---
### 17. **`list_is_singular(head)`**
- **作用**: 检查链表 `head` 是否只有一个节点。
- **详细说明**:
- 如果链表不为空且 `head->next` 等于 `head->prev`,则链表只有一个节点,返回 `1`,否则返回 `0`。
---
### 18. **`list_replace(old, new)`**
- **作用**: 用新节点 `new` 替换链表中的旧节点 `old`。
- **详细说明**:
- 操作步骤:
1. 将 `new->next` 指向 `old->next`。
2. 将 `new->next->prev` 指向 `new`。
3. 将 `new->prev` 指向 `old->prev`。
4. 将 `new->prev->next` 指向 `new`。
---
### 19. **`list_replace_init(old, new)`**
- **作用**: 用新节点 `new` 替换链表中的旧节点 `old`,并初始化 `old`。
- **详细说明**:
- 调用 `list_replace(old, new)` 完成替换操作,然后调用 `INIT_LIST_HEAD(old)` 初始化 `old`。
---
### 20. **`list_rotate_left(head)`**
- **作用**: 将链表向左旋转一次。
- **详细说明**:
- 将链表的第一个节点移动到链表的末尾。
- 操作步骤:
1. 获取链表的第一个节点 `first`。
2. 调用 `list_move_tail(first, head)` 将 `first` 移动到链表末尾。
---
### 21. **`list_entry(ptr, type, member)`**
- **作用**: 通过链表节点的指针 `ptr` 获取包含该节点的结构体的指针。
- **详细说明**:
- `type` 是结构体类型,`member` 是链表节点在结构体中的成员名。
- 该宏通过指针运算计算出结构体的起始地址。
---
### 22. **`list_first_entry(ptr, type, member)`**
- **作用**: 获取链表的第一个节点的结构体指针。
- **详细说明**:
- `ptr` 是链表头,`type` 是结构体类型,`member` 是链表节点在结构体中的成员名。
- 调用 `list_entry((ptr)->next, type, member)` 获取第一个节点的结构体指针。
---
### 23. **`list_last_entry(ptr, type, member)`**
- **作用**: 获取链表的最后一个节点的结构体指针。
- **详细说明**:
- `ptr` 是链表头,`type` 是结构体类型,`member` 是链表节点在结构体中的成员名。
- 调用 `list_entry((ptr)->prev, type, member)` 获取最后一个节点的结构体指针。
---
### 24. **`list_next_entry(pos, member)`**
- **作用**: 获取链表中当前节点 `pos` 的下一个节点的结构体指针。
- **详细说明**:
- `pos` 是当前结构体的指针,`member` 是链表节点在结构体中的成员名。
- 调用 `list_entry((pos)->member.next, typeof(*pos), member)` 获取下一个节点的结构体指针。
---
### 25. **`list_prev_entry(pos, member)`**
- **作用**: 获取链表中当前节点 `pos` 的前一个节点的结构体指针。
- **详细说明**:
- `pos` 是当前结构体的指针,`member` 是链表节点在结构体中的成员名。
- 调用 `list_entry((pos)->member.prev, typeof(*pos), member)` 获取前一个节点的结构体指针。
---
### 26. **`list_for_each(pos, head)`**
- **作用**: 遍历链表中的每个节点。
- **详细说明**:
- `pos` 是当前节点的指针,`head` 是链表头。
- 从 `head->next` 开始遍历,直到回到 `head`。
---
### 27. **`list_for_each_entry(pos, head, member)`**
- **作用**: 遍历链表中的每个节点,并获取包含该节点的结构体指针。
- **详细说明**:
- `pos` 是当前结构体的指针,`head` 是链表头,`member` 是链表节点在结构体中的成员名。
- 从 `head->next` 开始遍历,直到回到 `head`。
---
### 28. **`list_for_each_entry_safe(pos, n, head, member)`**
- **作用**: 安全地遍历链表中的每个节点,允许在遍历过程中删除节点。
- **详细说明**:
- `pos` 是当前结构体的指针,`n` 是下一个结构体的指针,`head` 是链表头,`member` 是链表节点在结构体中的成员名。
- 使用 `n` 保存下一个节点的指针,以便在删除 `pos` 时不会丢失遍历信息。
---
### 29. **`list_for_each_entry_reverse(pos, head, member)`**
- **作用**: 反向遍历链表中的每个节点,并获取包含该节点的结构体指针。
- **详细说明**:
- `pos` 是当前结构体的指针,`head` 是链表头,`member` 是链表节点在结构体中的成员名。
- 从 `head->prev` 开始遍历,直到回到 `head`。
---
### 30. **`list_for_each_entry_safe_reverse(pos, n, head, member)`**
- **作用**: 安全地反向遍历链表中的每个节点,允许在遍历过程中删除节点。
- **详细说明**:
- `pos` 是当前结构体的指针,`n` 是前一个结构体的指针,`head` 是链表头,`member` 是链表节点在结构体中的成员名。
- 使用 `n` 保存前一个节点的指针,以便在删除 `pos` 时不会丢失遍历信息。
---
### 31. **`list_next(ptr, head, type, member)`**
- **作用**: 获取链表中当前节点 `ptr` 的下一个节点的结构体指针。
- **详细说明**:
- 如果 `ptr->member.next` 等于 `head`,则返回 `NULL`,否则返回下一个节点的结构体指针。
---
### 32. **`list_prev(ptr, head, type, member)`**
- **作用**: 获取链表中当前节点 `ptr` 的前一个节点的结构体指针。
- **详细说明**:
- 如果 `ptr->member.prev` 等于 `head`,则返回 `NULL`,否则返回前一个节点的结构体指针。
---
以上是对 `list.h` 文件中每个函数和宏的详细解释。这些函数和宏提供了对双向链表的完整操作支持,包括初始化、插入、删除、遍历、替换等。