分类: C/C++
2014-09-28 16:54:54
在C语言中存在一种情况,就是在一个大的结构体中,会有一个小的结构体成员变量(而非指针),这个小的结构体只有两个成员,一个是next,一个是prev,具体如下:
struct list_head {
struct list_head *next;
struct list_head *prev;
}
有一个奇妙的用法是,我们可以根据大结构体中小结构体的地址,得到大结构体的地址:
#define list_entry(entry,type,member) \
((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
对这句话的解析:
将以0地址开始的位置转换为type
*类型,那么它的member的地址,就是相对于0地址的偏移,将entry的地址减去该member的相对偏移量就是大结构体所在的地址,(entry是大结构体中小结构体的地址)然后将其转换成type
* 类型。
ps1:需要从后往前看,entry是list_head
*型,member是list_head型,type是大结构体的类型
ps2 : 我们知道NULL的值为0