contiki之list(2)

有了list(1)的分析,list.c文件接下来的函数都好说了
/*********************************list.c*******************************/
值得注意的是,list.c里传入函数的参数里,都是list_t类型,也就是说是指向链表头指针的指针。
void list_init(list_t list)
{
*list = NULL;
}
通俗易懂,也就是说把指向链表头的指针赋值为NULL
void * list_head(list_t list)
{
return *list;
}
返回链表的头指针
void list_copy(list_t dest, list_t src)
{
*dest = *src;
}
复制链表,可以看到只是把链表头指针赋值给另外一个指针而已。
void * list_tail(list_t list)
{
struct list *l;
if(*list == NULL) {
return NULL;
}
for(l = *list; l->next != NULL; l = l->next);
return l;
}
找到链表的尾,并返回指向该单元的指针。先判断指向链表头的指针是不是空,如果不是空,注意了,这个时候链表头指针指向的将是一个带有具体数据的结构体,该结构体第一个成员是next。还记得list(1)讲的么,因为我们在函数里把指向这个结构体的指针强转成struct list*,所以就算原来的结构体除了next成员还有其他数据结构,我们还是只能访问到next成员而已。接下来的for循环,就是常规的链式检索,找到一个链表成员,它的next变量是NULL的既是尾了。只要把这个函数返回的指针用原来带有数据的结构体类型强转解引用就可以正常访问里面的数据了。
void list_push(list_t list, void *item)
{
/* struct list *l;*/
/* Make sure not to add the same element twice */
list_remove(list, item);
((struct list *)item)->next = *list;
*list = item;
}
这个函数把新加入的成员放在链表头。
void * list_chop(list_t list)
{
struct list *l, *r;
if(*list == NULL) {
return NULL;
}
if(((struct list *)*list)->next == NULL) {
l = *list;
*list = NULL;
return l;
}
for(l = *list; l->next->next != NULL; l = l->next);
r = l->next;
l->next = NULL;
return r;
}
这个函数返回指向链表最后一个成员的指针,并把最后一个成员从链表里剔除。
if(((struct list *)*list)->next == NULL)这句是为了判断这个链表是不是才只有一个成员而已。如果才一个成员,那么剔除最后一个成员后就得让指向链表头的指针变成NULL
for(l = *list; l->next->next != NULL; l = l->next);这句执行完I将是指向倒数第二个成员的指针。
void * list_pop(list_t list)
{
struct list *l;
l = *list;
if(*list != NULL) {
*list = ((struct list *)*list)->next;
}
return l;
}
这个函数返回指向链表第一个成员的指针,并把第一个成员从链表里剔除。
void list_remove(list_t list, void *item)
{
struct list *l, *r;
if(*list == NULL) {
return;
}
r = NULL;
for(l = *list; l != NULL; l = l->next)
{
if(l == item)
{
if(r == NULL)
{
/* First on list */
*list = l->next;
}
else
{
/* Not first on list */
r->next = l->next;
}
l->next = NULL;
return;
}
r = l;
}///end of for
}
这个函数从链表里找到给定的成员,把它从链表里剔除。r变量是为了保存上一次for循环指向的成员。这样子当找到给定的成员的是,我们可以这个成员的前面一个成员,即r的next指向给定成员的下一个成员,为了安全把找到的给定成员的next变量设置为NULL然后return
int list_length(list_t list)
{
struct list *l;
int n = 0;
for(l = *list; l != NULL; l = l->next) {
++n;
}
return n;
}
这个就简单了,数一数链表里总共有多少个成员
void list_insert(list_t list, void *previtem, void *newitem)
{
if(previtem == NULL) {
list_push(list, newitem);
} else {
((struct list *)newitem)->next = ((struct list *)previtem)->next;
((struct list *)previtem)->next = newitem;
}
}
这个函数也很简单,在把新成员newitem插入到指定成员previtem后面。如果指定成员是NULL,则插入到链表头
void * list_item_next(void *item)
{
return item == NULL? NULL: ((struct list *)item)->next;
}
最后一个函数,返回给定成员的下一个成员指针。

猜你喜欢

转载自blog.csdn.net/xbzlxtz/article/details/77532876