初出茅庐的小李第73篇博客之offsetof(type, member-designator)使用

offsetof(type, member-designator)

这是一个宏定义包含在<stddef.h>里,它的作用是用来计算一个结构成员相对于结构开头的字节偏移量。

说到这里我先来补习一下结构体的知识:
我们在实际项目中就会发现结构体是大量存在的,我本身是学单片机的经常用的就是STM32单片机,STM32官方的库到处都是结构体。研发人员常使用结构体来封装一些属性来组成新的类型,比如传感器的数据帧,或者一些属性参数都会用到。由于C语言无法操作数据库,所以在项目中通过对结构体内部变量的操作将大量的数据存储在内存中,以完成对数据的存储和操作。

今天重点不是学习结构体而是学习结构体成员相对于结构体开头的字节偏移量

开始之前我们先定义一个结构体

struct student
{
   char name[13];
   float fenshu;
   int  age;
};

可以试着想一下这个结构体空间是多大??
13+4+4=21?

测试代码

#include <stddef.h>
#include <stdio.h>
// #pragma pack(1)
struct student
{
   char name[13];
   float fenshu;
   int  age;
};
   
int main()
{
   printf("student 结构中的 name 偏移   = %d 字节。\n",
   offsetof(struct student, name));
   printf("student 结构中的 fenshu 偏移 = %d 字节。\n",
   offsetof(struct student, fenshu));
   printf("student 结构中的 age 偏移    = %d 字节。\n",
   offsetof(struct student, age));
   
   return(0);
} 

运行结果

在这里插入图片描述
跟我们设想的不一样?
这个字节偏移怎么是20?难道是计算错误了吗?

补充概念,字节对齐

其实如果我们不强制字节对齐的话这个结构体的尺寸会被编译器搞成24

在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/22fc25fe0e694eec90f742e91aa99877.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5Yid5Ye66IyF5bqQ55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16
float 是4字节 int是2字节 cahr是1字节
按理说应该是**0 13(char) 17(char + float)**才符合预期啊 ?

这其中的原因就是编译器自动进行了字节对齐操作 关于字节对齐**、

我在B站上发现一遍写的非常不错的文章
贴出来大家一起学习**在这里插入图片描述
https://www.bilibili.com/read/cv2868049?from=search
那我们有没有办法让其其它方式对齐呢

#pragma pack(1)

对 就是这个强制单字节对齐 加上这句话 我们结构体就会自动按照单字节对齐

#include <stddef.h>
#include <stdio.h>
#pragma pack(1)
struct student
{
   char name[13];
   float fenshu;
   int  age;
};
   
int main()
{
   printf("student 结构中的 name 偏移   = %d 字节。\n",
   offsetof(struct student, name));
   printf("student 结构中的 fenshu 偏移 = %d 字节。\n",
   offsetof(struct student, fenshu));
   printf("student 结构中的 age 偏移    = %d 字节。\n",
   offsetof(struct student, age));

   printf("sizeof(struct student) = %d\n",sizeof(struct student));
   return(0);
} 

代码运行

在这里插入图片描述
13+4+4=21

最后其实我还有一个疑问那就是我们库函数整这个宏定义能干啥呢,或者说我能用这个宏定义干点啥呢??
果然是应了那句话 ***你知道的越多你不知道就越多***我发现就这个宏定义引发出来的未知就又很多了,
在不同的平台或者说编译器都有自己对这个宏定义的实现 感兴趣可以继续研究下面这篇文章非常建议看看,我看了一遍深受启发,今天先把它收藏了,日后还要仔细拜读!!!

强烈推荐前辈的一篇文章,深受启发

offsetof,搞嵌入式必须会的杀手锏

https://blog.csdn.net/embeddedsoft/article/details/1351125?spm=1001.2014.3001.5501

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值