// // coreList.h // hehe // // Created by yin on 16/8/24. // Copyright © 2016年 yin. All rights reserved. // #ifndef coreList_h #define coreList_h #define LIST_POISON1 ((struct list_head *) 0x0) #define LIST_POISON2 ((struct list_head *) 0x0) struct list_head { struct list_head *next, *prev;/* next後指針,prev前指針 */ }; /** \brief 鏈表頭初始化 */ #define LIST_HEAD_INIT(name) { &(name), &(name) } /** \brief 鏈表頭初始化 */ #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) /** \brief 初始化鏈表頭 \param[in] ptr 鏈表結構指針 \return 無 */ #define INIT_LIST_HEAD(ptr) { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } static inline void __list_add(struct list_head *new_head, struct list_head *prev, struct list_head *next) { /* 添加到鏈表 */ next->prev = new_head; new_head->next = next; new_head->prev = prev; prev->next = new_head; } /** \brief 添加新的鏈表元素到鏈表頭 \param[in] new_head 待添加鏈表結構指針 \param[in] head 鏈表頭結構指針 \\return 無 */ static inline void list_add(struct list_head *new_head, struct list_head *head) { /* 添加到鏈表頭 */ __list_add(new_head, head, head->next); } /** \brief 添加新的鏈表元素到鏈表尾 \param[in] new_head 待添加鏈表結構指針 \param[in] head 鏈表頭結構指針 \\return 無 */ static inline void list_add_tail(struct list_head *new_head, struct list_head *head) { /* 添加到鏈表尾 */ __list_add(new_head, head->prev, head); } static inline void __list_del(struct list_head * prev, struct list_head * next) { /* 從鏈表刪除 */ next->prev = prev; prev->next = next; } /** \brief 從鏈表刪除節點 \param[in] entry 待刪除鏈表結構指針 \\return 無 */ static inline void list_del(struct list_head *entry) { /* 刪除鏈表記錄 */ __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } /** \brief 判斷鏈表是否為空 \param[in] head 鏈表頭指針 \return 無 */ static inline int list_empty(struct list_head *head) { /* 判斷鏈表是否為空 */ return head->next == head; } /** \brief 刪除指定鏈表元素並初始化 \param[in] entry 待刪除並初始化的鏈表元素 \\return 無 */ static inline void list_del_init(struct list_head *entry) { __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); } static inline void __list_splice(struct list_head *list, struct list_head *head) { struct list_head *first = list->next; struct list_head *last = list->prev; struct list_head *at = head->next; first->prev = head; head->next = first; last->next = at; at->prev = last; } /** \brief 合並鏈表 \param[in] list 待合並的新鏈表 \param[in] head 合並的舊鏈表 \\return 無 */ static inline void list_splice(struct list_head *list, struct list_head *head) { if (!list_empty(list)) __list_splice(list, head); } /** \brief 合並鏈表並初始化新鏈表頭 \param[in] list 待添加的新鏈表頭 \param[in] head 合並新鏈表的位置 \\return 無 */ static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head); INIT_LIST_HEAD(list); } } /** \brief 轉移鏈表元素到新鏈表頭 \param[in] list 舊鏈表的鏈表頭 \param[in] head 新鏈表的鏈表頭 \\return 無 */ static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add(list, head); } /** \brief 轉移鏈表元素到新鏈表尾 \param[in] list 舊鏈表的鏈表頭 \param[in] head 新鏈表的鏈表頭 \\return 無 */ static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add_tail(list, head); } /** \brief 通過鏈表地址獲得結構體指針 \param[in] ptr 鏈表結構指針 \param[in] type 結構體類型 \param[in] member 結構體中鏈表所表示的字段 \return 無 */ #define list_entry(ptr, type, member) ((type *)(void *)((char *)(ptr) - (char*)(void*)(&((type*)0)->member))) /** \brief 向後遍歷鏈表 \attention 遍歷過程中不允許刪除鏈表元素 \param[in] pos 當前所指向的鏈表節點 \param[in] head 鏈表頭指針 \return 無 */ #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = pos->next) /** \brief 從pos的下一個節點, 向後遍歷鏈表 \attention 遍歷過程中不允許刪除鏈表元素 \param[in] pos 指定的鏈表節點 \param[in] head 鏈表頭指針 \return 無 */ #define list_for_each_continue(pos, head)\ for ((pos) = (pos)->next; (pos) != (head); (pos) = (pos)->next) /** \brief 向後遍歷鏈表 \attention 用戶必須自行在遍歷過程中刪除鏈表元素,否則將導致死循環 \param[in] pos 當前所指向的鏈表節點 \param[in] head 鏈表頭指針 \return 無 */ #define list_for_del_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = (head)->next) /** \brief 向後遍歷鏈表 \attention 遍歷過程中支持用戶自行刪除鏈表元素,用戶可自行決定是否刪除 \param[in] pos 當前所指向的鏈表節點 \param[in] n 循環臨時值 \param[in] head 鏈表頭指針 \return 無 */ #define list_for_each_safe(pos, n, head) for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next) /** \brief 從pos的下一個節點開始, 向後遍歷鏈表 \attention 遍歷過程中支持用戶自行刪除鏈表元素,用戶可自行決定是否刪除 \param[in] pos 指定的鏈表節點 \param[in] n 循環臨時值 \param[in] head 鏈表頭指針 \return 無 */ #define list_for_each_safe_continue(pos, n, head)\ for ((pos) = (pos)->next, n = (pos)->next; pos != (head); \ (pos) = n, n = (pos)->next) #define list_for_each_prev_safe(pos, p, head)\ for(pos = (head)->prev, p = pos->prev; pos != (head);\ pos = p, p = pos->prev) /** \brief 向前遍歷鏈表 \attention 遍歷過程中不允許刪除鏈表元素 \param[in] pos 當前所指向的鏈表節點 \param[in] head 鏈表頭指針 \return 無 */ #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; pos != (head); pos = pos->prev) /** \brief 向後遍歷鏈表,並獲得鏈表所在結構體指針 \attention 遍歷過程中不允許刪除鏈表元素 \param[in] pos 鏈表所在結構體指針 \param[in] type 結構體類型 \param[in] head 鏈表頭指針 \param[in] member 結構體成員名 \return 無 */ #define list_for_each_entry(pos, head, member,type) \ for (pos = list_entry((head)->next, type, member); \ &pos->member != (head); \ pos = list_entry(pos->member.next, type, member)) #define INIT_LIST_NODE(ptr) { (ptr)->next = LIST_POISON1; (ptr)->prev = LIST_POISON2; } #define IS_LIST_NODE_INIT(ptr) ((LIST_POISON1 == (ptr)->next) && (LIST_POISON2 == (ptr)->prev)) #endif /* coreList_h */
實例:
#include#include #include "coreList.h" typedef struct tagCAR_S { struct list_head node; int id; }CAR_S; typedef struct tagPOLICE_S { int serNum; struct list_head carHead; int carNum; }POLICE_S; int main(void) { struct list_head *cur = NULL; POLICE_S *p = NULL; CAR_S *car = NULL; p = (POLICE_S *)malloc(sizeof(POLICE_S)); if (NULL == p) { return -1; } INIT_LIST_HEAD(&p->carHead); for (int i = 0; i < 10; ++i) { car = (CAR_S*)malloc(sizeof(CAR_S)); if (NULL == car) { return -1; } car->id = i; list_add_tail(&car->node, &p->carHead); p->carNum++; } list_for_each(cur, &p->carHead) { car = list_entry(cur, CAR_S, node); printf("id = %d\n", car->id); } return 0; }