核心鍊錶
核心鍊錶與傳統鍊錶不一樣,傳統鍊錶資料域與指標域都是使用者自定義的,而是核心鍊錶資料域是使用者定義,但是指標域是核心煉表頭檔案中已經定義好的了。
核心鍊錶 :頭節點無效,雙向迴圈鍊錶
指標域結構體的結構
核心煉表頭檔案:kernel_list.h
struct list_head
;
設計節點模型struct list_node
;
學習核心鍊錶的增刪改查
初始化空鍊錶?
1)為頭節點申請堆空間
head = (struct list_node *)malloc(sizeof(struct list_node));
2)為頭節點指標域賦值
init_list_head(&(head->list));
解析:kernel_list.h ->49行:
#define init_list_head(ptr)
dowhile(0
)
插入資料到鍊錶中
1)為新的節點申請空間
struct list_node *node =
null
; node =
(struct list_node *
)malloc
(sizeof
(struct list_node)
);
2)為資料域賦值
node->a = num
3)呼叫尾插/頭插的函式
尾插:list_add_tail(&(node->list),&(head->list));
頭插:list_add(&(node->list),&(head->list));
分析插入資料函式介面:
函式一: 將乙個節點new插入兩個節點next與prev之間。
static
inline
void
__list_add
(struct list_head *new,
-> 新節點的指標域結構體的位址
struct list_head *prev,
-> 新節點前乙個節點的指標域結構體的位址
struct list_head *next)
-> 新節點後乙個節點的指標域結構體的位址
函式二: 尾插
list_add_tail – add a new entry -> 在鍊錶尾部新增乙個節點
insert a new entry before the specified head -> 尾插其實相當於在頭節點的前面插入乙個新的節點。
static
inline
void
list_add_tail
(struct list_head *new,
-> 新節點的指標域結構體的位址
struct list_head *head)
-> 頭節點的指標域結構體的位址
函式三: 頭插
list_add – add a new entry
insert a new entry after the specified head.
-> 在頭節點之後插入乙個資料
static
inline
void
list_add
(struct list_head *new,
-> 新節點的指標域結構體的位址
struct list_head *head)
-> 頭節點的指標域結構體的位址
往後遍歷鍊錶
20%
int
show_list_node
(struct list_node *head)
return0;
}或者80%
intshow_list
(struct list_node *head)
return0;
}
往前遍歷鍊錶
int
backward_show_list_node
(struct list_node *head)
return0;
}
分析:
list_entry – get the struct for this entry -> 列出某個節點內容
#define list_entry(ptr, type, member)
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
ptr: the &struct list_head pointer. -> 指向節點中指標域的結構體的位址 p
type: the type of the struct this is embedded in -> 大的結構體的型別 struct list_node
member: the name of the list_struct within the struct -> 小的結構體在大的結構體中變數叫什麼 list
返回值:指向大的結構體的指標。
list_for_each - iterate over a list -> 將整條鍊錶從頭開始往後遍歷一遍
#define list_for_each(pos, head)
for(pos=(head)->next;pos!=(head);pos=pos->next)
list_for_each_prev - iterate over a list backwards -> 將整條鍊錶從頭開始往前遍歷一遍
#define list_for_each_prev(pos, head)
for(pos=(head)->prev;pos!=(head);pos=pos->prev)
list_for_each_entry ->往後遍歷,其實就是list_for_each與list_entry結合。
#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))
struct list_node
;struct list_node a;
fgets
(a.name,10,
stdin);
add_list_tail
(head,
"ggy"
,"12345678901"
,"gzdx",10
,"classmate");
使用者 -> buf:num if
(strncmp
(buf,
"num")==
0)if(
strncmp
(buf,
"relationship")==
0)使用者 ->
10-> 遍歷鍊錶
list_for_each_entry
(p,&
(head->list)
,list)
根據特徵值刪除節點
int
delete_list_node
(struct list_node *head,
int num)
}return0;
}或者intdelete_list_node
(struct list_node *head,
int num)
}return0;
}list_for_each_entry_safe -> 其實是list_for_each_safe與list_entry結合。
list_for_each_entry -> 其實是list_for_each與list_entry結合。
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
釋放整條鍊錶的空間
int
delete_list
(struct list_node *head)
list_del(&
(head->list));
free
(head)
;return0;
}
我所理解的前端
轉眼間,在鵝廠的實習已經過去三個多月,涉及到實習生轉正留用的考核流程也逐步開始了。帶著一堆疑問,以及自己實習期間的心得體會,與導師暢談了一番。他作為資深前端工程師,就前端領域及我個人未來的職業規劃等方面分享了他自己的經驗。這次與導師的溝通讓我受益匪淺,現簡單總結如下。前端知識學習路線 首先,當然是就...
我所理解的陣列
陣列 一 一維陣列 1 陣列的建立 陣列顧名思義是含有相同元素的集合,類似我們高中數學所學習的集合 例如int arr 10 char arr1 2 float arr2 3 double arr3 5 注意 切記 這個中要給常量,不能使用變數。2 陣列的初始化 初始化是指 在陣列的建立同時並賦予合...
我所理解的OpenSocial
昨天在google參加了opensocial的講座,通過三位opensocial工程師的精彩演講,我對這個東西有了一些簡單的理解。下面就把我所理解的opensocial,也算是筆記整理在這裡。1 為什麼會有opensocial?當前社會是乙個網路的社會,當前的網路是乙個社會性的網路,sns遍地開花到...