C 鍊錶 linux 如何實現

2021-07-26 16:13:32 字數 2248 閱讀 8586

鍊錶是基本資料結構, 一開始學習資料結構時, 我一般這麼定義, 對應實現從頭或尾插入的處理函式,

struct int_node_old ;

void old_list_insert(struct int_node_old *head, struct int_node_old *new)

void old_list_insert_tail(struct int_node_old *head, struct int_node_old *new)

但是發現, 如果這麼定義的話,每次實現乙個list的結構, 都需要重新對應編寫處理函式, 重複輪子。

想起前段時間, 看到freertos提供的煉表處理方式(《 freertos 任務排程 list 組織 》), 將鍊錶結構定義和實際使用時具體節點資料內容分開定義, 供系統各個模組使用。

檢視linux的原始碼, 發現linux中也為我們提供了相似的實現(原始碼), 把一些共性統一起來。 類是 python 中for_each處理,有些意思。

linux 下的鍊錶定義在檔案include/linux/types.h, 採用的是雙向列表

struct list_head ;
在檔案list.h, 提供了一常用的介面,

根據自己的需求, 定義節點node, 建立 list 並新增節點後, 看到的組織如圖所示 :

利用這個定義, 我定義了乙個自己的list資料結構, 並copy了一些介面實現,感受下,linux 是如何管理鍊錶的。

// list 節點結構定義

struct int_node ;

// 新建乙個list head, 初始化其指標指向自身

#define list_head(name) \

struct list_head name = ;

// 將新節點插入到指定兩個節點之間

static

inline

void __list_add(struct list_head *new,

struct list_head *prev,

struct list_head *next)

// 將新節點插入到煉表頭

static

inline

void list_add(struct list_head *new, struct list_head *head)

// 將新節點插入到鍊錶尾

static

inline

void list_add_tail(struct list_head *new, struct list_head *head)

// 正序遍歷巨集,

#define list_for_each(pos, head) \

for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)

// 逆序遍歷巨集

#define list_for_each_prev(pos, head) \

for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)

// 已知乙個結構的成員,獲取該成員所屬結構體位址

#define container_of(ptr, type, menber) \

(type *)((char*)ptr - (char*) &(((type *)0)->menber))

#define list_entry(ptr, type, menber) container_of(ptr, type, menber)

通過container_of, 可以取得我們當前正在操作鍊錶所屬結構體位址,進而對具體資料進行處理, 利用c語言的乙個小技巧, 把結構體投影到位址為0的地方,那麼成員的絕對位址就是偏移量, 得到偏移量後,根據成員的p指標反算出結構體的首位址。 另外一種做法是定義list_head中, 包含乙個成員變數,指向其所屬,freertos是如此做的。

int main(void)

printf("\n");

list_for_each_prev(plist, &my_list)

printf("\n");

return

0;}

雖然比較簡單,記錄下,學習linux **, 程式設計師的自我修養。

如何實現鍊錶?

鍊錶是一種物理儲存單元上非連續 非順序的儲存結構,資料元素的邏輯順序是通過鍊錶中的指標鏈結次序實現的。鍊錶由一系列結點 鍊錶中每乙個元素稱為結點 組成,結點可以在執行時動態生成。每個結點包括兩個部分 乙個是儲存資料元素的資料域,另乙個是儲存下乙個結點位址的指標域。操作複雜。由於不必須按順序儲存,鍊錶...

php mysql 鍊錶 php如何實現鍊錶?

php實現鍊錶的方法 首先定義乙個節點類,為 function construct val null 然後實現鍊錶的實現類,為 function construct this dummyhead new nod php實現鍊錶的方法 首先定義乙個節點類class node public val pu...

鍊錶C 實現

node.h 第乙個檔案 ifndef node h define node h define true 1 define false 0 define ok 1 define error 0 define null 0 define flag 1 class node endif node h l...