C语言重要知识点总结(四)--结构体、结构体内存对齐、位段、枚举、联合

本文详细介绍了C语言中的结构体、内存对齐原理及规则,位段的使用和限制,以及枚举和联合(共用体)的概念和特性。通过对这些知识点的总结,有助于深入理解C语言的内存管理和数据组织。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、结构体

结构体:将不同类型的数据存放在一起,作为一个整体进行处理(有时候将结构体声明叫做模板,以为它勾勒出数据该如何存储,并没有实例化数据对象)

struct 结构体名
{
	成员变量1;
	成员变量2;
	.
	.
	.
};分号表示结构体定义结束
此时只是告诉编译器该如何表示数据,并未分配空间
struct Student
{
	char name[10];
	int age;
};
struct Student stu;//定义一个结构体变量stu
struct Student s = {"man",20};//定义一个结构体,并对其进行初始化

在初始化结构体应该注意:
1.如果在定义结构体时没有进行初始化,那么后面就不能全部一起初始化,只能为结构体成员单个赋值。
2.可以将结构体变量作为一个整体赋值给另一个相同类型的结构体变量,可以达到整体赋值的效果。

二、结构体的内存对齐

结构体的总大小为该结构体内部成员最大基本类型的整数倍,不足的要补齐,而不是简单的所有成员大小的总和。
结构体内存对齐规则:
1.第一个结构体成员在与结构体变量偏移量为0的地址处。
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认对齐数与该成员大小的较小值。(除了第一个成员变量外,其他的成员都有一个对齐数)
3.结构体所占内存的大小为结构体成员变量中最大数据类型大小的整数倍,不够整数倍需要补齐。
4.如果嵌套了结构体的话,嵌套的结构体对齐到自己的最大对齐数的整数倍处,外部结构体整体的大小就是所有最大对齐数(包含内部嵌套结构体的对齐数)的整数倍
。(也就是说:如果结构体1是另一个结构体2的成员,则在结构体2中,结构体1要从1内部成员最大对齐数的整数倍地址开始存储。)

int main()
{
	struct s1
	{
		char c1;
		int i;
		char c2;
	};
	struct s2
	{
		char c1;
		char c2;
		int i;
	};
	struct s3
	{
		double d;
		char c1;
		int i;
	};
	struct s4
	{
		char c1;
		struct s3 s;//8
		double d;
	};
	printf("%d\n",sizeof(struct s1));//12
	printf("%d\n",sizeof(struct s2));//8
	printf("%d\n",sizeof(struct s3));//16
	printf("%d\n",sizeof(struct s4));//32
	return 0;
}

在这里插入图片描述
为什么存在内存对齐:
1.平台原因:不是所有的硬件平台都能够访问任意地址处的任意数据。某些硬件平台只能在某些地址处取一些特定类型的数据,否则会抛出硬件异常。
2.性能原因:数据结构应该尽可能的在自然边界上对齐,原因在于,为了访问未对齐的内存,处理器需要做多次内存访问,而对齐的内存访问只需要一次。

三、位段

把一个字节中的8二进制位划分为几个不同的区域,并说明每个区域的二进制位数
位段的声明和结构体类似,但是有两个不同:
1.位段的成员必须是int ,unsigned int ,signed int
2.位段的成员名后面必须有一个冒号和数字来表示元素所占位数。

	struct 位段结构名
	{
		类型说明符1 位段名1 :位段长度;
		类型说明符2 位段名2 :位段长度;
		.
		.
		.
		类型说明符N 位段名N :位段长度;
	};
struct A
{
    int a:2;
    int b:5;
    int c:10;
};

C使用unsigned int 作为位字段的基本布局单元,因此,即使一个结构唯一成员只有一位字段,结构体的大小仍为32bit,4字节(不同平台下 unsigned int的大小可能不同)。
使用位段需要注意:
1.一个位段成员只能存储在同一个基本单元,不能跨两个单元,当一个单元所剩的空间不够存放下一个位段成员时,应当从下一个存储单元起始地址处开始存放。
2.一个位段成员的长度不能超过一个基本存储单元的长度。
3.一个位段成员可以是无名的,这时这个位段成员只能用作一个填充或调整位置,不能使用。
跟结构体相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。

四、枚举

枚举就是把可能的取值一一列举。

enum Color
{
    RED;
    GREEN;
    BLUE;
};

{}中的内容是枚举类型的可能取值,也叫枚举常量,这些可能取值都是有值的,默认从0开始,一次递增1,也可以在定义的时候赋初值。

enum Color
{
    RED=1;
    GREEN=3;
    BLUE=9;
};

五、联合(共用体)

将不同类型的集中变量存放到同一段内存中,这几个不同的变量共同占用同一段内存。

union Un
{
    char c;
    int i;
}
union Un un;//联合变量的定义

特点:
1.联合变量不能被直接引用,只能引用联合中的成员。
2.联合的同一个内存一般可以存放几种不同类型的成员,但是在一瞬间只能存放其中一种,即,每一个瞬间只有一个成员起作用。
3.联合变量的地址和它的各个成员的地址是相同的。
4.联合变量中起作用的成员是最后一次被赋值的成员。
5.数组可以是联合的成员,也可以定义共用体数组。

C语言重要知识点总结(一)–编译链接过程、数据类型、操作符
C语言重要知识点总结(二)–内存结构、函数调用过程(栈帧)、宏的优缺点以及##和#的使用
C语言重要知识点总结(三)–const、volatile、extern、static、restrict、register关键字解析

以上总结如有不足之处,希望指出,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值