当前位置: 首页 > news >正文

MDK中结构体的对齐、位域、配合联合体等用法说明

测试环境:STM32H7R3+MDK 5.39+AC5

注:PC、PowerPC等环境不适用本文。

一.字节对齐

        一般采用自然对齐(默认方式),提高数据存取速度。
        采用1字节对齐,变量在内存中无空隙,紧密存储,节省存储空间。另外可配合union,在通信时进行数值(void*)与tx/rx缓冲区(uint8_t*)的相互转换。


1.默认方式

#include <stdint.h>

typedef struct {
	uint8_t A;
	uint16_t B;
	uint16_t C;
}Test_T;

int main(void)
{
    Test_T Test={
                .A=0x11,
                .B=0x2222,
                .C=0x3333,
    };

    return 0;
}

内存图:

为保证自然对齐,成员在内存中有空隙。

uint16_t成员A占2字节,起始地址0x200003ED%2=1,非2字节对齐,而0x200003EE%2=0,满足对齐条件。

2.强制1字节对齐

#include <stdint.h>

#pragma pack(push, 1)
typedef struct {
	uint8_t A;
	uint16_t B;
	uint16_t C;
}Test_T;
#pragma pack(pop)

int main(void)
{
    Test_T Test={
                .A=0x11,
                .B=0x2222,
                .C=0x3333,
    };

    return 0;
}

内存图:
变量在内存中紧密排列,无空隙

二.位域

        C语言最小的数据类型是字节(8bit) ,我们只能选择8/16/32bit去存储数据。在某些应用中,数据需要更灵活的数据类型来存储,如开关量0/1只需要1bit来存储;考试成绩0~100只需要7bit来存储。

        通过位域,可在结构体实现指定bit数的存储。且成员数据类型只能为整型。

typedef struct {
	uint8_t 	A:1;
	uint16_t 	B:4;
	uint16_t 	C:7;
}Test_T;

Test_T Test={
.A=0b1,
.B=0b0000,
.C=0b1111111,
};

        此时Test_T的各成员数据类型(uint8_t、uint16_t)的作用,是限制位域成员的最大bit数,以及该位域的值应被如何解释。

         在未指定1字节对齐时(#pragma pack(push, 1)),位域结构体在内存中仍有空隙,对齐方式与成员类型以及位域大小有关。详见博文(C语言笔记)位域的详解使用(含内存对齐)。所以在需要形成连续比特流的场合,需要位序配合1字节对齐使用。

                注:Test_T的各成员的大小是非字节倍数的,无法用sizeof(Test_T.A)计算空间。但由各位域成员组成的结构体变量,仍可用sizeof(Test_T)计算大小。Test_T的各成员也无法通过指针操作。


        

三.联合体

        在通信中使用,可将有意义的数值转为字节缓冲区,即可实现快速组帧。

四.三者配合使用

如下有效利用资源,实现通信协议对数据的高度压缩。

http://www.dtcms.com/a/99430.html

相关文章:

  • C#:第一性原理拆解属性(property)
  • 分享一个Pyside6实现web数据展示界面的效果图
  • Springboot学习笔记3.20
  • SmolDocling文档处理模型介绍
  • Python 循环全解析:从语法到实战的进阶之路
  • 人工智能之数学基础:矩阵的相似变换的本质是什么?
  • DeepSeek网络拓扑设计解密:如何支撑千卡级AI训练的高效通信?
  • 缓存 vs 分布式锁:高并发场景下的并发控制之道
  • 【C++】类和对象(二)默认成员函数之拷贝构造函数、运算符重载、赋值运算符重载
  • <tauri><rust><GUI>基于rust和tauri,实现一个大寰电爪PGHL(串口设备)定制化控制程序
  • java pom文件加入这个可以将打包好的jar 双击运行
  • 积分赛——光敏控制多功系统设计
  • 区块链赋能,为木材货场 “智” 造未来
  • vue在线录音系统
  • Redis延时队列在订单超时未报到场景的应用补充说明
  • 利用 VSCode 配置提升 vibe coding 开发效率
  • 找python大数据就业,我应该学习Java哪些知识
  • dav_pg8_vacuum
  • c#的.Net Framework 的console 项目找不到System.Window.Forms 引用
  • VMware中新建Ubuntu虚拟机系统,并安装Anaconda
  • 1--当「穷举」成为艺术:CTF暴力破解漏洞技术从入门到入刑指南(知识点讲解版)
  • Android Architecture Components 深入解析
  • 【力扣刷题|第十七天】0-1 背包 完全背包
  • Linux进程管理的相关知识点以及我的相关笔记链接
  • 算法为舟 思想为楫:AI时代,创作何为?
  • Redis的ZSet有序集合
  • 深度剖析:U盘突然无法访问的数据拯救之道
  • 27. 移除元素【数组专题】Java\Python\JS\Go\C++
  • IP综合实验
  • 曲线拟合 | Matlab基于贝叶斯多项式的曲线拟合