| |
|
开发:
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/自定义类型详解】——结构体(struct)、位段、枚举(enum)、联合(union) -> 正文阅读 |
|
[C++知识库]【C/自定义类型详解】——结构体(struct)、位段、枚举(enum)、联合(union) |
主要目录1、结构体(struct)1.0 结构体类型的声明我们通常会用一个变量来定义一个事物,就比如我们要进行求和,我们通常会创建一个sum的变量来存放求和的结果,最终再打印sum,此时的sum就表示我们最终的求和结果。 但是,在生活中,有很多事物很难用一两句话来表示,就比如说一个学生,一个学生通常会由姓名、年龄、学号、班级…等很多信息来组成。 在C语言中也是如此,对于一个复杂对象,C语言提供了结构体,就拿上面的学生例子来说,对于这么一个复杂对象的描述,C语言是这样实现的。
在这里,姓名、年龄、学号、班级,这些属于结构体成员变量,结构体成员变量的类型可以不同。 1.0.1结构体的特殊声明
这就是结构体的不完全声明,大家可以理解为匿名类的声明。 对于结构体不完全声明,假如有以下这种情况:
此时,如果运行的话,编译器会报错,如下图: 1.1 结构的自引用大家看如下代码,假如我想在结构中包含一个类型为该结构本身的成员,以下这个代码是否可行?
答案是否定的,为什么呢?因为假如可行的话,这个结构体就会无限包含,如下: 会无限循环下去,这样的话,假如我们要计算它的大小,那么它的大小也是一个趋近于无限大的数,因为会一直包含,那假如一定要实现结构体包含一个结构体类型为该结构体呢?正确写法应该如下:
我们只需要把它写成结构体指针struct Node*的形式,这就意味着该指针指向的对象类型也是struct Node,就实现了在一个结构体中,包含一个类型为该结构本身的成员。同样,该成员作为一个指针存放在结构体中,它的大小为4(8)个字节。就不会出现上面这种“无限套娃”的现象。 1.2 结构体变量的定义和初始化结构体变量的定义有两种方法,一种是在声明结构体的同时,定义结构体变量,另一种就是直接定义结构体变量,如下:
在定义结构体变量的时候,我们也可以进行初始化:
另外,结构体变量是可以实现嵌套初始化的,如下所示:
1.3 结构体内存对齐我们知道,每个类型的变量都有它的大小(单位:字节),就比如,sizeof(int) ==4、sizeof(short) 的大小为2… 那么对于一个结构体来说,它的大小是多少呢?它的大小跟它的结构体成员变量之间有什么关系呢? 这里就涉及到了**结构体内存对齐**。话不多说,直接上代码演示:
在这里,我们可能会猜测,s1的大小与s2的大小相同,都是6byte,所以打印出来的是6 6,实际结果到底如何呢? 我们看到,这两种结果都和我们预想的不同,究竟为何呢?在这里,我们先来了解以下偏移量的概念,以及偏移量的计算,如下:
1. 第一个成员在与结构体变量偏移量为0的地址处。 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 具体到底是什么意思呢?第一条我们很好理解,就是第一个成员从偏移量为0的位置开始, 那么后面的具体是什么意思呢?还是来看上面的例子:
画个图来对比一下两者之间的差别:
练习题
1.4 结构体传参在调用函数时,结构体传参也是与我们常用到的变量传参一样,有两种方式,一种为传值调用,另一种为传址调用,如下:
两者相比显然是传地址更加好一点,简单来说,在这里传值调用的时候,形参也要用一个该结构体大小的结构体变量来接收,但是传址调用,只需要用一个4/8字节的结构体指针变量来接收,两者差别显而易见。 因此,在调用函数,结构体传参时,尽可能传址调用 1.5 结构体实现位段位段是什么? 位段的声明和结构是类似的,有两个不同: 举个例子:
在这里,A就是一个位段类型,那么sizeof(struct A)的大小是多少呢?诸君莫急,且往下看: 要计算它的大小,首先我们要了解位段的内存分配是如何实现的。
那么再回过头来看前面的那个题就简单了,首先开辟一个int类型的空间大小,即4byte,a、b、c一共占用17bit,剩下的15bit不够存放d,所以再次开辟一个int类型的空间,即4byte,所以一共8byte! 但并不保证别的平台也是如此,因为C99标准里并没有关于它的规定! 在一些情况下,跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但是有跨平台的问题存在。所谓的跨平台问题主要是以下几点:
2、枚举(enum)枚举就是列举,即把可能的取值一一列举。就比如一周可以有周一、周二…一直到周日, 在C语言中是这样来定义的:
{}中的内容是枚举类型的可能取值,也叫枚举常量。
枚举 vs #define
3、 联合(union)联合又叫联合体、共用体,它也是一种特殊的自定义类型
在这里,i和c共用一块空间,如下:
这里我们定义i的值为10,但是为什么打印的明明是c,结果也是10呢? 联合体的使用 百度笔试题:
这道题在之前的文章中写过了一种方法,就是先定义一个变量,初始化为1,然后强制类型转换为char*,然后解引用,就会访问第一个字节,如果是1,就说明是小端,反之大端存储。 这里我们还可以用联合体的巧妙性来解:
原理如下: 联合大小的计算应遵循以下原则:
end |
|
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/25 11:25:19- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |