大多数的读者在学习编程语言的时候都不喜欢那些枯燥的文字描述,包括我自己在开始学习编程的时候也是这样,对于代码的热情远远高于文字,所以我在我写东西的时候也不喜欢用枯燥的文字描述来向读者讲解,更喜欢用代码加上适当的文字描述的方式进行讲解,因为有些东西可能用枯燥的文字描述半天还不如实实在在的给读者呈现出一段简单的代码,让读者理解得更加的透彻些。但是并不是说文字描述就没用,文字描述也很重要,只是绝大部分读者都更加的希望直接达到最终的效果,都想跳过那些中间的步骤。接下来我们接着上一篇博客《C语言的那些小秘密之链表(三)》的内容继续讲解linux内核双向循环链表。[cpp] view plaincopystatic inline int list_empty(const struct list_head *head)本文引用地址:http://www.eepw.com.cn/article/273506.htm
{
return head->next == head;
}
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
list_empty()函数和list_empty_careful()函数都是用来检测链表是否为空的。但是稍有区别的就是第一个链表使用的检测方法是判断表头的结点的下一个结点是否为其本身,如果是则返回为true,否则返回false。第二个函数使用的检测方法是判断表头的前一个结点和后一个结点是否为其本身,如果同时满足则返回false,否则返回值为true。说多了可能读者就会没耐心了,那么接下来我来看看下面的代码。
[html] view plaincopy#include
#include
#include "list.h"
typedef struct _stu
{
char name[20];
int num;
struct list_head list;
}stu;
int main()
{
stu *pstu;
stu *tmp_stu;
struct list_head stu_list;
struct list_head *pos;
int i = 0;
INIT_LIST_HEAD(&stu_list);
pstu = malloc(sizeof(stu)*5);
for(i=0;i<5;i++)
{
sprintf(pstu[i].name,"Stu%d",i+1);
pstu[i].num = i+1;
list_add( &(pstu[i].list), &stu_list);
}
list_for_each(pos,&stu_list)
{
tmp_stu = list_entry(pos, stu, list);
printf("student num: %d\tstudent name: %s\n",tmp_stu->num,tmp_stu->name);
}
if(list_empty(&stu_list))
printf("使用list_empty()检测,链表为空\n");
else
printf("使用list_empty()检测,链表非空\n");
if(list_empty_careful(&stu_list))
printf("使用list_empty_careful()检测,链表为空\n");
else
printf("使用list_empty_careful()检测,链表非空\n");
free(pstu);
return 0;
}
运行结果为:
[html] view plaincopyroot@ubuntu:/home/paixu/dlist_node# ./a
student num: 5 student name: Stu5
student num: 4 student name: Stu4
student num: 3 student name: Stu3
student num: 2 student name: Stu2
student num: 1 student name: Stu1
使用list_empty()检测,链表非空
使用list_empty_careful()检测,链表非空
看看代码就知道如何使用了,接下来看看链表的合成。
[html] view plaincopystatic inline vo