offset_of宏和contianer_of宏的功能

来源:互联网 发布:2017年全球数据总量 编辑:程序博客网 时间:2024/06/06 03:20

通过学习朱老师互联网大讲堂整理出来:

1.offset宏的作用

用宏来计算结构体中某一个元素和结构体首元素地址的偏移量。(实质上是通过编译器来计算的)

2.0ffset宏的原理
我们虚拟一个type类型的结构体变量,然后用type.member的方式来访问,这个member元素,继而得到整个menber相对于首地址的偏移量。


宏的定义方法:#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)

理解方法:

1.(TYPE *)0 强制类型转换,把0地址强制转换成一个指针,这个指针指向TYPE类型的结构体变量。

2.((TYPE *)0)->MEMBER)(TYPE *)0是一个TYPE类型结构体变量的指针,通过这个指针来访问结果体变量里面的元素member。

3. &((TYPE *)0)->MEMBER)

这个等效于 &(((TYPE *)0)->MEMBER)),得到menber的地址。


container宏
作用:直到结构体变量中某一个变量,用来反推这个结构体变量的指针,有了container宏,我们可以由结构体中的某个变量的指针得到整个结构体的地址。从而到其他元素的指针。
定义如下:
#define container_of(ptr, type, member) ({\
const typeof(((type *)0)->member) * __mptr = (ptr);\
(type *)((char *)__mptr - offsetof(type, member)); })

container_of宏分为两部分,

第一部分:const typeof( ((type *)0)->member ) *__mptr = (ptr);

通过typeof定义一个member指针类型的指针变量__mptr,(即__mptr是指向member类型的指针),并将__mptr赋值为ptr。

第二部分: (type *)( (char *)__mptr - offsetof(type,member) ),通过offsetof宏计算出member在type中的偏移,然后用member的实际地址__mptr减去偏移,得到type的起始地址,即指向type类型的指针。

第一部分的目的是为了将统一转换为member类型指针。

struct mystruct s1;
struct mystruct *pS = NULL;
char *p = &(s1.b);
printf("s1的指针等于:%p.\n", &s1);
pS = container_of(p, struct mystruct, b);
printf("pS等于:%p.\n", pS);//与&s1得到的是一样的





原创粉丝点击