码迷,mamicode.com
首页 > 其他好文 > 详细

container_of宏和offsetof宏的总结

时间:2018-10-06 16:44:35      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:alt   技术分享   nta   container   clu   \n   def   print   图片   

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 }

运行结果:

技术分享图片

 

container_of宏和offsetof宏的总结

标签:alt   技术分享   nta   container   clu   \n   def   print   图片   

原文地址:https://www.cnblogs.com/reviewing/p/9747382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!