在文件系统内核代码中有list_entry函数,详细解说见:
http://blog.csdn.net/chuchuanchuan/article/details/8138009
http://blog.csdn.net/sh_sige/article/details/9814673
list_entry的宏定义如下:
#define list_entry(ptr,type,member) container_of(ptr,type,member),由于containner_of宏中包含offsetof宏,故如下分析这两个宏
1.#define offsetof(TYPE,MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
宏功能:获得一个结构体变量在该结构体中的偏移量。
#include <stdio.h> #define offsetof(TYPE, MEMBER) ((int)(&((TYPE *)0)->MEMBER)) struct _test_{ int x; int y; float z; }; int main(void) { int temp = -1; temp = offsetof(struct _test_, z); printf("temp = %d\n", temp); return 0; }
运行结果:temp=8
即求出结构体成员变量z在结构体中的偏移为8
2 #define container_of(ptr,type,member)({const typeof(((type *)0)->member) *_mptr=(ptr); (type *)((char *)_mptr-offsetof(type,member));})
宏功能:由结构体(type)某成员变量(member)指针(ptr),求出该结构体(type)的首指针。ps 该首指针是包含该成员变量实例的首指针。
#include <stdio.h> #define offsetof(TYPE, MEMBER) ((int)(&((TYPE *)0)->MEMBER)) #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) struct _test_ { int x; int y; int z; }; void Assignment(struct _test_ *t) { t->x = 1; t->y = 2; t->z = 3; } void GetheadPoint(int *tz)//传入成员变量的指针tz,即可以得到该成员变量首指针temp { struct _test_ *p; int temp = -1; p = container_of(tz,struct _test_, z); //根据成员变量的地址获得该结构体的首地址 temp = p->y; //根据首地址获得其中另外一个成员变量的值 printf("line31 = %d\n", temp); } int main(void) { int temp = -1; struct _test_ tmp; //定义一个结构体变量 Assignment(&tmp); //给这个变量赋值 GetheadPoint(&tmp.z); //只传给这个函数一个结构体成员变量的地址 printf("line43 tmp - >x = %d\n", tmp.x); return 0; }
运行结果:由getheadpoint函数得知,由穿入成员变量指针,可以得到该struct实例的首指针