以下地址文章解释很好

http://blog.chinaunix.net/uid-27122224-id-3277511.html

对下面的结构体分析

1 struct person
2 {
3 int age;
4 int weight;
5 struct list_head list;
6 };

遍历的方法中用到的一个重要宏,这个宏可以遍历不同类型的结构体

1 /**
2 * list_entry - get the struct for this entry
3 * @ptr: the &struct list_head pointer.
4 * @type: the type of the struct this is embedded in.
5 * @member: the name of the list_struct within the struct.
6 */
7 #define list_entry(ptr, type, member) \
8 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
从person类的链表成员中获取person的方法:
1 struct person *one = list_entry(pos, struct person, list);

也就是:

1 ((struct person *)((char *)(pos) - (unsigned long)(&((struct person *)0)->list)))
我慢慢的分解,首先分成两部分(char *)(pos)减去(unsigned long)(&((struct person *)0)- 
>list)然后转 成(struct person *)类型的指针。 
 
(char *)(pos):是将pos由struct list_head*转 成char* ,这个好理解。 
(unsigned long)(&((struct person *)0)->list):先看最里面的(struct person *)0),它是把0 
地址转 成struct person指针,然后(struct person *)0)->list就是指向list变量,之后是 
&((struct person *)0)->list是取这个变量的地址,最后是(unsigned long)(&((struct person 
*)0)->list)把这个变量的地址值变成一个整形数! 
这么复杂啊,其实说白了,这个(unsigned long)(&((struct person *)0)->list)的意思就是取list 
变量在struct person结构中的偏移量。 
用个图形来说(unsigned long)(&((struct person *)0)->list,如下:
而(unsigned long)(&((struct person *)0)->list就是获取这个offset的值。
((char *)(pos) - (unsigned long)(&((struct person *)0)->list))
就是将pos指针往前移动offset位置,即是本来pos是struct list_head类型,它即是list。即是把 
pos指针往struct person结构的头地址位置移动过去,如上图的pos和虚箭头。 
当pos移到struct person结构头后就转 成(struct person *)指针,这样就可以得到struct person 
*变量了。 

C语言之内核中的struct list_head 结构体的更多相关文章

  1. 全国计算机等级考试二级教程-C语言程序设计_第14章_结构体、共用体和用户定义类型

    函数的返回值是结构体类型 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> struct ...

  2. Golang面向对象编程-struct(结构体)

    Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...

  3. struct socket结构体详解

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://weiguozhihui.blog.51cto.com/3060615/15852 ...

  4. Linux中表示“时间”的结构体和相关函数

    转载于:http://blog.chinaunix.net/uid-25909722-id-2827364.html      Linux中表示“时间”的结构体和相关函数 2011-09-13 17: ...

  5. struct ifreq结构体与ip,子网掩码,网关等信息

    总结一下,今天学习的关于通过socket,ioctl来获得ip,netmask等信息,其中很多内容参照了很多网上的信息,我会一一列出的 我用的这个函数,就是下面这个函数,其中的有一些全局变量,很好懂, ...

  6. Objective-C中经常使用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect

    Objective-C中经常使用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect 1   NSRange NSRange 的原型为 typedef struct _N ...

  7. struct timeval结构体 以及 gettimeofday()函数(转)

    struct timeval结构体 转载地址:http://blog.chinaunix.net/uid-20548989-id-2533161.html 该结构体是Linux系统中定义,struct ...

  8. struct in_addr 结构体

    struct in_addr 结构体: struct in_addr { in_addr_t s_addr; }; 表示一个32位的IPv4地址. in_addr_t一般为32位的unsigned i ...

  9. typedef struct与struct定义结构体

    今天在定义结构体的时候发现typedef struct与struct定义结构体有一些不同之处: 结构也是一种数据类型, 能够使用结构变量, 因此,  象其他 类型的变量一样, 在使用结构变量时要先对其 ...

随机推荐

  1. 洛谷 P3232 [HNOI2013]游走

    链接: P3232 题意: 和上次考试 T4 的简化且无修改一样,经典图上高斯消元求期望. 分析: 要求出每个点的期望出发次数 \(f_i\),每个点度数为 \(d_i\),有 \[f1=\sum\d ...

  2. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)

    一.基于邻接表的Dijkstra算法 如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点.使用邻接表表示,可以使用 BFS ...

  3. 用C++实现的数独解题程序 SudokuSolver 2.6 的新功能及相关分析

    SudokuSolver 2.6 的新功能及相关分析 SudokuSolver 2.6 的命令清单如下: H:\Read\num\Release>sudoku.exe Order please: ...

  4. Ubuntu用apt安装MySQL

    这里以MySQL5.7为例. # 如果之前有安装旧版,先移除sudo apt-get --purge remove mysql-server mysql-client mysql-common # 安 ...

  5. Vue面试题01

    说出vue常用的指令: v-text,  v-html,  v-bind,  v-for,  v-if,  v-else,  v-else-if,   v-show,    v-on, 谈谈你对MVC ...

  6. Discovery直播 | 3D“模”术师,还原立体世界——探秘3D建模服务

    通过多张普通的照片重建一个立体逼真的3D物体模型,曾经靠想象实现的事情,现在, 使用HMS Core 3D建模服务即可实现! 3D模型作为物品在数字世界中的孪生体,用户可以自己拍摄.建模并在终端直观感 ...

  7. Windows 防火墙

    本文防火墙配置是基于 Windows Server 2008 R2 服务器进行叙述,其他Windows服务器版本仅供参考 防火墙安全策略 定义 :安全策略按照一定规则检查数据流是否可以通过防火墙的基本 ...

  8. yum设置取消代理

    unset http_proxy unset https_proxy 暂时取消代理,若永久取消代理,需要修改/etc/yum.conf 去掉 proxy=http://proxyhost:8080

  9. C#生成新浪微博短网址 示例源码

    using System; using System.Collections.Generic; using System.Linq; using System.Text;     using DotN ...

  10. ES6—数值(Number,Math对象)(复习+学习)

    ES6-数值(Number,Math对象)(复习+学习) 每天一学,今天要学习ES6的关于数的扩展以及复习,然后通过看书,查阅资料,以及webAPI来搞清楚遇到的,没见过的对象方法等等,下面为本次学习 ...