我们阅读一下contiki的源码,list.c(路径是./core/lib/list.h).

#include "lib/list.h"

#define NULL 0

struct list {
struct list *next;
};

这就是核心结构体了,发现了吗?没有数据域,成员就是一个指针。其实这个有点类似Linux里面的链表,对,就是嵌入在结构体里面的那个list.我们继续往下看。

void
list_init(list_t list)
{
*list = NULL;
}

初始化函数,这里要说明的是,list_t 就是void**类型。

在头文件中,有这样的定义:

#define LIST_CONCAT2(s1, s2) s1##s2
#define LIST_CONCAT(s1, s2) LIST_CONCAT2(s1, s2)
#define LIST(name) \
static void *LIST_CONCAT(name,_list) = NULL; \
static list_t name = (list_t)&LIST_CONCAT(name,_list)

其实就是定义一个链表(假设name是hello).   有个变量叫hello_list, 其实是一个void*类型的指针,初始化为NULL,这个链表的名字叫hello, hello是指向hello_list的二级指针。

这里的list是没有头节点的,*hello就得到了第一个元素。因为每个元素都是指针,那么初始化的时候,第一个元素自然为NULL了,表示链表为空。

void *
list_head(list_t list)
{
return *list;
}

返回链表的第一个元素。

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;
}

返回链表的最后一个元素。

void
list_remove(list_t list, void *item)
{
struct list *l, *r; if(*list == NULL) {
return;
} r = NULL;//r用来保存前一个元素
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;
}
}

删除某个元素。(千万要记住,这个链表的元素就是指针!)

void
list_add(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 = NULL; l = list_tail(list);//得到最后一个元素 if(l == NULL) {
*list = item;
} else {
l->next = item;
}
}

把元素追加到末尾。

void
list_push(list_t list, void *item)
{ /* 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;
}

”弹出“最末尾的一个元素。

void *
list_pop(list_t list)
{
struct list *l;
l = *list;
if(*list != NULL) {
*list = ((struct list *)*list)->next;
} return l;
}

“弹出”第一个元素。

其他函数代码都很简单,我们不再赘述。

有的朋友不禁要问了,这样的一个链表,怎么用呢?答案下次揭晓,下次我们结合内存管理,举例说明这个链表的用法。

contiki源码阅读之list的更多相关文章

  1. contiki源码阅读之mmem.c

    上次我们说了list,这次我们就借着mmem.c的代码来用一下这个链表. 代码目录是./core/lib/mmem.c 结构体定义如下 struct mmem { struct mmem *next; ...

  2. Contiki源码结构

    Contiki源码结构 apps目录下,用于存放Application,也就是我们的应用程序放在这个目录下.如webserver,webrowser等,如下图所示. core目录是contiki操作系 ...

  3. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  4. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  5. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  6. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  7. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  8. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  9. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

随机推荐

  1. c#创建Table

    private void BindDatazhangting() { DataTable dt = new DataTable(); dt.Columns.Add("channel" ...

  2. Algorithms - Quick Sort

    印象 图2 快速排序过程 思想 通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 分析 稳定: ...

  3. Block 代码块

    前言 iOS4.0开始,Block横空出世,自他出生开始,就深受Apple和开发者的喜爱.他其实就是c预言的补充,书面点说就是带有自动变量的匿名函数. 其实很多初级开发者也很喜欢使用Block,第一呢 ...

  4. Linux定时任务(crond)

    1.Crond定义 crond是Linux系统中用来定期执行命令或指定程序的一种服务或软件. (1)linux系统自身定期执行的任务(轮询系统日志.备份数据等) (2)用户执行的任务(定时更新同步时间 ...

  5. nagios安装使用指南

    话不多说,下面开始,nagios具体的介绍,可以搜一下,这篇文章为作者在实际操作中整理出来,写出来的都是负责人的内容~ 环境准备 此文档共用2台服务器的配置,操作系统均为centOS6.7,安装用户都 ...

  6. Eclipse中Spring插件的安装及使用

    一.安装流程 1.Help——Install New Software——在Work With中添加地址http://dist.springsource.com/release/TOOLS/updat ...

  7. web flash推流录制测试研究

    用flash as3写了一段推流测试demo,参考srs_publisher和simplest_as3_rtmp_streamer.推流到srs2服务器,录制为flv文件.测试一轮结果如下: Web ...

  8. P1472 奶牛家谱 Cow Pedigrees

    题意:问你指定二叉树有几种 1.高度为k 2.节点数为n 3.每个点的度为0或2 爆搜------->30分QAQ 首先,因为每个节点度为0或2, 所以如果n是偶数直接输出0就行了吧(嘿嘿) 如 ...

  9. docker 部署net core程序 curl访问地址 提示 Connection reset by peer

    最近研究netcore 部署到docker上.在参考https://www.cnblogs.com/subendong/p/8992285.html教程之后,部署成功.但是curl访问对应的主机端口地 ...

  10. composer.json 配置设置

    配置文件的值为 key:val 必须双引号包裹 一.配置文件 名字 name包名称由用户名名称和仓库名称组成包版本限制来请求Monolog软件包 1.0.*.这意味着1.0开发分支中的任何版本,或大于 ...