Chinaunix首页 | 论坛 | 博客
  • 博客访问: 611217
  • 博文数量: 69
  • 博客积分: 1891
  • 博客等级: 上尉
  • 技术积分: 1359
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-20 23:38
文章分类

全部博文(69)

文章存档

2012年(46)

2011年(23)

分类: LINUX

2011-08-07 13:03:05

先上代码
  1. #define LIST_HEAD_INIT(name) { &(name), &(name) }
  2. #define LIST_HEAD(name) /
  3.     struct list_head name = LIST_HEAD_INIT(name)
不晓得是长时间没有看c的原因,上面的代码一直没搞明白,今天上网查了一下,才搞懂。
这两个宏要放一起看,才会明白,一个一个去理解基本上不可能了。

首先,解决一个代码写法上的问题,
  1. #define LIST_HEAD_INIT(name) { &(name), &(name) }

宏里面的变量要加括号,要不宏展开的时候就会出问题,例如如果写成下面的方式
  1. #define LIST_HEAD_INIT(name){&name,&name}
就会吧LIST_HEAD_INIT_(A+B),展开成{&A+B,&A+B},明显和预期的{&(A+B),&(A+B)}不同。

接着,就是结合后面的宏,整个来理解一下了。首先得了解一下循环链表,

  1. struct list_head {
  2.     struct list_head *next, *prev;
  3. };

在只有一个头节点的时候,这个节点的prev和next都是指向自身的,其实这就是循环链表初始化要做的工作,也就是LIST_HEAD这个宏要完成的工作。那么,把整个宏展开即是:

  1. #define LIST_HEAD(name)/
  2. struct list_head name = {&(name),&(name)}
说时候,分析到这一步的时候,我自己还没弄明白是什么,汗,c语言都忘干了。
其实这就是结构体的初始化方法,即是功能等价下面的代码:
  1. struct list_head head;
  2. head.prev=&head;
  3. head.next=&prev;
这下总算是清楚了,可见linux的代码着实很考验自己的功底阿。

阅读(10749) | 评论(1) | 转发(3) |
1

上一篇:#if 1 妙用

下一篇:Erlang编程指南【3-5】

给主人留下些什么吧!~~

naughty0072014-12-04 15:28:52

最后一行写错了把,head.next=&prev; --> head.next=&head;