container_of宏和offsetof宏的总结

1、offsetof 宏

 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

将地址0强制转换为type类型的指针,从而得到结构体成员member相对于结构体起始地址的偏移量。

2、container_of 宏 

 #define container_of(ptr, type, member) ({   \
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
     (type *)( (char *)__mptr - offsetof(type,member) );})

作用:结构体(type)的成员member地址 减去 member在type中的偏移 得到该结构体(type)的起始地址。

container_of 宏分为两部分:

 第一部分:const typeof( ((type *)0)->member ) *__mptr = (ptr);
   通过typeof定义一个member指针类型的指针变量__mptr,并将__mptr赋值为ptr。
 第二部分:(type *)( (char *)__mptr - offsetof(type,member) );
   通过offsetof宏计算出member在type中的偏移,
   然后用member的实际地址__mptr减去偏移,得到type的起始地址,即指向type类型的指针。

测试代码:

 1 #include <stdio.h>
 2 
 3 #define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER)
 4 
 5 #define container_of(ptr, type, member) ({  \
 6     const typeof( ((type *)0)->member) *__mptr = (ptr);  \
 7     (type *)( (char *)__mptr - offsetof(type, member));})
 8 
 9 typedef struct{
10     int id;
11     char name[20];
12     int age;
13 }student;
14 
15 int main()
16 {
17     printf("%lu\n", offsetof(student, id));
18     printf("%lu\n", offsetof(student, name));
19     printf("%lu\n", offsetof(student, age));
20 
21     student s;
22     s.age = 20;
23     student *ps = container_of(&s.age, student, age);
24     printf("%d\n", ps->age);
25     printf("%p\n", &s);
26     printf("%p\n", ps);
27     
28     return 0;
29 }

运行结果:

猜你喜欢

转载自www.cnblogs.com/reviewing/p/9747382.html