标签:
关于结构体学习,需要了解:结构体的定义和使用、内存对齐、结构体指针、得到结构体元素的偏移量(offsetof宏实现)
一、复习结构体的基本定义和使用
1 typedef struct mystruct 2 { 3 int a; 4 char b; 5 double c; 6 }MyS1; 7 8 /* 9 函数功能:演示结构体的定义和使用 10 */ 11 void func1(void) 12 { 13 //定义时赋值 14 MyS1 s1 = { 15 .a =1, 16 .b =2, 17 .c = 1.23, 18 }; 19 printf("s1.a = %d.\n", s1.a); 20 printf("s1.b = %d.\n", s1.b); 21 printf("s1.c = %f.\n", s1.c); 22 printf("value is change.\n"); 23 // 使用.访问方式赋值 24 s1.a = 123; 25 s1.b = 4; 26 s1.c = 3.12; 27 28 printf("s1.a = %d.\n", s1.a); 29 printf("s1.b = %d.\n", s1.b); 30 printf("s1.c = %f.\n", s1.c); 31 }
结果:
分析:主要是复习一下结构体的定义和使用。
二、结构体指针的使用
1 typedef struct mystruct 2 { 3 int a; 4 char b; 5 double c; 6 }MyS1; 7 /* 8 函数功能:演示结构体指针的使用 9 */ 10 void func2(MyS1 *s_temp) 11 { 12 s_temp->a = 12; 13 s_temp->b = 34; 14 s_temp->c = 56.123; 15 printf("s_temp->a = %d.\n", s_temp->a); 16 printf("s_temp->a = %d.\n", s_temp->b); 17 printf("s_temp->a = %f.\n", s_temp->c); 18 } 19 int main(void) 20 { 21 MyS1 s1; 22 MyS1 *ps1 = &s1; 23 func2(ps1); 24 return 0; 25 }
结果:
三、offsetof宏详解
先看看代码,是如何使用offsetof的
1 #define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) 2 3 struct mystruct 4 { 5 int a; 6 char b; 7 double c; 8 }; 9 int adr_a = offsetof(struct mystruct, b); // adr_a = 4
offsetof宏的分析: #define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER)
1、功能:返回结构体元素的相对结构体首地址的偏移
2、参数:TYPE是结构体类型,MEMBER是结构体中一个元素的元素名
3、分析:
(1) (TYPE *)0; 将0转换成结构体指针;
(2) ((TYPE *)0)->MEMBER; 使用指针方式访问结构体中元素
(3) &(((TYPE *)0)->MEMBER); 取结构体中元素的地址
(4) (int) &(((TYPE *)0)->MEMBER); 转换成int型返回
四、container_of宏详解
先看代码
1 #define container_of(ptr, type, member) ({ 2 const typeof(((type *)0)->member) * __mptr = (ptr); 3 (type *)((char *)__mptr - offsetof(type, member));}) 4 5 typedef struct mystruct 6 { 7 int a; 8 char b; 9 double c; 10 }MyS1; 11 struct mystruct s1; 12 MyS1 *ps = NULL; 13 double *p = &s1.c; 14 printf("&s1 = %p.\n" ,&s1); 15 16 ps = container_of(p, MyS1, c); 17 printf("ps = %p.\n" ,ps);
结果:
分析:根据&s1.c的地址得到整个结构体的首地址
详解:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member));})
1、功能:返回整个结构体变量的指针
2、参数:ptr是指向结构体中一个元素的指针;type是结构体类型;member是结构体中一个元素的元素名
3、分析:
(1) typeof(((type *)0)->member); 获取结构体中一个元素的类型;s1.c 的类型是double
(2) const typeof(((type *)0)->member) * __mptr = (ptr);
就可以理解为:
const double * __mptr = (ptr);//__mptr指向ptr处
(3) (char *)__mptr - offsetof(type, member); // 结构体其中一个元素的地址 - 该元素相对结构体首地址的偏移
(4) (type *)((char *)__mptr - offsetof(type, member)); // 转换成该结构体类型的指针返回
-----------------------------------------------------------------------------------------------------------------------------------
注:以上程序是参考“朱老师物联网视频”中的代码,特此申明!
----------------------------------------------------------------------------------------------------------------------------
C语言笔记(结构体与offsetof、container_of之前的关系)
标签:
原文地址:http://www.cnblogs.com/zou107/p/4950936.html