结构体的对齐规则和位段

文章介绍了结构体的对齐规则,包括成员对齐、结构体总大小的对齐原则,并通过示例解释了这些规则。接着,讨论了结构体位段的使用,如何节省内存空间,以及位段的限制和跨平台问题。位段虽能减少内存占用,但由于其不兼容性和不确定性,应当谨慎使用。
摘要由CSDN通过智能技术生成

前言

在初步学习了结构体之后我们需要更深层次的了解和学习结构体具有的一些性质
此篇文章讲述结构体的对齐规则和位段

一、结构体的对齐规则

了解结构体的对齐规则的重要作用就是计算结构体的大小
根据规定有以下规则:
1.结构体的第一个成员永远都放在0偏移处

2.从第二个成员开始,以后的每个成员都要对齐到某个对齐数的整数倍处
这个对齐数是成员自身大小和默认对齐数的较小值
注意:VS环境下默认对齐数是8,gcc环境下没有默认对齐数,没有默认对齐数时,对齐数就是成员自身的大小

3.当成员全部存放进去后,结构体的总大小必须是所有成员的对齐数中最大对齐数的整数倍。如果不够,则浪费空间对齐。

4.如果嵌套了结构体,嵌套的结构体成员要对齐到自己成员的最大对齐数的整数倍处。
整个结构体的大小,必须是最大对齐数的整数倍,最大对齐数包含中嵌套的结构体成员中的对齐数。

在简略了解规则之后,我们举几个例子帮助深刻理解对齐规则

例1.

struct S1
{
	char c1;
	int i;
	char c2;
};
	printf("%d\n", sizeof(struct S1));

在这里插入图片描述

我们放到编译器里面验证
在这里插入图片描述

例2.

struct S2
{
	char c1;
	char c2;
	int i;
};
	printf("%d\n", sizeof(struct S2));

在这里插入图片描述

在这里插入图片描述

例3.

struct S3
{
double d;
char c;
int i;
};
printf("%d\n", sizeof(struct S3));

在这里插入图片描述

在这里插入图片描述

例4.

struct S4
{
char c1;
struct S3 s3;
double d;
};
printf("%d\n", sizeof(struct S4));

在这里插入图片描述

在这里插入图片描述

二、结构体位段

结构体位段的使用能够有效减少内存空间的使用

位段的声明和结构是类似的,有两个不同:
1、位段的成员必须是 int 、unsigned int 、或signed int以及char类型(只要是整型家族就行,一般都是相同的类型出现)
2、位段的成员名后边有一个冒号和一个数字(数字的含义是该变量给定的bit位大小)
例如:

struct A
{
	int a:2;
	int b:5;
	int c:10;
	int d:30;
};
在vs的编译器情况下 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时会舍弃剩余的位
所以上述代码 在该结构体向int对齐的情况下开辟一个段位会给定32个bit位四个字节,a,b,c三个变量一共占17个bit位 只剩余了15个bit位而d变量需要占30个bit位 所以d变量会重新开辟一个段位  也就是上述变量一共需要64个bit位或者说8个字节的空间

其次在使用位段时,我们需要注意

  1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
  2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段

虽然位段的使用能够减少空间的使用,但局限性很大,不仅仅在使用情况上存在限制,而且存在平台的不兼容性

位段的跨平台问题

  1. int 位段被当成有符号数还是无符号数是不确定的
  2. 位段中最大位的数目不能确定,16位机器最大16,32位机器最大32,写成27,在16位机器会出问题
  3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义
  4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的

所以位段的使用需要特定的条件,并且还需要考虑跨平台的不兼容性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值