offsetof宏与container_of宏
1、由结构体指针进而访问各元素的原理
(1)通过结构体整体变量来访问其中各个元素,本质上是通过指针方式来访问的,形式上是通过.的方式来访问的(这个
时候其实是编译器帮我们自动计算了偏移量)。
2、offsetof宏:
#define offsetof(TYPE, MEMBER) ((int)&( (TYPE *)0)->MEMBER )
(1)offsetof宏的作用是:用宏来计算结构体中某个元素和结构体首地址的偏移量(其实质是通过编译器来帮助我们计算)。
(2)offsetof宏的原理:我们虚拟一个type类型结构体变量,然后用type.member的方式来访问那个member元素,继而得到member
相对于整个变量首地址的偏移量。
#define offsetof(TYPE, MEMBER) ((int)&( (TYPE *)0)->MEMBER )
(TYPE *)0
这是一个强制类型转换,把0地址强制转换成一个指针,这个指针指向一个TYPE类型的结构体变量。
(实际上这个结构体变量可能不存在,但是只要我不去解引用这个指针就不会出错)。
((TYPE *)0)->MEMBER
(TYPE *)0是一个TYPE类型结构体变量的指针,通过指针来访问这个结构体变量的member元素
&((TYPE *)0)->MEMBER
&((TYPE *)0)->MEMBER等效于&(((TYPE *)0)->MEMBER),意思就是得到member元素的地址。但是因为整个结构体变量的首地址是0,所以相当于
整个结构体变量的起始地址是0,而member元素的首地址是&((TYPE *)0)->MEMBER,所以这个数字减去0还是这个数字,但是减去之后的意义就变
成了member元素相对于整个结构体变量首地址的偏移量。
实例:
 struct mystruct
 {
  char a;
  int b;
  short c;
 };
 int offsetofa = offsetof(struct mystruct, a);
 printf("offsetofa = %d.\n", offsetofa);     //offsetofa = 0;
 int offsetofb = offsetof(struct mystruct, b);
 printf("offsetofb = %d.\n", offsetofb);     //offsetofb = 4;
 int offsetofc = offsetof(struct mystruct, c);
 printf("offsetofc = %d.\n", offsetofc);     //offsetofa = 8;
3、container_of宏:
#define container_of(ptr, type, member) ({           \
    const typeof(((type *)0)->member) * __mptr = (ptr); \
    (type *)((char *)__mptr - offsetof(type, member)); })
(1)作用:知道一个结构体中某个元素的指针,反推这个结构体变量的指针。有了container_of宏,我们可以从一个元素的指针得到整个结构体
变量的指针,继而得到结构体中其他元素的指针。
(2)typeof关键字的作用是:typeof(a)时由变量a得到a的类型,typeof就是由变量名得到变量数据类型的。
(3)这个宏的工作原理:先用typeof得到member元素的类型定义成一个指针,然后用这个指针减去该元素相对于整个结构体变量的偏移量(偏移量
用offsetof宏得到的),减去之后得到的就是整个结构体变量的首地址了,再把这个地址强制转换成type *即可。
实例:
 struct mystruct
 {
  char a;
  int b;
  short c;
 };
 struct mystruct s1;
 struct mystruct *ps = NULL;
 short *p = &(s1.c);    //p就是指向结构体中某个member的指针
 //问题就是通过p来计算得到s1的指针
 ps = container_of(p, struct mystruct, c);
 printf(ps等于:%p.\n, ps);

offsetof宏与container_of宏的更多相关文章

  1. (转)offsetof与container_of宏[总结]

    1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...

  2. offsetof与container_of宏[总结]

    1.前言 今天在看代码时,遇到offsetof和container_of两个宏,觉得很有意思,功能很强大.offsetof是用来判断结构体中成员的偏移位置,container_of宏用来根据成员的地址 ...

  3. linux中offsetof与container_of宏定义

    linux内核中offsetof与container_of的宏定义 #define offsetof(TYPE, MEMBER)    ((size_t) &((TYPE *)0)->M ...

  4. offsetof与container_of宏分析

    offsetof宏:结构体成员相对结构体的偏移位置 container_of:根据结构体成员的地址来获取结构体的地址 offsetof 宏 原型: #define offsetof(TYPE, MEM ...

  5. typeof, offsetof, container_of宏

    container_of宏实现如下: #define container_of(ptr, type, member) ({ \ )->member ) *__mptr = (ptr); \ (t ...

  6. 对offsetof、 container_of宏和结构体的理解

    offsetof 宏 #include<stdio.h> #define offsetoff(type, member)      ((int)&((type*)0)->me ...

  7. container_of宏定义分析---linux内核

    问题:如何通过结构中的某个变量获取结构本身的指针??? 关于container_of宏定义在[include/linux/kernel.h]中:/*_** container_of - cast a ...

  8. container_of宏剖析

    container_of宏剖析//该宏位于include/linux/kernel.h 1.定义格式 /** * container_of - cast a member of a structure ...

  9. 内核中container_of宏的详细分析【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637597.html 内核中container_of宏的详细分析 16年2月28日09:00:37 内核中 ...

随机推荐

  1. eshop1-大型电商架构演进

    1. 项目初期 2. 服务器分离 以上的服务分离架构,即使文件服务crash 了,但是application server 和 Database Server 继续可以访问运行 3. 基于并发访问越来 ...

  2. 转载-- SQL连接查询2 外连接(左右联接查询)

    http://www.cnblogs.com/zhangqs008/archive/2010/07/02/2341196.html 外连接主要包括左连接.右连接和完整外部连接. 1)左连接:Left ...

  3. 活动目录对象属性批量修改工具------ADModify

    最近下载了一个可以修改活动目录用户.组.联系人等活动目录对象属性的工具,试用了一下,发现还是蛮好用的,并且还可以修改对象的扩展属性,如:在活动目录中安装了Exchange 2003,Exchange ...

  4. 【问题管理】-- Tomcat8部署项目加载静态资源html页面编码错误

    1.问题背景及解决方式 最近在回顾Tomcat部署Web项目,自己简单地从Tomcat的下载安装及配置server.xml文件入手,学习Tomcat的项目部署,在自己使用IDEA创建了一个简单地web ...

  5. Java自学-集合框架 Comparator和Comparable

    Java Comparator和Comparable 步骤 1 : Comparator 假设Hero有三个属性 name,hp,damage 一个集合中放存放10个Hero,通过Collection ...

  6. 046-unset对静态变量无法销毁

    <?php function digui() { static $count = 0; echo $count; $count++; unset($count); } digui(); digu ...

  7. Power BI 安装注册教程

    把下载好的MSI包PBIDesktop_x64.msi 双击安装 点击下一步 选择文件路径 点击安装 点击完成 初始化中 安装完成界面 账号注册 https://powerbi.microsoft.c ...

  8. spring源码 ConfigurableListableBeanFactory根接口

    用机器翻译+原作者的翻译:https://blog.csdn.net/u011179993/article/details/51636742 /* * Copyright 2002-2015 the ...

  9. 通过Navicat Premium 实现Oracle的连接和基本操作

    一.Oracle的连接 以下为Navicat Premium连接Oracle数据库的教程 一.需要准备的软件(下载适合自己系统的软件) 1.Navicat premium 官方下载地址:http:// ...

  10. 基础语法-其它流程控制语句break和continue

    基础语法-其它流程控制语句break和continue 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.break语句 /** * break语句 * @author 尹正杰 * ...