container_of宏和offsetof宏的总结

1、offsetof 宏

 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

将地址0强制转换为type类型的指针,从而得到结构体成员member相对于结构体起始地址的偏移量。

2、container_of 宏

 #define container_of(ptr, type, member) ({        const typeof( ((type *)0)->member ) *__mptr = (ptr);      (type *)( (char *)__mptr - offsetof(type,member) );})

作用:结构体(type)的成员member地址 减去 member在type中的偏移 得到该结构体(type)的起始地址。

container_of 宏分为两部分:

第一部分:const typeof( ((type *)0)->member ) *__mptr = (ptr);
   通过typeof定义一个member指针类型的指针变量__mptr,并将__mptr赋值为ptr。
 第二部分:(type *)( (char *)__mptr - offsetof(type,member) );
   通过offsetof宏计算出member在type中的偏移,
   然后用member的实际地址__mptr减去偏移,得到type的起始地址,即指向type类型的指针。

测试代码:

 1 #include <stdio.h>
 2
 3 #define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER)
 4
 5 #define container_of(ptr, type, member) ({   6     const typeof( ((type *)0)->member) *__mptr = (ptr);   7     (type *)( (char *)__mptr - offsetof(type, member));})
 8
 9 typedef struct{
10     int id;
11     char name[20];
12     int age;
13 }student;
14
15 int main()
16 {
17     printf("%lu\n", offsetof(student, id));
18     printf("%lu\n", offsetof(student, name));
19     printf("%lu\n", offsetof(student, age));
20
21     student s;
22     s.age = 20;
23     student *ps = container_of(&s.age, student, age);
24     printf("%d\n", ps->age);
25     printf("%p\n", &s);
26     printf("%p\n", ps);
27
28     return 0;
29 }

运行结果:

原文地址:https://www.cnblogs.com/reviewing/p/9747382.html

时间: 2024-10-12 14:39:51

container_of宏和offsetof宏的总结的相关文章

C语言之offsetof宏和container_of宏

首先我们要明白一点通过结构体变量来访问结构体中的各个元素时,其本质上是 通过指针的方式来实现访问的,只不过是这个时候编译器帮自动帮我们计算了每个 元素与结构体起始地址之间的偏移量而已 一:offsetof宏: #define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) 1:参数与返回值分析: (1)TYPE是结构体类型,MEMBER是结构体中一个元素的元素名 (2)这个宏返回的是member元素相对于整个结构体变量的首地址的偏移量,

offsetof宏与container_of宏

offsetof宏与container_of宏1.由结构体指针进而访问各元素的原理(1)通过结构体整体变量来访问其中各个元素,本质上是通过指针方式来访问的,形式上是通过.的方式来访问的(这个时候其实是编译器帮我们自动计算了偏移量).2.offsetof宏: #define offsetof(TYPE, MEMBER) ((int)&( (TYPE *)0)->MEMBER )(1)offsetof宏的作用是:用宏来计算结构体中某个元素和结构体首地址的偏移量(其实质是通过编译器来帮助我们计算)

C语言中offsetof宏的应用

1) #define offsetof(s, m)   (size_t)&(((s *)0)->m) 2) #define OBJECT_HEAD_ADDRESS(ClassName,MemberName,Addre) \Addre - offsetof(ClassName, MemberName) C语言中offsetof宏的应用

Excel VBA(宏):添加宏

写在前面: 1.编写宏,打开VBA,双击ThisWorkbook对当前工作薄进行编写宏:双击Sheet1,对整个sheet编写宏: 或者创建模块,在模块里,编写.调试代码. 打开VBA的方法见第一讲,结合常用窗口进行编写.调试. 2.部分对象有提示,如Dim a As,敲击空格后有提示. 3.所有宏要运行,必须启动宏.(2007版启动宏,点击表格左上角 "excel选项" "信任中心" "信任中心设置" "启用宏") 4.&q

sas宏(3)宏,调试宏,创建带参数的宏,理解符号表(全局宏与局部宏解析),宏条件运算符,在宏中进行运算

宏类似于c中的函数,传入指定参数后执行,并且宏内部可以包含data步程序和条件运算符号. 宏变量只是小小的变量....(by the way作用也很大) 1:宏的基本语法 如何创建一个简单的宏并使用? %macro prtlast; proc print data=&syslast (obs=5); title "Listing of &syslast data set"; run; %mend; %prtlast /*不要加分号,加了有可能出错*/ 宏创建过程中做了什

sas宏(2),运行中创建宏与使用宏,proc sql创建宏, scl中宏处理(暂缺)

1:在程序运行中进行宏定义 CALL routines that enable you to transfer information between an executing DATA step and the macro processor. You can use the SYMPUT routine to create a macro variable and to assign to that variable any value that is available in the DA

宏常量,宏替换,const常量

(1)宏常量也称为符号常量,是指用一个标识符号来表示的常量,宏常量是由宏定义编译预处理命令来定义的,宏定义的一般形式:#define 标识符 字符串 宏定义中的标识符被称为宏名,将程序中出现的宏名替换成字符串的过程称为宏替换,宏替换时是不做任何语法检查的,因此,只有在对已经被宏展开后的源程序进行编译时才会发现语法错误 (2)const常量:使用宏常量的最大问题是,宏常量没有数据类型.那么是否可以声明具有某种数据类型的常量呢?这就是const常量 const常量被编译器放在只读存储区,不允许在程序

两级宏&amp;&amp;字符串化宏

如果你想字符串化宏参数扩展的结果,你必须使用两个级别的宏. 1 #define xstr(s) str(s) 2 #define str(s) #s 3 #define foo 4 4 str (foo) 5 ==> "foo" 6 xstr (foo) 7 ==> xstr (4) 8 ==> str (4) 9 ==> "4" 当s被用在str中,s被字符串化,所以首先它不是宏扩展. 但s是xstr的一个普通参数,所以在xstr完全宏扩展

C语言:类似linux内核的分等级DEBUG宏(打印宏)

总结几种log打印printf函数的宏定义 http://blog.chinaunix.net/uid-20564848-id-73402.html #include <stdio.h> #define lU_DEBUG_PREFIX "##########" #define LU_DEBUG_CMD 0x01 #define LU_DEBUG_DATA 0x02 #define LU_DEBUG_ERROR 0x04 #define LU_PRINTF_cmd(msg..