结构体介绍(2)

发布于:2024-05-06 ⋅ 阅读:(32) ⋅ 点赞:(0)


前言

根据之前讲了结构体的《声明》、《创建》、《初始化》、《结构体内存对齐》。 接下来我们就来深入探讨结构体


问题:那么有没有考虑结构体嵌套结构体的内存对齐呢?

一、结构体的内存对齐之深入理解

示例:

struct S3
{
	double d;
	char c;
	int i;
};
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
int mian()
{
	struct S4 s4 = { 0 };
	printf("%zd\n", sizeof(s4));
	return 0;
}

根据规则4:如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员最大对齐数的整数辈出,结构体的整体大小就是所有最大对齐数(包含嵌套结构体中成员对齐数)的整数倍。
那么根据以上代码:
s3就对应其中成员最大对齐数为double类型(8)
再根据规则1、2、3就可以得出这个结构体的大小
在这里插入图片描述

为什么存在内存对齐?

在这里插入图片描述

修改默认对齐数

#pragma 这个预处理指令,可以改变编译器的默认对齐数。

#pragma pack(1)//把默认对齐数定义为1
struct S
{
	char c;
	int i;
	char a;
};
int main()
{
	printf("%zd\n", sizeof(struct S));
	return 0;
}

在这里插入图片描述

二、结构体传参

2.1:该怎么传参呢?

代码如下(示例):

struct S
{
	int arr[1000];
	int n;
	double b;
};
void print1(struct S tmp)
{
	int i = 0;
	for (i = 0;i < 5;i++)
	{
		printf("%d", tmp.arr[i]);
	}
	printf("%d\n", tmp.n);
	printf("%lf\n", tmp.b);
}
int main()
{
	struct S s = { {1,2,3,4,5},100,3.14 };
	print1(s);//这里s里面的数组arr[1000](空间大),但是传参过去时会有空间的浪费
	return 0;
}

这里s里面的数组arr1000,但是传参过去时会有空间的浪费,那么我们用地址来传
同时我们也可以达到同样的效果

修正:
struct S
{
int arr[1000];
int n;
double b;
};
void print1(struct S* tmp)
{
int i = 0;
for (i = 0;i < 5;i++)
{
printf(“%d”, tmp->arr[i]);
}
printf(“%d\n”, tmp->n);
printf(“%lf\n”, tmp->b);
}
int main()
{
struct S s = { {1,2,3,4,5},100,3.14 };
print1(&s);
return 0;
}
在这里插入图片描述

三、结构体实现位段

3.1什么是位段

在这里插入图片描述
比如:
struct S
{
int_a:2;//位段结构、4个字节----32个bit
int_b:5;//位段结构、4个字节----32个bit
int_c:10;//位段结构、4个字节----32个bit
int_d:30;//位段结构、4个字节----32个bit
};
int main()
{
return 0;
}

首先: 位段中的位是二进制位
那么0就可以用2个bit来表达00
1-----------2---------------01
2-----------2---------------10
3…以此类推
在这里插入图片描述
这样可以节省很多空间
在这里插入图片描述
节省内存
那么位段是怎么分配内存的呢?

位段的内存分配

3.2

在这里插入图片描述
根据以下图片分析:
在这里插入图片描述
每次申请1个字节(8个bit位)这里采用了从右向左,浪费操作。
在这里插入图片描述
在这里插入图片描述
按照16进制来表达时:0x620304。
浪费的bit用0来填补
在这里插入图片描述
例子:在这里插入图片描述
根据上面的图片可知:
当不够你所要申请的空间,那么就会重新开辟一个空间来容纳你的空间
(如:第一个a申请了2个bit,第二个申请了5个bit,第三个申请10个bit,而第四个要30个bit,那就在申请一个空间来容纳第四个空间!

位段的跨平台问题

在这里插入图片描述
在16位int是2个字节!!!
如果我们把16位看成32位那么这样就会产生不同结果!!!
所以位段是不跨平台的。


总结

1:结构体内存对齐----浪费空间来促进时间;
2:位段-------节省内存;
3:跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在