ホームページ >運用・保守 >Linuxの運用と保守 >Linux のカーネル リンク リストに関するコード例の共有
この記事では、Linux のカーネル リンク リストの例の詳細な説明に関する関連情報を主に紹介します。リンク リストでは、一般的に初期化、挿入、削除、表示、リンク リストの解放、およびノードの検索が必要です。 Linuxのカーネルリンクリストの例を詳しく解説
リンクリストでは、初期化、挿入、削除、表示、リンクリストの解放、ノードの検索などの操作が一般的にあります。以下にこれらの操作を簡単に紹介します。私の能力が不十分なため、いくつかのことを十分に理解していない可能性があり、その結果、特定の間違いが発生する可能性があります。ブロガーの皆様、ご指摘ください。
A. Linux カーネルのリンク リストのいくつかの主要な関数 (誰もが分析できるようにカーネル内のソース コードを以下に示します)
1) 初期化:#define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) // ptr为struct list_head,其中包括两个指针next和prev,这里已经可以看出内核链表是双向循环链表
2) 末尾の挿入:
static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } //尾部插入,传入的参数是新节点中的两个指针和头结点中的两个指针
3) ヘッダー挿入関数
static inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } //头插入函数,传入的参数是新节点中的两个指针和头结点中的两个指针
4) ノード削除関数
static inline void list_del(struct list_head *entry) //传入要删除节点中的指针域 { __list_del(entry->prev, entry->next);//两个参数分别为所删除节点前一个节点和后一个节点 entry->next = (void *) 0;//删除节点后置为空 entry->prev = (void *) 0; }
5) 表示関数(リンクされたリストの情報を印刷したい場合は、印刷関数を自分で記述する必要があります、 printf など、このため実際にはトラバーサル関数であり、表示機能はありません)
#define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) /* 这个函数用于遍历链表 pos为节点指针, head是头结点中的两个指针的地址 member为各节点中的指针域 */
6) リンクされたリストを削除します
#define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) //这里面的pos和n都是list_head指针,n指针是用于在删除时不让链表断链
7) ノードを検索します (これは のトラバーサル関数でもあります)カーネル)
#define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member))
B. これがその使用方法を示すコードです
#include"kernel.h" #include<errno.h> #include<stdio.h> #include<stdlib.h> typedef struct list_node { int data; struct list_head list;//节点的指针域是被封装在struct list_head这个结构体内 //这个结构体中包括struct list_head *next,*prev }*node,node1; node init_head(node head)//初始化空链表 { head = (node)malloc(sizeof(node1));//为节点分配空间 if(head == NULL) { perror("head"); return NULL; } INIT_LIST_HEAD(&(head->list));//#define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0)//调用内核中的初始化函数,传入的参数是 //节点的中两个指针,即struct list_head结构体中的两个指针 return head; } node insert_tail(node head,int data)//尾部插入函数 { node new = (node)malloc(sizeof(node1));//为新节点分配空间 if(new == NULL)//判断一下分配空间是否成功 { perror("new:"); return NULL; } new->data = data; list_add_tail(&(new->list),&(head->list));//调用内核中的从尾部插入的函数,传入的参数为新节点中的两个指针 //和头结点中的两个指针 return 0; } head_insert_node(node head,int data)//头插入函数 { node new;//创建一个新节点 new = (node)malloc(sizeof(node1));//为新节点分配空间 if(new == NULL)//判断一下分配空间是否成功 { perror("new:"); return 0; } new->data = data; list_add(&(new->list),&(head->list));//调用内核中从头插入的函数,传入的参数为新节点的两个指针和头结点的两个指针 return 0; } node search_node(node head,int data)//寻找节点函数 { node p = NULL; list_for_each_entry(p,&(head->list),list) //内核中的遍历函数 { if(p->data == data) //p即为需要找的节点 { printf("found the data:%d\n",p->data); goto OK; } } puts("not found the data!"); return NULL; OK: return p; } int show_node(node tmp) { if(tmp == NULL) { puts("tmp is NULL!"); return -1; } printf("the data is %d\n",tmp->data); return 0; } int delete_node(node head,int data) { node p = NULL; list_for_each_entry(p,&(head->list),list) { if(p->data == data) { printf("found the data which you want to delete!\n"); goto f; } } f: list_del(&(p->list)); free(p); return 0; } int show_list(node head) { node p = NULL; list_for_each_entry(p,&(head->list),list) { printf("data:%d\n",p->data); } return 0; } int delete_list(node head)//删除链表函数 { node p,q; list_for_each_entry_safe(p,q,&(head->list),list)//这是内核中的安全删除函数 { list_del(&(p->list)); free(p); } list_del(&(head->list)); free(head); return 0; } int main(int argc,char **argv) { node head; node tmp; head = init_head(head);//初始化空链表函数 insert_tail(head,45);//从末尾插入函数 insert_tail(head,55); insert_tail(head,65); head_insert_node(head,75);//从头插入函数 show_list(head); //显示链表函数 tmp = search_node(head,55);//寻找结点函数 show_node(head); delete_node(head,55); //show_list(head); delete_list(head);//删除链表函数 return 0; }
以上がLinux のカーネル リンク リストに関するコード例の共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。