| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 自定义数据类型----->结构、枚举、联合 -> 正文阅读 |
|
[C++知识库]自定义数据类型----->结构、枚举、联合 |
通过一段时间的学习,我们已经了解了C语言的内置类型,也懂得怎么用内置类型去描述一些事物,但是在现实的生活情景里,仅仅用内置类型是无法准确描述一些事物的特征的!比如描述一个学生的信息,学生的信息是一个复杂的集合体,不可能仅仅通过某种单一的内置类型就可以准确地描述出来,为了解决这一问题,C语言设计者给我们设计了自定义的数据类型--->结构、枚举、联合。接下来,我们就仔细探究这三种类型。 一、结构体类型: 以描述学生的信息为案例,一个学生有如下的信息:姓名、性别、年龄这三个信息,那么姓名和性别用字符数组来存储,成绩用整型来存储的这样的一个信息综合体,每一个信息都是互相独立的,这种应用场景下我们应该使用结构体来存储,首先我们先来看结构体的声明的语法形式:
首先,struct是结构体关键字,表示接下来声明的类型是结构体类型!其次,紧挨着struct的是声明的结构体类型的名字,花括号里的是该结构体对应的成员的名字,接下来我们就创建一个学生结构体
了解了结构体的创建,接下来我们来看一看结构体变量应该如何使用!
运行结果如下: ?而假设你要用结构体指针,那么有两种访问结构体成员的方式:
注意:在使用学生结构体的时候,类型是struct Stu而不是Stu,如果仅仅只想使用Stu作为结构体的类型名需要对struct进行typedef,即
第二:结构体成员不能包括同类型的成员,但可以包括同类型的指针,同样以学生结构体为例
补充:数据结构中的链表就是存储同类型指针的一种结构体,等到了数据结构的分析我们会介绍链表,这里先稍微提一提。 重点:结构体大小的计算 这是非常重要的知识点,关于结构体大小的计算,结构体的大小并不是简单的成员大小总和的叠加,它遵循的是内存对齐的规则! 对齐的规则如下:
对齐数:是指自身的类型大小和默认对齐数二者中的较小值,在vs环境下,默认对齐数是8 接下来我们来通过两个案例来尝试计算结构体的大小:
我们的分析如图所示: ?我们分析的结果是12个字节,那么程序运行的结果是否和我们预料的一样呢? 程序运行结果如下: ?确实结果和我们预期的一致,说明确实结构体在内存中存在内存对齐的现象,那么为什么会结构体需要在存储数据的时候采用内存对齐的方式呢?具体的原因大致有两点: 1.早期的计算机的寄存器只能在特定位置读取数据,所以在读取数据之前,编译器会对数据进行两次对齐处理以便于数据能够放置在特定的位置便于读取,而如果在存储的时候就采取内存对齐的方式,那么只需要在读取之前就只要在对齐一次就可以了,这样提高了效率! 2.采取内存对齐的方式也有利于一些结构体的拷贝操作等等 位段: 这也是一种结构体内部数据的存储形式,具体来讲就是按位进行存储
这里的结果是2,首先开辟了1个字节,a,b两个数据一共占用了6个比特位,剩下的比特位不够存放数据c,所以又开辟了1个字节的空间给c,所以最后一共开辟了两个字节。 接下来看这样一段代码:
打开内存窗口观察结果如下:
发现结果和我们预期的是一样的,所以说在vs环境下,当一个位段大于剩余的比特位的时候,编译器会另外开辟1个字节,在新的字节里处理信息!不过对于位段有以下几个注意点: 1.使用位段只能是char,unsigned char,int ,unsigned int这几种数据类型 2.使用位段式存储读取的数据是按有符号数还是无符号数理解是标准没有规定的 3.不同的机子对应的数据的比特位是不同的,所以位段不具有跨平台性! 二、枚举类型: 在生活中,一些场景下的可能性是可以被枚举出来的,C语言提供了可以描述可被枚举的类型的集合---->枚举类型,关键字是enum,我们以枚举一周7天的可能性为例:
这就是枚举的语法格式,在使用枚举类型的时候有以下几个注意的点 1.枚举类型的每种可能取值都是有对应的整型值的:
2.给某个枚举的可能取值指定初始值以后,后面的值以这个值为基准值而变化,以上面的枚举类型的值为例:
我们将Fri,Sat,Sun的值打印出来看看是否收到了影响:运行结果如下: ?可以看出,Fri,Sat,Sun的值变成了6,7,8。因为Thur变成了5,所以向后的枚举类型的值依次加一。 3.枚举类型的值是常量,不能够修改!而枚举的内部我们的Thur=5并不是修改的值,而是初始化,因为常量也必须有一个初始值。 注意:在C语言编译器下,给枚举类型的变量赋整型初始值并不会报错,但不代表这是正确的! 在C++编译器下,枚举类型的变量必须用枚举类型的值赋值,否则就会报错!所以在使用枚举类型变量的时候,要用枚举类型的常量赋值才是正确的! 三、联合体 在C语言里,还有一类自定义的数据类型----->联合体,那么联合体有什么特别之处?联合体的应用场景又是什么样的呢?别急,听我慢慢和你说。 我们来看这样一段代码:
?我们发现,联合体变量a,成员c,i的地址都是相同的,这个结果说明,成员c和成员i共用了一部分空间!事实上,联合体的特殊之处就是成员共用一部分空间! 那么联合体的大小应该怎么计算呢?联合体主要遵寻两个规则
就拿代码里的联合体做例子来说,联合体的大小最小是整型i的大小4,然后最大对齐数是4,因为4刚好是最大对齐的整数倍,所以该联合体的大小就是4 或许聪明的你已经猜到了联合体不能同时使用两个成员!因为成员共享一部分内存空间的原因,对其中一个成员的改变一定会改变另一个成员,所以联合体不能同时使用两个成员! 那么联合体有没有什么具体的使用场景呢?有,在你明确两种选择中你只会使用其中一种的情况下,可以使用联合体不能同时使用的特点来设计!下面我用联合体来研究计算机的大小端字节序。 首先先来回顾大小端存储的概念:
曾经我们使用的是利用的是指针类型的意义来研究,今天我们来使用联合体来研究:
我们可以看到,大小端不同的地方就是第一个字节,而联合体的成员的地址都是相同的,那么不妨我们定义一个联合体,该联合体有一个char类型和int类型的成员,我们往int类型的成员放置1,在访问char类型的成员,这样就可以获取第一个字节的内容来判断存储模式!
运行结果如下: ?可以看到,程序依旧运行出了正确的结果,对于这段代码还可以进行一点点的小优化,因为这个结构体我们仅仅使用了一次,所以我们可以利用匿名联合体只能使用一次的特性来优化代码:
这就是联合体在探究大小端字节序的应用。 以上就是自定义数据类型的一些知识的整理,希望对大家的学习有所帮助,祝大家新年快乐! ? |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 8:52:13- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |