C语言结构体内存对齐使用场景

#pragma pack(push, 1)#pragma pack(pop) 的使用场景(C语言)

这两个预处理指令用于控制结构体成员的内存对齐方式,主要在以下场景中使用:

主要使用场景

  1. 网络通信协议处理

    • 当需要精确控制结构体布局以匹配网络协议格式时

    • 确保结构体与协议定义的二进制格式完全一致

  2. 文件格式处理

    • 读写特定二进制文件格式(如图像、音频文件头等)

    • 确保结构体与文件中的二进制布局完全匹配

  3. 硬件寄存器映射

    • 当需要将结构体映射到特定的硬件寄存器布局时

    • 嵌入式系统中常见

  4. 与外部系统的数据交换

    • 与其他语言或系统进行二进制数据交换时

典型用法

复制代码
#pragma pack(push, 1)  // 保存当前对齐方式,并设置为1字节对齐

typedef struct {
    char id[4];
    int width;
    int height;
    short colorDepth;
} ImageHeader;  // 这个结构体将紧密排列,无填充字节

#pragma pack(pop)  // 恢复之前的对齐设置

复制代码
/*当前电流*/
#pragma pack(push, 1)
typedef struct _18E8EFF3_Frame{
    uint32_t                battery_calendar_life;          		    //电池日历寿命 			  精度1   单位S
    uint16_t                continuous_charging_current_allowed;        //BMS当前允许持续充电电流  精度0.1 单位A
    uint16_t                Continuous_discharge_current_allowed;       //BMS当前允许持续放电电流  精度0.1 单位A
}_18E8EFF3_Frame;
#pragma pack(pop)

复制代码
/*电芯电压*/
#pragma pack(push, 1)
typedef struct _18E5EFF3_Frame{
    uint16_t                max_cell_volt;                              //最大电池电压 factor 0.001,offset 0   
    uint16_t                min_cell_volt;                              //最小电池电压 factor 0.001,offset 0
    uint16_t                ave_cell_volt;                              //平均电池电压 factor 0.001,offset 0
    uint8_t                 max_cell_volt_pos;                          //最大电池电压位置 factor 1,offset 0
    uint8_t                 min_cell_volt_pos;                          //最小电池电压位置 factor 1,offset 0
}_18E5EFF3_Frame;
#pragma pack(pop)

复制代码
/*电压电流*/
#pragma pack(push, 1)
typedef struct _18E3EFF3_Frame{
    uint16_t                num_of_charge_cycles;                       //电池充电循环次数 factor 1
    uint8_t                 pack_soc;                                   //soc factor 0.5
    uint8_t                 pack_soh;                                   //soh factor 0.5
    int16_t                 pack_total_cur;                             //总电流 factor 0.1 A  电池包总电流(充电为负值,放电为正值)
    uint16_t                pack_total_vol;                             //总电压 factor 0.1 V  电池包电压            
}_18E3EFF3_Frame;
#pragma pack(pop)

为什么需要

  • 默认对齐:编译器通常会按成员大小对齐(如int按4字节边界)

  • 填充字节:编译器可能插入填充字节以实现对齐

  • 跨平台一致性:确保在不同平台上有相同的布局

注意事项

  1. 过度使用可能影响性能(未对齐访问在某些架构上较慢)

  2. 某些架构可能不支持非对齐访问(会导致硬件异常)

  3. 只应用于确实需要精确布局的结构体

  4. 确保push和pop成对出现,避免影响其他代码

这种技术虽然强大,但应谨慎使用,通常只在特定需求下才需要。

相关推荐
shinelord明4 分钟前
【大数据技术实战】Kafka 认证机制全解析
大数据·数据结构·分布式·架构·kafka
小龙报19 分钟前
《彻底理解C语言指针全攻略(6)-- qsort、sizeof和strlen》
c语言·开发语言·职场和发展·创业创新·学习方法·业界资讯·visual studio
让我们一起加油好吗21 分钟前
【基础算法】01BFS
数据结构·c++·算法·bfs·01bfs
孤狼灬笑27 分钟前
机器学习十大经典算法解析与对比
人工智能·算法·机器学习
草莓工作室36 分钟前
数据结构3:线性表2-顺序存储的线性表
数据结构·windows
郝学胜-神的一滴36 分钟前
Three.js光照技术详解:为3D场景注入灵魂
开发语言·前端·javascript·3d·web3·webgl
fie888937 分钟前
基于Matlab的深度堆叠自编码器(SAE)实现与分类应用
开发语言·分类
_w_z_j_1 小时前
C++11----列表初始化和initializer_list
开发语言·c++
冬天的雪20081 小时前
java内存性能优化工具Mat
java·开发语言
Le1Yu1 小时前
消息队列以及RabbitMQ的使用
java·开发语言