container_of宏
2016-05-22 19:29
399 查看
17.container_of宏
这个宏的是根据传进去的结构体中的某个成员的指针来返回该结构体的首地址,以后我们就可以通过结构体的首地址来方便访问该结构体中的任何成员了。
这个宏工作的原理:先用typedef得到member元素的类型定义成一个指针,然后用这个指针减去该元素相对于整个结构体变量的偏移量(偏移量用offsetof宏得到的),减去之后得到的就是整个结构体变量的首地址了,再把这个地址强制类型转换为type*即可。
#define container_of(ptr, type, member) ({
\
const typeof(((type *)0) ->member)
* __mptr = (ptr);
\
(type *)((char *)__mptr - offsetof(type, member));})
解析:
typeof(a):由变量a得到a的类型,typeof就是由变量名得到变量数据类型的。
offsetof(type, member):得到type数据结构里的元素member相对该数据结构的首地址的偏移量。
(type *)0:将地址0强制转换成(type)类型的指针;
((type *)0) ->member):将该指针指向member成员;
typeof(((type *)0) ->member):获取member成员这个变量的类型;
const typeof(((type *)0) ->member) *
__mptr:用来定义一个指针变量__mptr;
const typeof(((type *)0) ->member) *
__mptr = (ptr):__mptr指向ptr;
(char *)__mptr:取__mptr的地址;
offsetof(type, member)):member成员相对数据结构体首地址的偏移量;
(char *)__mptr - offsetof(type, member):得到数据结构的首地址;
(type *)(char *)__mptr - offsetof(type, member):将改地址转换为type *型的。
struct mystruct
{
char a;
// 0
int b;
// 4
short c;
// 8
};
// TYPE是结构体类型,MEMBER是结构体中一个元素的元素名
// 这个宏返回的是member元素相对于整个结构体变量的首地址的偏移量,类型是int
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
// ptr是指向结构体元素member的指针,type是结构体类型,member是结构体中一个元素的元素名
// 这个宏返回的就是指向整个结构体变量的指针,类型是(type *)
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr);
\
(type *)((char *)__mptr - offsetof(type, member)); })
int main(void)
{
struct mystruct s1;
struct mystruct *pS = NULL;
short *p = &(s1.c);
// p就是指向结构体中某个member的指针
printf("s1的指针等于:%p.\n", &s1);
// 问题是要通过p来计算得到s1的指针
pS = container_of(p, struct mystruct, c);
printf("pS等于:%p.\n", pS);
}
这个宏的是根据传进去的结构体中的某个成员的指针来返回该结构体的首地址,以后我们就可以通过结构体的首地址来方便访问该结构体中的任何成员了。
这个宏工作的原理:先用typedef得到member元素的类型定义成一个指针,然后用这个指针减去该元素相对于整个结构体变量的偏移量(偏移量用offsetof宏得到的),减去之后得到的就是整个结构体变量的首地址了,再把这个地址强制类型转换为type*即可。
#define container_of(ptr, type, member) ({
\
const typeof(((type *)0) ->member)
* __mptr = (ptr);
\
(type *)((char *)__mptr - offsetof(type, member));})
解析:
typeof(a):由变量a得到a的类型,typeof就是由变量名得到变量数据类型的。
offsetof(type, member):得到type数据结构里的元素member相对该数据结构的首地址的偏移量。
(type *)0:将地址0强制转换成(type)类型的指针;
((type *)0) ->member):将该指针指向member成员;
typeof(((type *)0) ->member):获取member成员这个变量的类型;
const typeof(((type *)0) ->member) *
__mptr:用来定义一个指针变量__mptr;
const typeof(((type *)0) ->member) *
__mptr = (ptr):__mptr指向ptr;
(char *)__mptr:取__mptr的地址;
offsetof(type, member)):member成员相对数据结构体首地址的偏移量;
(char *)__mptr - offsetof(type, member):得到数据结构的首地址;
(type *)(char *)__mptr - offsetof(type, member):将改地址转换为type *型的。
struct mystruct
{
char a;
// 0
int b;
// 4
short c;
// 8
};
// TYPE是结构体类型,MEMBER是结构体中一个元素的元素名
// 这个宏返回的是member元素相对于整个结构体变量的首地址的偏移量,类型是int
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
// ptr是指向结构体元素member的指针,type是结构体类型,member是结构体中一个元素的元素名
// 这个宏返回的就是指向整个结构体变量的指针,类型是(type *)
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr);
\
(type *)((char *)__mptr - offsetof(type, member)); })
int main(void)
{
struct mystruct s1;
struct mystruct *pS = NULL;
short *p = &(s1.c);
// p就是指向结构体中某个member的指针
printf("s1的指针等于:%p.\n", &s1);
// 问题是要通过p来计算得到s1的指针
pS = container_of(p, struct mystruct, c);
printf("pS等于:%p.\n", pS);
}
相关文章推荐
- hdu 1151 Air Raid【最小路径覆盖】
- FAILED: InvalidConfigurationException hive.server2.authentication can't be none in non-testing mode
- main方法的理解
- uva1450-Airport
- TensorFlow人工智能引擎入门教程所有目录
- map与vector---Email Aliases
- 人工智能之机器学习常见算法
- 安装CENTOS 6.5 32位(CentOS-6.5-i386)+postfix+dovecot+openwebmail passwd验证的邮件系统
- Uva 507 - Jill Rides Again(最大子数组求和问题)
- 使用aidl工具快速在应用层实现binder进程间通信
- zabbix3.0.2 实现发送email报警的详细过程
- AIX操作系统通过光盘进行备份与恢复
- compress_pair_ref
- 谷歌约束控件(ConstraintLayout)扁平化布局入门
- HDU 5029 Relief grain 树链剖分 好题
- toString() unavailable - no suspended threads
- Airbnb 分享经济步步紧逼:传统酒店老板要和出租车司机同病相怜?
- 【NOIP2013模拟】Rainbow的信号
- Block如何避免self retain
- LeetCode 70. Climbing Stairs(爬楼梯)