关于结构体学习,需要了解:结构体的定义和使用、内存对齐、结构体指针、得到结构体元素的偏移量(offsetof宏实现)
一、复习结构体的基本定义和使用
typedef struct mystruct
{
int a;
char b;
double c;
}MyS1; /*
函数功能:演示结构体的定义和使用
*/
void func1(void)
{
//定义时赋值
MyS1 s1 = {
.a =,
.b =,
.c = 1.23,
};
printf("s1.a = %d.\n", s1.a);
printf("s1.b = %d.\n", s1.b);
printf("s1.c = %f.\n", s1.c);
printf("value is change.\n");
// 使用.访问方式赋值
s1.a = ;
s1.b = ;
s1.c = 3.12; printf("s1.a = %d.\n", s1.a);
printf("s1.b = %d.\n", s1.b);
printf("s1.c = %f.\n", s1.c);
}
结果:
分析:主要是复习一下结构体的定义和使用。
二、结构体指针的使用
typedef struct mystruct
{
int a;
char b;
double c;
}MyS1;
/*
函数功能:演示结构体指针的使用
*/
void func2(MyS1 *s_temp)
{
s_temp->a = ;
s_temp->b = ;
s_temp->c = 56.123;
printf("s_temp->a = %d.\n", s_temp->a);
printf("s_temp->a = %d.\n", s_temp->b);
printf("s_temp->a = %f.\n", s_temp->c);
}
int main(void)
{
MyS1 s1;
MyS1 *ps1 = &s1;
func2(ps1);
return ;
}
结果:
三、offsetof宏详解
先看看代码,是如何使用offsetof的
#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) struct mystruct
{
int a;
char b;
double c;
};
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宏详解
先看代码
#define container_of(ptr, type, member) ({ \
const typeof(((type *))->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member));}) typedef struct mystruct
{
int a;
char b;
double c;
}MyS1;
struct mystruct s1;
MyS1 *ps = NULL;
double *p = &s1.c;
printf("&s1 = %p.\n" ,&s1); ps = container_of(p, MyS1, c);
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)); // 转换成该结构体类型的指针返回
-----------------------------------------------------------------------------------------------------------------------------------
注:以上程序是参考“朱老师物联网视频”中的代码,特此申明!
----------------------------------------------------------------------------------------------------------------------------