C语言自定义类型:结构体

结构体定义与声明

定义:
结构体是一种用户自定义的数据类型,它允许你将不同类型的数据区别于数组)组合成一个整体。例如,如果你要表示一个学生的信息,可能包括姓名(字符串)、年龄(整数)、成绩(浮点数)等不同类型的数据。

声明:
struct(关键字)+tag(自己设置的结构体标签)
{
member-list;(成员列表)
}variable-list(变量列表);

在这里插入图片描述
!!!!students不是变量名

此外除了在变量列表定义结构体变量,也能在结构体声明后定义变量

在这里插入图片描述

结构体成员的访问

两种操作符

(一) ->
这是一个双目操作符,左测为结构体变量的指针,右侧为成员名称
在这里插入图片描述

(二) .
这也是个双目操作符,左测为结构体变量的名称,右侧为成员名称在这里插入图片描述

结构体变量的初始化

1.结构体变量可按照成员列表顺序初始化
在这里插入图片描述

2.结构体变量可按照特定顺序初始化(运用结构体成员访问操作符)
在这里插入图片描述

结构体内存对齐

在C语言内置数据类型中,每个类型所占的字节大小是一定的,如一个int占4字节
那么结构体变量呢?
在这里插入图片描述
如果是简单的将每个成员所占字节数相加结果是6
然而实际上结果是12
这是因为结构体发生了内存对齐

内存对齐的四大规则与对齐数

对齐数

结构体的对齐数是成员变量自身大小默认对齐数(一般编译器默认对齐数是 8 字节,有些编译器可能不同)中较小的那个值(没有默认对齐数则对齐数即为变量自身大小)。
上述代码在内存中的实际存放方式
在这里插入图片描述

修改默认对齐数

可以用到#pragma pack(n)
例如#pragma pack(1)
设置默认对⻬数为1

#pragma pack()
修改后再次使用可取消设置的对⻬数,还原为默认

规则1.

结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处(简单来说即从结构体变量起始位置开始)

如图c1放在了初始位置

规则2.

其他成员变量要对⻬到对⻬数的整数倍的地址处。

如图i的数据类型为int,大小为4,默认对齐数是8,较小值是4,因此对齐数4,因此i会放在4,8,…,4n处,因4未被占用所以从4开始

c2数据类型为char,大小为1,默认对齐数是8,较小值是1,因此对齐数是1,同理c2可以放在1,2,…,n处,因为8未被占用所以从8开始

规则3.

结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的对齐数)的整数倍

按照前两条可以知道此时长度仅是9(0-8长度为9),此时成员的对齐数分别为1,4,1最大对齐数为4,结构体的总大小为最大对齐数的整数倍(4n),由于此时长度为9,为了开辟足够空间,得出的最小n值为3,因此总长度为12。

规则4.

如果嵌套了结构体的情况(结构体成员包含另一个结构体),嵌套的内层结构体的对齐数是该结构体成员的对齐数中最大的一个
在这里插入图片描述

注意事项

结构体本身不占据内存空间,定义的结构体变量占据内存空间

结构体是一种自定义的数据类型,它本身类似于一个模板,用于定义数据的组织形式。就像一个建筑蓝图,它规定了建筑物(结构体变量)的结构和布局,但蓝图本身(结构体类型定义)并不占据实际用于存放建筑材料(数据)的空间

为什么存在内存对⻬

结论:结构体的内存对⻬是拿空间来换取时间的做法

匿名结构体

定义:匿名结构体是一种没有名字的结构体类型

在这里插入图片描述
局限性:匿名结构体的主要局限在于它没有类型名,所以不能在定义它的作用域(例如定义于函数内)之外使用,一般仅能使用一次

使用场景:和普通结构体一样,匿名结构体可以将相关的数据封装在一起。例如,在一个函数内部,如果只需要临时组合一些数据来传递或使用,可以使用匿名结构体
在这里插入图片描述

结构体传参

两种方式
在这里插入图片描述

更优解是传递结构体指针
函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。
如果传递⼀个结构体对象的时候,结构体过⼤,参数压栈的的系统开销⽐⼤,所以会导致性能的下降

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值