Chinaunix首页 | 论坛 | 博客
  • 博客访问: 620398
  • 博文数量: 168
  • 博客积分: 1053
  • 博客等级: 少尉
  • 技术积分: 1187
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-30 17:20
个人简介

公众号【嵌入式er笔记】持续记录和分享C/C++、Linux、ARM、Android、IoT等技术相关知识,以及职场、生活经验和感悟。

文章分类

全部博文(168)

分类: LINUX

2013-08-14 10:20:38

原文地址:LIST_HEAD_INIT 作者:kenvifire

先上代码
  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的代码着实很考验自己的功底阿。

阅读(1592) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~