赞
踩
在linux下有一种常用的链表结构。当你需要很多相同结构体,并想把它们连接在一起。方便你增减或者逐个访问的时候,可以用这种结构。当然你也可以直接用链表指针,那么你就必须自己写,初始化链表,添加和删除,循环访问等函数。如果直接用list,就是直接把struct list_head放在你的结构体里。然后包含一个头文件list.h。就可以直接使用现成的链表操作的各种函数(创建, 增加, 删除和遍历)。
struct list_head {
struct list_head *next, *prev;
};
list的结构体,里面只有两个指针。一个向前指,一个向后指
#define LIST_HEAD_INIT(name) { &(name), &(name) }
初始化这个链表指向自己,相当于下面的图
/* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { if (!__list_add_valid(new, prev, next)) return; next->prev = new; new->next = next; new->prev = prev; WRITE_ONCE(prev->next, new);//等价与 prev->next = new } /** * list_add - add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ static inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); }
把新链表new,添加在head之前,相当于下图,把新节点往前放。
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (void *) 0;
entry->prev = (void *) 0;
}
删除链表中的一个节点
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
这个宏, 的作用就是从head开始的第一个函数开始, 遍历这个链表, 用for语句
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#ifndef container_of
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
#endif
这个的作用就是从ptr所指的type的类型,寻找member的这个变量。
大概意思就是,通过ptr的位置找到prt所在结构体的位置。这个结构体的类型是type
typedef struct stud
{
struct list_head list;
char name[MAX_NAME_LEN];
char stu_number[MAX_ID_LEN];
}num_n_stu;
例如这个结构体。通过list的位置,确定stud的位置。
如果想了解细节:请参考这里
/************************************************************************* > File Name: list.c > Author: kayshi > Mail: kayshi2019@qq.com > Created Time: Fri 30 Oct 2020 11:28:54 AM CST ************************************************************************/ #include <stdio.h> #include <string.h> #include "list.h" #define MAX_NAME_LEN 32 #define MAX_ID_LEN 10 typedef struct stud { struct list_head list; char name[MAX_NAME_LEN]; char stu_number[MAX_ID_LEN]; }num_n_stu; typedef struct stud_1 { struct list_head list; char name[MAX_NAME_LEN]; char stu_number[MAX_ID_LEN]; char id; }num_n_stu1; int main(void) { struct list_head head; num_n_stu stu_1; num_n_stu stu_2; num_n_stu1 stu_x; num_n_stu *entry; struct list_head *p; INIT_LIST_HEAD(&head); strcpy(stu_1.name, "lisi"); strcpy(stu_1.stu_number, "10000000"); strcpy(stu_2.name, "kay"); strcpy(stu_2.stu_number, "10000001"); strcpy(stu_x.name, "yan"); strcpy(stu_x.stu_number, "10000002"); list_add(&stu_1.list, &head); list_add(&stu_2.list, &head); list_add(&stu_x.list, &head); //list_del(&stu_2.list); list_for_each(p, &head) { entry= list_entry(p, struct stud, list); printf("name:%s\n", entry->name); printf("stu_number:%s\n", entry->stu_number); } list_del(&stu_1.list); return 0; }
结果
kayshi@ubuntu:~/code/list$ ./a.out
name:yan
stu_number:10000002
name:kay
stu_number:10000001
name:lisi
stu_number:10000000
kayshi@ubuntu:~/code/list$
note:你会发现遍历打印的顺序和加入的顺序相反,这也说明了加入是向head前面加的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。