自己实现linux的双链表:
1) MEMBER_OFFSET(type, member) 获取数据成员在数据结构type中的偏移值
2) LIST_ENTRY(ptrToList, type, member) 数据成员的指针地址和成员名字,获取整个数据结构地址
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct listNode{
struct listNode *next;
struct listNode *pre;
};
void InitListHead(struct listNode *head)
{
head->pre = head;
head->next = head;
}
void AddToList(struct listNode *pre, struct listNode *next, struct listNode *node)
{
pre->next = node;
node->pre = pre;
next->pre = node;
node->next = next;
}
void AddToHead(struct listNode *head, struct listNode *new)
{
AddToList(head, head->next, new);
}
void AddToTail(struct listNode *head, struct listNode *new)
{
AddToList(head->pre, head, new);
}
#define LIST_FOR_EACH(head, n) for (n = (head)->next; n != head; n = n->next)
#define LIST_FOR_EACH_SAFE(head, n, m) for (n = (head)->next, m = n->next; n != head; n = m, m = n->next)
#define MEMBER_OFFSET(type, member) ((size_t) &((type *)0)->member)
#define LIST_ENTRY(ptrToList,type, member) ({\
const typeof(((type *)0)->member) * _mptr = (ptrToList);\
(type *)((char *)_mptr - MEMBER_OFFSET(type, member));})
typedef struct {
int key;
int value;
struct listNode node;
}MyNode;
void AddMyDataPre(struct listNode *head, int key, int value)
{
MyNode *nodeData = malloc(sizeof(MyNode));
nodeData->key = key;
nodeData->value = value;
AddToHead(head, &(nodeData->node));
}
void AddMyDataTail(struct listNode *head, int key, int value)
{
MyNode *node = malloc(sizeof(MyNode));
node->key = key;
node->value = value;
AddToTail(head, &(node->node));
}
void DelFromList(struct listNode *node)
{
node->pre->next = node->next;
node->next->pre = node->pre;
}
void ShowData(MyNode *ptr)
{
printf("key:%08d value:%08d\n", ptr->key, ptr->value);
}
int main()
{
struct listNode head;
struct listNode *n;
struct listNode *m;
InitListHead(&head);
AddMyDataPre(&head, 1, 1);
AddMyDataPre(&head, 2, 2);
LIST_FOR_EACH(&head, n){
MyNode *tmpData = LIST_ENTRY(n, MyNode, node);
ShowData(tmpData);
}
LIST_FOR_EACH_SAFE(&head, n, m) {
DelFromList(n);
MyNode *tmpData = LIST_ENTRY(n, MyNode, node);
ShowData(tmpData);
free(n);
}
return 0;
}