从位段-对齐-到结构体字节大小(精简版)

位段

	位段:位段是通过结构体来实现的一种以位(bit位)为单位的数据存储结构,它可以把数据以位的形式紧凑的储存,并允许程序员对此结构的位进行操作。位段的成员必须是整型家族的成员(char、int、unsigned int、signed int……)(即基本类型除浮点型)
	基本类型位段:

在这里插入图片描述
指定数据位段大小

struct packed_data{
     unsigned char a : 4;
     unsigned int b : 19;
     unsigned char c : 3;
     unsigned int d : 5;
 };
// 输出为4字节, 4+19+3+5<32(位)

对齐(x86下,GCC)

	各数据类型位段长度不同,编译器为了提高CPU数据访问速度,规定每次访相问字节大小,所设定的规则每次读取相同字节大小数据,对数据复合数据做的处理叫做对齐。
	一般是4个字节(x86下,GCC),高于4字节是4字节的整数倍叫自然对齐,不足4字节的对齐叫做字节对齐,可以根据开发人员需求更改;

	数组 :按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。
	联合 :按其包含的长度最大的数据类型对齐。
	结构体: 结构体中每个数据类型都要对齐。

	其中结构体对其最麻烦;

结构体的对齐

	先举个例子:
#include <stdio.h>
struct packed_data{
     unsigned char a;  //char位段1字节
     unsigned int b;  //int位段4字节
     unsigned char c;  
     unsigned int d; 
 };
 int main()
 {
 	struct packed_data data;
 	data.a = 6;
 	data.b = 12;
 	data.c = 76;
 	data.d = 45;
 	
 	printf("%lu\n", sizeof(data)); //打印结构体字节大小
	
	return 0;
}
	编译运行得到16字节
	编译器是这样处理的

在这里插入图片描述
第一个数据char,位段1个字节,第二个int数据,位段是4字节,第二个int数据加入char后超出4字节空间大小,不能使数据对齐,直接存放入下一个空间
举几个例子

struct packed_data{
     char a;
     char b;
     char c;  
     int d; 
 };
 //结构体占8字节

struct packed_data{
     int a;
     char b;
     char c;  
     char d; 
 };
 //结构体占8字节

struct packed_data{
     long int a;
     char b;
     short c;  
     char d; 
 };
 //结构体占8字节

修改对齐规则

	1.__attribute__选项
struct stu
{
  char sex;
  int length;
  char name[10];
}__attribute__((aligned (1)));  //两个下划线
	//指定1字节对齐    注意:(不同编译器环境效果不同)
	//我linux GCC 无效果,依然是按4字节对其处理,输出20字节。
	//输出无规律,不太实用

struct stu
{
  char sex;
  int length;
  char name[10];
}__attribute__((aligned (8)));

//输出为24  不太实用 可以看下第二种方法
	2.#pragma pack(n);指定对齐数(单位:位)
  • 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
  • 使用伪指令#pragma pack (),取消自定义字节对齐方式。
    其中的n就是对齐系数。VS中默认的值为8;linux中的默认值为4。
#pragma pack(2);    //指定对其字节数为2字节
 struct packed_data{
     unsigned char a;
     unsigned int b;
     char name[10];
     unsigned int d;    
 }data;

data按照指定2字节对齐,输出结果为20;

更深入理解请参考:https://embedx.blog.csdn.net/article/details/108306754

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值