结构体类型的大小与位段

我们之前学习到各类型的空间大小所占的字节:

 那么我们定义的结构体类型所占的空间大小又是多少呢?

结构体内存对齐

对齐规则

1.结构体的第一个成员放在0偏移处。(就是存放结构体类型的第一个字节空间处)

2.从第二个成员开始,之后的每一个成员都要对齐到某个对齐数的整数倍处。

    该成员对齐数是:成员自身大小和默认对齐数的较小值(VS的默认对齐数是8)(gcc无        默认对齐数)

3.当成员全部存放进去之后,结构体的总大小必须是所有成员中最大对齐数的整数倍。

    (如果不够整数倍就浪费内存也要空间对齐)

4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整     体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。(类似于把嵌套结构体     拆开)

 struct test 1

 //最终需要的八个字节正好是最大对齐数4的整数倍,即:已经对齐好了。

验证

// char a 的地址:0x00007ff7e86fc1e8,short b 的地址:0x00007ff7e86fc1ea之间正好差一个字节的空间,故满足。如果你还不确定就拿起你的“武器”开始调试看看吧!

//其实这里也可以用 offsetof 实现:计算一个结构体的成员相较于他的起始位置的偏移量。

  struct test 2

 //最终需要十个字节,并不是最大对齐数4的整数倍,即:花费两个字节的空间对齐 共十二个字节

   struct test 3

 //这里的最大对齐数是8,而16也恰好是较大对齐数8的倍数。

 补充

struct tes
{
	double a;
	char b;
	int i;
};
struct test
{
	char a;
	struct tes b;
	double d;
};

int main()
{
	printf("%zu\n", sizeof(struct test));

	return 0;
}

//猜猜结果? 规则四喔

 解析

结构体的整体大小就是所有成员最大对齐数(含嵌套结构体的对齐数)的整数倍。(类似于把嵌套结构体拆开)

//而这里的所有最大对齐数就是8,恰巧32是8的整数倍


 修改默认对齐数

我们上面使用VS在计算中的默认对齐数是8,如果我没觉得8不合适的话也是可以自己进行修改的,按你的想法来

 展示

 //提一下哈,这个虽然好用,但我们最好别设出一个对齐数让自己尴尬哈


位段

百度百科:位段,C语言允许在一个 结构体 中以位为单位来指定其成员所占 内存 长度,这种以位为单位的成员称为“位段”或称“ 位域 ”

对象:一般是整型

功能: 能够减少储存数据的位数(比特位)节省空间

定义: 信息的存取一般以字节为单位

举例使用(VS平台)

typedef struct test
{
	int a : 2;//占2个比特位
	int b : 5;//占5个比特位
	int c : 10;//占10个比特位
	int d : 30;//占30个比特位
}test;
int main()
{
	printf("%zu\n", sizeof(test));
	return 0;
}

编译

你可能会说47个比特位,六个字节就可以放得下了呀,为什么是八个字节两个呢 

 那就请您在看看啦!

位段的内存分配

规则

1.位段的成员可以是 int ,unsigned int或者char类型

2.位段的空间是按照需要以一次提供 四个字节(int)或者一个字节(char)的方式来开辟的

3.位段涉及许多的不确定因素,不跨平台(不同的编译器使用位段可能不一样)

 那么我们就以VS的编译器看看是如何分配的吧:

举例

typedef struct test
{
	char a : 3;
	char b : 4;
	char c : 5;
	char d : 4;
}test;
int main()
{
	test k = { 0 };//初始化为全0
	k.a = 9;
	k.b = 8;
	k.c = 7;
	k.d = 6;

	return 0;
}

解析

 ​编译

 以上仅仅只是在VS上的结果,在其他的平台上可能就不一样了。并且VS上是一次性开辟八个比特位(一个char)的空间,使用时多余的空间不足以存储下一个数据时,多余的空间就浪费掉,不再使用(之后也不用)

 //位段相对于结构体而言就节省了很多的空间,但是位段不具有跨平台性。

位段的作用:可以使数据单元节省储存空间,当程序需要成千上万个数据单元时,这种方法就显得尤为重要。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

高居沉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值