#include <stdio.h>
#include <string.h>
#include <malloc.h>
//通用链表结构
struct list_head {
struct list_head *next, *prev;
};
typedef struct tag_student
{
int age;
double score;
struct list_head list;
}STU;
#define PT(stVar) printf("%d %.2f \n", (stVar)->age, (stVar)->score)
//定义并初始化链表头
#define HEAD_INIT(head) struct list_head head = {&head, &head}
//从表头添加新节点
static void addNode(struct list_head *newNode, struct list_head *head)
{
newNode->next = head->next;
newNode->prev = head;
head->next->prev = newNode;
head->next = newNode;
}
//遍历链表(不能用于遍历时删除节点)
#define LIST_SEARCH_FOR_FORWARD(head, pos) for((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
#define LIST_SEARCH_FOR_BACKWARD(head, pos) for((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)
//遍历链表(只能用于遍历时删除节点)
#define LIST_SEARCH_FOR_DEL_FORWARD(head, pos, bak) for(pos = (head)->next, bak = pos->next; pos != (head); pos = bak, bak = bak->next)
#define LIST_SEARCH_FOR_DEL_BACKWARD(head, pos, bak) for(pos = (head)->prev, bak = pos->prev; pos != (head); pos = bak, bak = bak->prev)
//根据list成员获取结构体的指针
#define LIST_ENTRY(node, list, type) (type *)((char *)(node) - (unsigned long)&(((type *)0)->list))
//删除一个节点
static void NodeDel(struct list_head *Node)
{
Node->prev->next = Node->next;
Node->next->prev = Node->prev;
}
int main(int argc, char *argv[])
{
int i=0;
struct list_head *pos = NULL;
struct list_head *bak = NULL;
HEAD_INIT(head);
//添加节点
for(i = 0; i < 5; i ++)
{
STU *tmp = NULL;
tmp = (STU *)calloc(1, sizeof(STU));
tmp->age = 35+i;
tmp->score = 35.6+i;
addNode(&tmp->list, &head);
}
LIST_SEARCH_FOR_BACKWARD(&head, pos)
{
STU *temp = NULL;
temp = LIST_ENTRY(pos, list, STU);
PT(temp);
}
//删除年龄为37的节点
LIST_SEARCH_FOR_DEL_BACKWARD(&head, pos, bak)
{
STU *temp = NULL;
temp = LIST_ENTRY(pos, list, STU);
if(temp->age == 37)
{
NodeDel(&temp->list);
free(temp);
}
}
printf("after del the node whose age is 37\n");
//删除年龄为37的节点后
LIST_SEARCH_FOR_BACKWARD(&head, pos)
{
STU *temp = NULL;
temp = LIST_ENTRY(pos, list, STU);
PT(temp);
}
//释放链表
LIST_SEARCH_FOR_DEL_BACKWARD(&head, pos, bak)
{
STU *temp = NULL;
temp = LIST_ENTRY(pos, list, STU);
NodeDel(&temp->list);
free(temp);
}
//释放链表后再去遍历,看是效果
LIST_SEARCH_FOR_BACKWARD(&head, pos)
{
printf("a\n");
}
LIST_SEARCH_FOR_FORWARD(&head, pos)
{
printf("b\n");
}
return 0;
}