结构体------对齐与压缩(#pragma, __packed)

8 篇文章 1 订阅

结构体对齐

摘自原则:

  • 结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始(以结构体变量首地址为0计算)。
  • 在经过第一原则分析后,检查计算出的存储单元是否为所有元素中最宽的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍。

我这边补在赘述结构体的对齐原则,上面一篇文章详细讲了,可供大家参考。
新建一个结构体

typedef struct test_struct
{
	uint8_t A;
	uint16_t B;
	uint32_t C;
}test_t;

test_t test;
uint16_t size  = 0;//查看大小
uint8_t *A_addr;
uint16_t *B_addr;
uint32_t *C_addr;
woid main()
{
	test.A = 1;
	test.B = 2;
	test.C = 3;
	size = sizeof(test);
	A_addr = &test.A;
	B_addr = &test.B;
	C_addr = &test.C;
	while(1)
	{
	}
}

首先是结构体的大小为:8
在这里插入图片描述

各个元素的地址
在这里插入图片描述
在内存中是这样的:
XX表示未被初始化的内存,虽然也是00,但是我们为了区分所以用XX表示
在这里插入图片描述

压缩结构体的方法

__packed

定义

__packed在 "cmsis_armcc.h"文件中定义:

#ifndef   __PACKED
  #define __PACKED                               __attribute__((packed))

作用

packed属性的主要目的是让编译器更紧凑地使用内存。当它用于变量时,告诉编译器该变量应该有尽可能小的对齐,也就是1字节对齐。当它用于结构体时 ,相当于给该结构体的每个成员加上了packed属性,这时该结构体将占用尽可能少的内存。

typedef __packed struct test_struct
{
	uint8_t A;
	uint16_t B;
	uint32_t C;
}test_t;	

使用__packed之后结果:
在这里插入图片描述
在这里插入图片描述

从上图中可以发现结构体成员地址向前移动了一个,其内存模型如下:
在这里插入图片描述

#pragma

语法

  • #pragma pack (n) 作用:C编译器将按照n个字节对齐。

  • #pragma pack () 作用:取消自定义字节对齐方式。

  • #pragma pack (push,1) 作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为一个字节对齐

  • #pragma pack(pop) 作用:恢复对齐状态

结果

结果与__packed一致都是按字节对齐的。

#pragma pack(1)
typedef struct test_struct 
{
	uint8_t A;
	uint16_t B;
	uint32_t C;
}test_t;
#pragma pack ()

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柒妖71

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值