结构体位域与内存对齐

结构体位域的使用就是来压缩空间的如一个字节8个bit位可以表示8个事件标志

union Byte
{
	struct _bit
	{
		int a : 5;
		int b : 3;
	} Bit;

	int c;
}_Byte;

_Byte.Bit.a = 1; //a占用了低字节的低5位(大小端模式)
_Byte.Bit.b = 2; //b占用了低字节的高3位
/*int c与结构体Bit共用一块内存空间*/ 	
printf("%d\n",_Byte.c);  //65--010 00001
                           b =2    a = 1

2:位域的大小:不能横跨两个成员变量要存储在同个类型数据长度内

struct _bit
{
	int a : 5;  //5位还剩11位
	int b : 8; // 够存放8位
	int c : 8; //不够再开辟2个字节
}Bit;
	printf("%d\n", sizeof(Bit));//4个字节
struct _bit
{
	char a : 5;  //5位还剩3位
	char b : 8; // 不够重新再开辟1个字节
	char c : 8; //重新再开一个字节
}Bit1;
    printf("%d\n", sizeof(Bit));//3个字节

结构体内存对齐

原则1:数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存               储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。

原则2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。               (struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)

原则3:收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。

struct nature
{
   char c1;
   char c2;
   char c3;
}tenet;
/*输出 3个字节*/
printf("%d\n",sizeof(tenet));
//对齐数=编译器默认的对齐数与该成员大小的较小值。VS中默认对齐数为8,linux默认对齐数为4.
//对齐数基本上char(1),short(2),int(4),double(8);tenet对齐数是1总的内存大小也是倍数关系
    struct cs
	{
		long l;  //1111
		char c;  //1***
		int  t;  //1111
	}gt;
	printf("%d\n", sizeof(gt));//12

声明1表示占用了一个字节的空间,*表示未占用来填充。char  c这里填充了三个字节是由于原则1: int 型变量t要从4字节的整数倍位置开始存储;结构体gt 的首地址也是 l的首地址填充三个字节后位8是int类型的2倍。

struct  LL
{
    char C;//1
    int  T;//1111
    short S;//11
}lj;
12 = sizeof(lj);
T要从4的整数倍的内存空间开始存储所以C占用的空间1***,T为1111,在加上S的两个字节就是10byte
明显不符合对齐原则3总的结构体占用的空间不是 T类型的整数倍所以T占用的空间为11**.
lj = 12;(*表示的空间倍浪费)

因此无论结构体里面成员的的变量类型是多少种都是按照这三个原则去对齐,填充只要确定好成员量的类型长度即可。

以上都是在没有没有#pragma pack宏的情况下,如果先使用了#pragma pack宏要按照宏定义的条件来进行对齐

#pragma pack(4)
	struct cs
	{
		long l;  //4
		char c;  //1
		int  t;  //4
	}gt;
	printf("%d\n", sizeof(gt));
 #pragma pack(1)   gt = 9
 #pragma pack(2)   gt = 10
 #pragma pack(4)   gt = 12
由此可见结构体占得总的内存空间是 对齐字节数*倍数>实际变量占用的内存空间数(最小倍数)

结构体中有位域的存在

struct BIT
{
	char c1:3; //用3bit剩5bit够开辟c3的内存空间
	char c3 : 2;//沿用c1开辟后剩余的空间后第一个字节还剩3个bit不足以开辟c2的7位
	char c2 : 7;//由于同类型不能横跨同一个类型字节长度所以要重新开辟一个char空间	
}_Bit;         //所以总共就用了2个字节个空间
	printf("%d\n", sizeof(_Bit));
    2= sizeof(_Bit)
struct BIT
{
	char c1:3;
    char c2 : 7;
	char c3 : 2;
}_Bit;//同上剩余字节理论分析三个成员变量都个独占一个字节的空间
3 = sizeof(_Bit)
struct BIT
{
	char c1:3;
	char c3 : 2;//c1,c3总共占用1个字节再填充3个byte
	int  t;    //4byte
	char c2 : 7;//独占1个字节
}_Bit;  //实用9byte不是int的整数倍所以c2再填充3字节(1byte为最小单位)
12= sizeof(_Bit);

结构体的内存空间要顾后的特点所以把占用空间小的类型放前面依次增大

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值