最详细讲解结构体,枚举,联合,看完就搞懂了

结构体

前面我们讲过一些结构体的知识这里不在叙述,补充一些没有的

匿名结构体

在这里插入图片描述
在这里插入图片描述

匿名结构体有两点需要注意

1.匿名结构体只能使用一次,在创建的时候就要有变量,相当于全局变量。
2.两个匿名结构体虽然声明都是一样的,但是编译器会把这两个声明当成完全不同的两个类型

结构体的自引用

在结构中包含一个类型为该结构本身的成为是否可以呢?

在这里插入图片描述
上面这种自引用是不可以的,如果这样声明,sizeof(struct Node)需要开辟多大空间。

在这里插入图片描述
采用这种方法,我只需要放一个int型数据大小,再放一个struct Node*指针大小就可以,这个指针会帮我找到下一个数据的位置。

结构体内存对齐

前面文章讲过结构体内存对齐规则,但是并没有讲结构体嵌套结构体,下面就讲讲这种。
在这里插入图片描述
在这里插入图片描述
如果嵌套了结构体先把嵌套的结构体总大小算出来,然后按照第2条规则放第一个成员的位置。弄完嵌套的,再算其他的的成员。
在这里插入图片描述
为什么会有结构体内存对齐?
1.平台原因(移植原因)

不是所有的硬件平台都能随意访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据;否则抛出硬件异常

2.性能原因

数据结构(尤其是栈)应该尽可能地在自然边界对齐
原因在于,对于访问未对齐的内存,处理器需要做两个内存访问;而对齐的内存访问仅需要一次访问

总的来说

结构体的内存对齐就是拿空间来换取时间的做法

那么设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:

让占用空间小的成员尽量集中在一起

修改默认对齐数

在这里插入图片描述

结构体传参

在这里插入图片描述
结构体有两中传参方式,但是我们知道形参是实参的临时拷贝,如果实参过大,传给形参,形参也会开辟一大片空间,这样浪费了内存空间,

所以结构体传参要传地址

位段

位段的声明和结构体类似,但有两个不同

1.位段的成员必须是int,unsigned int,signed int或者char(char属于整型家族)
2.位段的成员名后边有一个冒号和数字
在这里插入图片描述
这样一个位段的大小是多少;
在这里插入图片描述

位段的内存分配

位段的空间是按照4个字节(int)或者1个字节(char)的方式开辟的

就如上面,先开辟了一个int大小的字节,32个byte,a,b,c共占17个,还剩下15个。但是要分配给d的不够,所以又开辟了一个int大小字节。

使用位段的意义:

比如你用一个int a=2;这样会开辟4个byte,32个bit位,但是2的二进制00000000 00000000 00000000 00000010;
只需要保存最后两位01;就可以把2保存下来,
这样做是为了节省内存空间

位段的跨平台问题

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

枚举

枚举顾名思义就是一一列举
把可能的取值一一列举
比如

性别,月份,等等

枚举的类型

在这里插入图片描述
{ }中的内容是枚举类型的可能取值,也叫枚举常量
这些可能取值都是有值,默认从0开始,依次递增1,当然在定义中时候也可以赋初值

在这里插入图片描述

枚举的优点

我们可以使用#define定义常量,那为什么非要使用枚举?
枚举的优点

增加代码的可读性和可维护性
和#define定义的标识符比较枚举有类型差错,更加严谨
防止了命名污染
便于调试
使用方便,一个可以定义多个常量

枚举的使用

在这里插入图片描述
注意只能拿枚举常量给枚举变量赋值,才不会出现类型差异,比如day=5;这样就是把int转化给enum Day会出现问题

联合(共用体)

联合类型的定义

联合也是一种特性的自定义类型
这种类型定义的变量也包含了一系列的成员,特征是这些成员公用同一块空间

在这里插入图片描述

联合的特点

联合的成员是共用同一块内存空间,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大得那个成员)

使用联合体查看当前电脑大小端存储方式

在这里插入图片描述

联合大小的计算

联合的大小至少是最大成员的大小
当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍。

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值