C/C++知识点之container_of 和 offsetof宏
顾宇峰 2019-04-10 来源 : 阅读 1983 评论 0

摘要:本文主要向大家介绍了C/C++知识点之container_of 和 offsetof宏,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了C/C++知识点之container_of 和 offsetof宏,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之container_of 和 offsetof宏

在linux 驱动源码中,有两个很有意思的宏,分别是offsetof和container_of,他们的作用和定义是这样子的

  1. offsetof 获得结构体某成员相对于结构体的偏移长度

    /**
     *   计算的结构体中某成员的偏移量
     */#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

    这个实现很巧妙,相当于设结构体的整体地址设成0,然后它的成员的地址就相当于成员的偏移

    测试代码:

    #include <stdio.h>#include ""list.h""typedef struct Test_struct{        char ca;        int ib;        double dc;
    }Test_struct_t;int main(){        printf(""offset ca is %d\n"",offsetof(Test_struct_t,ca));        printf(""offset ib is %d\n"",offsetof(Test_struct_t,ib));        printf(""offset dc is %d\n"",offsetof(Test_struct_t,dc));        return 0;
    }

    执行结果:
    offset ca is 0
    offset ib is 4
    offset dc is 8

2.container_of 是通过结构体的某成员的地址得到整个结构体的地址,在使用上进而可以访问到结构体的其余成员

/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:    the pointer to the member.
 * @type:   the type of the container struct this is embedded in.
 * @member: the name of the member within the struct.
 *  通过结构体中的某个成员的指针,反推出来结构体的指针,可以进而可以访问其他成员
 */#define container_of(ptr, type, member) ({          \    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
    (type *)( (char *)__mptr - offsetof(type,member) );})

实现上实际就是当前这个成员的地址 减去 这个成员相对整个结构体的的偏移量,就是结构体的地址

测试代码

typedef struct person{    char name[20];    char phone_num[12];    int index;
}Person_t;void showInfo(Person_t *ptr){    printf(""name :%s\n"",ptr->name);    printf(""phone_num :%s\n"",ptr->phone_num);    printf(""index :%d\n"",ptr->index);
}// 通过姓名打印所以信息void getInfoByName(char name[]){    if(!name)        return ;
    Person_t *ptr = container_of(name,Person_t,name);    if(ptr)
    {
        showInfo(ptr);
    }
}int main(){

    Person_t person;    memset(&person,0x0,sizeof(Person_t));

    person.index = 110;    strncpy(person.name,""zhangsan"",strlen(""zhangsan""));    strncpy(person.phone_num,""15617274954"",strlen(""15617274954""));

   showInfo(&person);   printf(""\============\n"");
   getInfoByName(&person.name);    return 0;
}

执行结果
name :zhangsan
phone_num :15617274954
index :110
\============
name :zhangsan
phone_num :15617274954
index :110

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @职坐标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论
本文作者 联系TA

2年研发与教育经验

  • 10
    文章
  • 2517
    人气
  • 0%
    受欢迎度

已有0人表明态度,0%喜欢该老师!

进入TA的空间
求职秘籍 直通车
  • 索取资料 索取资料 索取资料
  • 答疑解惑 答疑解惑 答疑解惑
  • 技术交流 技术交流 技术交流
  • 职业测评 职业测评 职业测评
  • 面试技巧 面试技巧 面试技巧
  • 高薪秘笈 高薪秘笈 高薪秘笈
TA的其他文章 更多>>
C/C++知识点之哈希表—位图
经验技巧 100% 的用户喜欢
C/C++知识点之哈希表详解
经验技巧 0% 的用户喜欢
C/C++知识点之平衡二叉树
经验技巧 0% 的用户喜欢
C/C++知识点之c++ 6种排序算法 源代码
经验技巧 0% 的用户喜欢
C/C++知识点之mac 下xcode配置opencv
经验技巧 0% 的用户喜欢
其他海同师资 更多>>
吕益平
吕益平 联系TA
熟悉企业软件开发的产品设计及开发
孔庆琦
孔庆琦 联系TA
对MVC模式和三层架构有深入的研究
周鸣君
周鸣君 联系TA
擅长Hadoop/Spark大数据技术
范佺菁
范佺菁 联系TA
擅长Java语言,只有合理的安排和管理时间你才能做得更多,行得更远!
金延鑫
金延鑫 联系TA
擅长与学生或家长及时有效沟通
经验技巧30天热搜词 更多>>

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程