概述
offsetof宏
/*计算结构体成员在结构体中的偏移量*/
#define
offsetof(TYPE, MEMBER)
((size_t) &((TYPE *)0) -> MEMBER)
offsetof宏作用
用于计算结构体成员在结构体中的偏移量
offsetof宏原理
TYPE : 结构体的类型
MEMBER : 结构体成员
使用结构体类型定义一个指针并指向结构体成员,表示该地址从0开始到结构体成员地址的偏移,即可计算出偏移量。
container_of宏
/*根据结构体某成员计算结构体的首地址*/
#define
container_of(ptr, type, member)
({
const typeof( ((type *)0) -> member ) *_mptr = (ptr);
(type *)( (char *)_mptr - offsetof(type, member) );})
container_of宏作用
根据结构体某成员变量计算结构体的首地址
container_of宏原理
ptr : 结构体成员地址
type : 结构体类型
member : 结构体成员变量
const typeof( ((type *)0) -> member ) *_mptr = (ptr);该语句表示使用结构体类型的指针指向成员member,进而获取结构体成员member的类型,使用该类型定义一个指针 _mptr保存结构体的成员地址ptr。
(type *)( (char *)_mptr - offsetof(type, member) );该语句表示把 _mptr强制转换为char *类型减去member在结构体中的偏移量即可获取首地址,再把获取到的首地址强制转换为结构体类型的指针返回。
该宏为语句表达式,语句表达式的返回值为最后一条语句的结果,因此container_of宏返回的是结构体类型的指针,指向结构体的首地址。
示例
#include <stdio.h>
/*计算结构体成员在结构体中的偏移量*/
#define
offsetof(TYPE, MEMBER)
((size_t) &((TYPE *)0) -> MEMBER)
/*根据结构体某成员计算结构体的首地址*/
#define
container_of(ptr, type, member)
({
const typeof( ((type *)0) -> member ) *_mptr = (ptr);
(type *)( (char *)_mptr - offsetof(type, member) );})
struct student
{
int age;
int num;
int math;
};
int main(void)
{
/*初始化结构体成员*/
struct student stu = {10, 20, 30};
/*定义指针ptr指向结构体中的num成员地址*/
int *ptr = &stu.num;
/*保存结构体的首地址*/
struct student *header_add = NULL;
/*计算结构体的首地址*/
header_add = container_of(ptr, struct student, num);
/*打印成员num在结构体中的偏移量*/
printf("num offsetof in stu = %drn", offsetof(struct student, num));
/*打印container_of返回的结构体首地址*/
printf("container_of header_add = %#prn", header_add);
/*直接打印结构体的首地址*/
printf("stu header_add = %#prn", &stu);
/*根据计算出来的结构体首地址指向结构体的其他成员*/
printf("header_add -> math = %drn", header_add -> math);
return 0;
}
上述代码运行后输出如下:
num offsetof in stu = 4
container_of header_add = 0X0061FEB8
stu header_add = 0X0061FEB8
header_add -> math = 30
可以发现使用container_of计算出来的结构体首地址和直接打印出来的结构体首地址相同,表示该宏可以获取结构体的首地址。
最后
以上就是健康抽屉为你收集整理的Linux中的offsetof/container_of宏的全部内容,希望文章能够帮你解决Linux中的offsetof/container_of宏所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复