C进阶-自定义类型详解(结构体+枚举+联合)

1.数据类型分类:

2.结构体:

①结构的基础知识:结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量

②结构的声明:

举例:假如描述一个学生

情况一:声明的同时定义结构体变量

情况二:声明的同时不定义结构体变量,并在之后定义

③特殊的声明:在声明结构的时候,可以不完全的声明(即匿名结构体类型)

解释:

④问题:

上面的两个结构在声明的时候省略掉了结构体标签(tag)。

那么问题来了?

注:匿名结构体的成员如果一样,在编译器看来也是不同的类型的结构体!

⑤:为⑥的自引用理解做准备:

⑥结构的自引用:

错误的自引用写法:

这种声明是错误的,因为这种声明实际上是一个无限循环,成员b是一个结构体,b的内部还会有成员是结构体,依次下去,无线循环。在分配内存的时候,由于无限嵌套,也无法确定这个结构体的长度,所以这种方式是非法的。

正确的自引用写法:

由于指针的长度是确定的(在32位机器上指针长度为4),所以编译器能够确定该结构体的长

⑦结构体声明时前面用typedef修饰:

这样写代码,可行否?

这里的目的是使用typedef为结构体创建一个别名Node。但是这里是错误的,因为类型名的作用域是从语句的结尾开始,而在结构体内部是不能使用的,因为还没定义。

⑧typedef修饰结构体时出现指针:

⑨结构体变量的定义和初始化

情况1:只声明不定义

情况2:声明后定义

情况3:既定义又初始化

情况4:结构体的嵌套

⑩结构体内存对齐--计算结构体的大小

内存对齐规则应用:

输出结果:8

我们来分析一下为什么结果是 8??

我们来看一下内存的分布图:

那我们再来看一下这个输出结果是多少呢?

输出结果:12

我们来分析一下为什么结果是 12??

我们来看一下内存的分布图:

结构体也是可以嵌套使用的,那如果嵌套的话,大小是怎么判断的呢?

输出结果:32

我们来分析一下为什么结果是 12??

我们来看一下内存的分布图:(图有点问题,s3对齐处应该是8)

为什么存在内存对齐呢?

解释访问:

结构体属性的偏移量计算——关于offsetof函数的详解

offsetof是一个宏,作用是计算结构体成员相对于起始位置的偏移量,使用时引用头文件stddef.h

案例一:

输出结果:

案例二:

输出结果:

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

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

案例:

S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别

⑬.修改默认对齐数

之前我们见过了 #pragma 这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数

注:①#pragma pack(1)等价于内存不对齐

②#pragma pack(n) n可以取(1, 2, 4, 8, 16)

⑭结构体传参

上面的 print1 和 print2 函数哪个好些?

答案是:首选print2函数

原因:

函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的 下降

结论:

结构体传参的时候,要传结构体的地址。

3.位段:

①什么是位段:

C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为位段。利用位段能够用较少的位数存储数据。

②位段的声明和结构是类似的,但有两处不同

案例:

输出结果:

解释:

③位段的内存分配:

案例:

解释:

④位段的跨平台问题

⑤位段的存储和大小端的区别

位段的应用

⑦位段占的二进制位数不能超过该基本类型所能表示的最大位数,即位段不能跨字节存储,比如在char是占1个字节,那么最多只能是8位

案例:

⑧在位段中不给其起名字,无法访问该位段,但是计算大小是仍占空间

案例:

输出结果:

⑨不可对位段进行取地址操作

案例:

输出结果:

⑩如果位段中存储的数据大于位段自身大小就会发生截断问题(在vs2013中测试的结果),在输出时会将截断之后的最高位当作符号位

案例:

输出结果:

解释:

如果将位段的类型换为无符号的:

输出结果:

我们接下来再用u%输出试一下:

输出结果:

4.枚举:

①定义格式为:

案例Ⅰ:

案例Ⅱ:

案例Ⅲ:

②以上定义的 enum Day , enum Sex , enum Color 都是枚举类型

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

案例:

输出结果:

案例:

输出结果:

③枚举的使用:(没搞懂,要问一下老师)

5.枚举的优点

①为什么使用枚举:

②便于调试

6.

结构体的关键字:struct

枚举的关键字:enum

联合体(共用体)的关键字:union

7.联合体:

①联合体的定义:联合体是一种特殊的自定义类型,联合体中的成员可以共用一部分内存,所以也叫做共用体

②联合体的声明和定义如下:

③内存占用情况:

④联合体的特点:

⑤证明:

输出结果:

⑥联合体大小的计算:

⑦判断联合体的大小端

以前判断的方法:

输出结果:

联合体方法:

输出结果:

解释:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值