/**
* double list structure
*/struct rt_list_node
;typedef
struct rt_list_node rt_list_t;
/**< type for lists. */
rt-thread 核心定義了 rt_list_node資料結構,字段 next 和 prev 分別表示通用雙向鍊錶向前和向後的指標元素。不過,值得特別關注的是,rt_list_node 欄位的指標中存放的是另乙個 rt_list_node欄位的位址,而不是含有 list_head 結構的整個資料結構位址
用 rt_list_node資料結構構造的乙個雙向鍊錶如下所示:
* rt_list_for_each -遍歷鍊錶,實際是得到指定鍊錶節點對應的資料物件結構
* @pos: 指向宿主結構的指標,在for迴圈中是乙個迭代變數
* @head: 煉表頭
*/#define rt_list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
通過巨集展開可以看出,實際上是乙個 for 迴圈,利用傳入的pos 作為迴圈變數,從表頭 head開始,逐項向後(next方向)移動 pos ,直至又回到 head,注意:此巨集必要把list_head放在資料結構第一項成員,至此,它的位址也就是結構變數的位址。
/**
* rt_container_of - 獲取type結構體中member成員在這個結構體中的偏移位址
* struct type.
*/#define rt_container_of(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
將巨集展開分析
1。0 將0視作位址2.(
(type *
)0 強制轉換為自定義結構體型別3.(
(type *)0
)->list 4.&
((type *)0
)->list 取得list成員的位址
其中(char*)(ptr) 為將ptr轉為char*型別,這樣就將位址加減操作步長減為乙個位元組,
unsign long將得到的偏移量轉為32/64位數字,將list指標和偏移量相減便得到結構位址,再用(type *)轉為相應型別位址。
巨集作用總結:
現在我們知道container_of()的作用就是通過乙個結構變數中乙個成員的位址找到這個結構體變數的首位址。
container_of(ptr,type,member),這裡面有ptr,type,member分別代表指標、型別、成員。
ptree資料結構分析
使用時包含標頭檔案ptree.h 還要編譯ptree.c檔案。3.1.1.應用 pat tree是目前資訊檢索領域應用十分成功的索引方法。主要在字串子串匹配上有著非常優異的表現,採用半無限長字串作為字串的查詢結構。當有了乙個文件的所有半無限長字串的集合,該文件的任何子串都可以定位為某一半無限長字串的...
Redis資料結構分析
redis有 記憶體資料庫的讚譽,其支援一下幾種資料結構 1.string 2.hashes 3.list 4.set 本文從源 角度來分析各種資料結構在 redis 內部是如何儲存和讀取的。在介紹各種資料結構之前,首先來介紹下 redisobject 這個 struct string hash l...
資料結構 演算法分析
1 冒泡法 冒泡法大家都較熟悉。其原理為從a 0 開始,依次將其和後面的元素比較,若a 0 a i 則交換它們,一直比較到a n 同理對a 1 a 2 a n 1 處理,即完成排序。voidbubble int a,intn 定義兩個引數 陣列首位址與陣列大小 冒泡法原理簡單,但其缺點是交換次數多,...