//
// 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 */
<span style="font-family: Arial, Helvetica, sans-serif;">实例:</span>
#include <stdio.h>
#include <stdlib.h>
#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;
}