我是靠谱客的博主 健康抽屉,最近开发中收集的这篇文章主要介绍Linux中的offsetof/container_of宏,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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宏所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部