现在开始:
- structlist_head {
- struct list_head *next, *prev;
- };
这个就是那个链表的头!是不觉得很奇怪?怎么只有两个指针域,没有数据域呢?其实我现在也纠结这这个问题着呢!没事,咱们先往下看。说不定什么时候,咱就明白了这是怎么一回事情呢。
- #define LIST_HEAD_INIT(name) { &(name), &(name) }
- #defineLIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
这俩是宏没错吧!来看看这个俩到底是个什么意思。
先来看看这个LIST_HEAD_INIT(name),当程序当中出现了这个东西的时候,他立马就会替换成后面的东西,例如出现了:
LIST_HEAD_INIT(headnode);
他立马就会替换成{&(headnode),&(headnode)},有人会问这个到底是什么意思;呵呵不要着急!下面详细的说明:
假设有这么一段C代码
……….
struct list_head headnode ;//定义了一个headnode节点
headnode = LIST_HEAD_INIT(headnode);
……….
那么他是不应该再编译阶段就立马的被替换成这样呢?
……….
struct list_head headnode ;//定义了一个headnode节点
headnode = { &(headnode), &(headnode) };
……….
注意:这里面对标准的C进行了拓展叫:GNU C,这个意思呢就是说,对headnode的两个成员赋值。这赋值之后成了什么样子了呢?看下图:
是不是自己指向了自己?至于为什么可以这么赋值,不是本文讨论的重点,详细的可以www.baidu.com或者www.google.com.hk
其实这里的LIST_HEAD_INIT(name)宏是用来初始化的;
而LIST_HEAD(name)宏则是用来定义+初始化。你看LIST_HEAD(name)宏是不比LIST_HEAD_INIT(name)宏多了这句 struct list_head name ?
记住:LIST_HEAD_INIT(name)宏是用来初始化的;LIST_HEAD(name)宏则是用来定义+初始化。
OK,我们接着往下看:
- static inline void INIT_LIST_HEAD(struct list_head *list)
- {
- list->next = list;
- list->prev = list;
- }
奇怪这里怎么好像又是在初始化,而且还和上面的功能一样。我觉得,他们这样做有如下考虑:1、有些人习惯于调用函数进行初始化,而有的人喜欢代码简洁而直接使用宏来进行初始化,但是不论是那种方式,都达到了一样的功能-----初始化。
在往下看,有关链表添加的
- #ifndef CONFIG_DEBUG_LIST
- static inline void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
- {
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
- }
- #else
- extern void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next);
没有评论:
发表评论