结构体进阶

结构体内存对齐

struct S1
{
 char c1;//第一个成员,从零开始0
 int i;//对齐数4的倍数,从4开始到5,6,7,浪费1,2,3
 char c2;//对齐数1的倍数,占据8的位置,此时结构体大小为9,但是结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍,所以再扩充到11的位置
};
 printf("%d\n", sizeof(struct S1));//是6吗?
//答案12,涉及知识点结构体内存对齐

首先得掌握结构体的对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。

  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值

VS中默认的值为8

Linux中没有默认对齐数,对齐数就是成员自身的大小

  1. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

  2. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yaBGbeuJ-1689256345243)(C:\Users\22724\AppData\Roaming\Typora\typora-user-images\image-20230712221207501.png)]

//练习-结构体嵌套问题
struct S3
{
 double d;//0到7,对齐数8
 char c;//占据8,对齐数1
 int i;//浪费9,10,11的位置,占据12,13,14,15的位置,但结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。此时大小为16,无需扩充
};

struct S4
{
 char c1;//0号位置
 struct S3 s3;//对齐数为8,根据如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
 //浪费1到7的位置,占据从8到15的位置
 double d;//对齐数为8,占据16的位置一直到21,此时结构体总大小22,扩充到32
};
printf("%d\n", sizeof(struct S4));//32


位段的练习

位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。

  1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型

  2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。

  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

//练习  
int main()
{
  unsigned char puc[4];
  struct tagPIM
  {
    unsigned char ucPim1;
    unsigned char ucData0 : 1;
    unsigned char ucData1 : 2;
    unsigned char ucData2 : 3;
  }*pstPimData;
  pstPimData = (struct tagPIM*)puc;
  memset(puc,0,4);
  pstPimData->ucPim1 = 2; 
  pstPimData->ucData0 = 3;
  pstPimData->ucData1 = 4;
  pstPimData->ucData2 = 5;
  printf("%02x %02x %02x %02x\n",puc[0], puc[1], puc[2], puc[3]);//02   29  00  00
  return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rMY3cyMk-1689256345244)(C:\Users\22724\AppData\Roaming\Typora\typora-user-images\image-20230713213217195.png)]

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值