说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
内容来源:
目录:
一、list_for_each宏
1.功能简介:
2.源码及注释:
3.源文件测试理解步骤
main.c
Makefile
结果
二、list_for_each_safe宏
1.功能简介:
2.源码及注释:
3.源文件测试理解步骤
main.c
Makefile
结果
三、list_for_each_entry
1.功能简介:
2.源码及注释:
3.源文件测试理解步骤
main.c
Makefile
结果
一、list_for_each宏
1.功能简介:
遍历双链表,不适合与遍历中进行删除节点的操作。
2.源码及注释:
/*
功能:遍历head指向的头链表
参数:
p:指向下一个节点的链表指针
head:头指针
*/
#define list_for_each(p, head) \
for ((p) = (head)->next; (p) != (head); (p) = (p)->next)
3.源文件测试理解步骤
main.c
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
/* 链表节点 */
typedef struct _TestStruct
{
struct list_head list;
int num;
bool pending;
char name;
void *pointer;
}struct_node;
static struct list_head dlist = LIST_HEAD_INIT(dlist); /* 初始化链表: */
int main(int argc, char *argv[])
{
struct_node *tmp = NULL; /* 暂存链表节点结构体 */
struct list_head *head = &dlist; /* 链表表头 */
struct list_head *p = NULL;
int i = 0;
//插入5个数据,使用头插法,类似于栈
for (i = 0; i < 5; i++)
{
tmp = (struct_node *)malloc(sizeof(struct_node));
tmp->num = i;
list_add_tail(&tmp->list, head); /* 插入链表尾部 */
}
/*
功能:遍历head指向的头链表
参数:
p:指向下一个节点的链表指针
head:头指针
*/
list_for_each(p, head)
{
tmp = container_of(p, struct_node, list);
printf("%d \n", tmp->num);
}
printf("------------------------------------\n");
for ((p) = (head)->next; (p) != (head); (p) = (p)->next)
{
tmp = container_of(p, struct_node, list);
printf("%d \n", tmp->num);
}
}
Makefile
TARGET:=test
SRCS:=main.c
OBJS:=$(SRCS:.c=.o)#变量替换函数,将所有*.c文件替换为*.o文件,与OBJS=$(patsubst %.c,%.o,$(SRCS))等效
CC:=gcc#编译器
CFLAGS:=-Wall -std=gnu99#gcc选项
$(TARGET):$(OBJS)
$(CC) -o $@ $^
clean:
rm -rf $(TARGET) $(OBJS)
结果
xsndz@Linux:~/Desktop/list$ ./hello
0
1
2
3
4
------------------------------------
0
1
2
3
4
二、list_for_each_safe宏
1.功能简介:
遍历链表,相较于list_for_each多增加了一个中间参数,保存当前结点的下个结点,避免当前结点删除后找不到下个结点。
2.源码及注释:
/*
功能:遍历链表(可用于删除结点)
参数:
p :指向下一个节点的链表指针
n :指向p的下一个节点的链表指针
head:头指针
*/
#define list_for_each_safe(p, n, head) \
for ((p) = (head)->next, n = (p)->next; (p) != (head); \
(p) = n, n = (p)->next)
3.源文件测试理解步骤
main.c
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "dlist_test.h"
/* 链表节点 */
typedef struct _TestStruct
{
struct list_head list;
int num;
bool pending;
char name;
void *pointer;
}struct_node;
static struct list_head dlist = LIST_HEAD_INIT(dlist); /* 初始化链表: */
int main(int argc, char *argv[])
{
struct_node *tmp = NULL; /* 暂存链表节点结构体 */
struct list_head *head = &dlist; /* 链表表头 */
struct list_head *p = NULL, *n = NULL;
int i = 0;
//插入5个数据,使用头插法,类似于栈
for (i = 0; i < 5; i++)
{
tmp = (struct_node *)malloc(sizeof(struct_node));
tmp->num = i;
list_add_tail(&tmp->list, head); /* 插入链表尾部 */
}
/*
功能:遍历链表(可用于删除结点)
参数:
p :指向下一个节点的链表指针
n :指向p的下一个节点的链表指针
head:头指针
*/
// for ((p) = (head)->next, n = (p)->next; (p) != (head); (p) = n, n = (p)->next)
list_for_each_safe(p,n,head)
{
tmp = list_entry(p, struct_node, list); /* 等价于container_of */
if (tmp->num == 1)
{
list_del(p);
free(p);
}
}
list_for_each(p, head)
{
tmp = container_of(p, struct_node, list);
printf("%d \n", tmp->num);
}
}
Makefile
与上面一致
结果
xsndz@Linux:~/Desktop/list$ ./test
0
2
3
4
三、list_for_each_entry
1.功能简介:
遍历链表的同时可同时获取对应链表的数据结点。
2.源码及注释:
/****** 遍历链表的同时获得结构体指针 ******/
#define list_for_each_entry(p, h, field) \
for ((p) = list_first_entry(h, typeof(*(p)), field); \
&(p)->field != (h); \
(p) = list_entry((p)->field.next, typeof(*(p)), field))
3.源文件测试理解步骤
main.c
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "dlist_test.h"
/* 链表节点 */
typedef struct _TestStruct
{
struct list_head list;
int num;
bool pending;
char name;
void *pointer;
}struct_node;
static struct list_head dlist = LIST_HEAD_INIT(dlist); /* 初始化链表: */
int main(int argc, char *argv[])
{
struct_node *tmp; /* 暂存链表节点结构体 */
struct list_head *head = &dlist; /* 链表表头 */
int i = 0;
//插入5个数据,使用头插法,类似于栈
for (i = 0; i < 5; i++)
{
tmp = (struct_node *)malloc(sizeof(struct_node));
tmp->num = i;
list_add_tail(&tmp->list, head); /* 插入链表尾部 */
}
/*
功能:遍历链表
参数:
tmp:用于存储链表结点
head:头指针
list:节点中链表的指针
*/
list_for_each_entry(tmp, head, list)
{
printf("%d\n",tmp->num);
}
}
Makefile
与上面一致。
结果
xsndz@Linux:~/Desktop/list$ ./test
0
1
2
3
4
评论(0)
您还未登录,请登录后发表或查看评论