C++篇:第七章_结构体、共用体和枚举_知识点大全
C++篇为本人学C++时所做笔记(特别是疑难杂点),全是硬货,虽然看着枯燥但会让你收益颇丰,可用作学习C++的一大利器
七、结构体、共用体和枚举
(一)结构体
C++的结构体中可以有构造函数,例:
struct ListNode { int val; ListNode *next; ListNode(int x) : val(x),next(NULL) {} };
class中的成员默认都是private的,结构体中的成员默认都是public的
结构体类型是可以用户自定义和声明的,因此,结构体的类型应该是无数多种
4. 结构体变量的操作:
① 可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量
② 只有结构变量的成员可以进行运算,变量之间不可以进行运算
③ 不能将一个结构体变量作为一个整体进行输入和输出,只能对结构体对象中的成员逐个进行输入或输出;例:student1和student2为结构体变量,并且它们已有值。不能cin>>student1;只能对结构体变量中的各个成员分别进行输入和输出
所有的成员在分配内存时都要与所有成员中占内存最多的数据类型所占内存空间的字节数对齐,例:最长的数据类型占 4 字节,所以是以 4 对齐
struct 能包含成员函数,能继承,能实现多态,可以有无参构造函数,和class的区别在于默认访问控制类型不同
struct成员类型不可以是它自己,因为会递归定义,理论上这样导致结构体的大小不能被计算(无限大小)。所以不能在结构体里的成员类型是结构体本身;但是成员可以定义为该结构体的指针
结构体对象可以进行赋值运算,但不能进行算术、关系运算等
将结构体对象作为函数实参传递到函数中,采用值传递的方法;将结构体数组和结构体指针作为函数参数,采用地址传递方式
10. 内存计算补齐原则:
数据对齐原则-内存按结构体成员的先后顺序排列,当排到该成员变量时,其前面所有成员已经占用的空间大小必须是该成员类型大小的整数倍,如果不够,则前面的成员占用的空间要补齐,使之成为当前成员类型的整数倍。假设是地址是从0开始,结构体中第一个成员类型char型占一个字节,则内存地址0-1,第二个成员从2开始,int型所占内存4个字节,根据原则b,第一个成员所占内存补齐4的倍数,故第一个成员所占内存:1 + 3 = 4; 第二个成员占5-8. 第三个成员占8个字节,满足原则b,不需要补齐,占9-16. 第四个成员占一个字节,占17. 故总内存为1 + 3 + 4 + 8 + 1 = 17个字节,但根据原则a,总字节数需是8的倍数,需将17补齐到24, 故此结构体总字节数为:24字节
结构体内什么数据类型占用内存最大,为n字节,则采用n字节对齐,例:
结构类型无法将自己的类型作为其成员的类型,因为自己的类型定义尚不完整,要在结束的大括号(})后才算定义完整
结构类型和其他基本类型或数组类型类似的用法,可以定义在函数之中或函数之外
14. 关于在结构体中用指针和用变长结构体(a[0])的区别:
① 在位置方面:指针可以放在任何地方,但是变长结构体的变长部分一定要放在结构体的最后。
② 在内存占用方面:指针会占一个指针的大小的内存空间,但是变长数组是不占内存的,它只是一个占位符。
③ 在内存布局方面:指针指向的内存和结构体的内存可以是不连续的,但是变长部分和结构体的内存必须是连续。
④ 在内存释放方面:使用指针,就要先释放指针所指的内存再释放整个结构体的内存,否则会照成内存泄露。
但是使用变长结构体直接释放整个结构体的空间就可以了
⑤ 一个限制:指针可以用在C++的类中,但是变长结构体就不可以了。因为有些编译器会将一些额外的信息放在类的最后,比如vptr或者虚基类的内容,使用了变长的类,就会把这部分的值改变,这种行为是未定义的,谁也不知道会发生什么
⑥ 故在结构体中定义变长数组,会出现编译器会认为这就是一个长度为0的数组,而且会支持对于长数组的越界访问的情况
(二)共用体
共用体(联合)是一种同一存储区域由不同类型变量共享的数据类型;结构体是用同一个名字引用的相关变量的集合
共用体的大小取内部最大的字节数
union 是一种特殊的类, C与C++中都可以使用
定义格式:union 共用体类型名{成员列表};// 共用体类型名与union一起作为类型名称
定义共用体对象时只能按一个成员给予初值
所有成员的值是相同的,区别是不同的类型决定了使用这个值的全部还是部分
(三)枚举
- 声明枚举变量三种方法:
① enum 枚举类型名 {命名枚举量列表(例:枚举标识符=整型常数)} 枚举对象名列表;
// 例:enum DIR {LEFT,UP} dir=LEFT;(dir为对象名)
② enum 枚举类型名 枚举对象名列表;
③ enum {命名枚举量列表} 枚举对象名列表;
枚举变量是全局变量的情况下, 枚举值的缺省值是0,不是枚举的第一个值。 其他情况,其值是不定的,而且不限定于所列出的枚举值;初始化的话就: {......}x=123;
命名枚举常量(大括号中的元素)是一个整形常量值,故是右值不是左值
weekday = weekday(2) // 其中weekday是枚举型,需要用此C++形式的强制类型转换才能赋值2
weekday = (weekday)2 // 此为C语言的强制类型转换
- 枚举变量的大小,即枚举类型所占内存的大小。由于枚举变量的赋值,一次只能存放枚举结构中的某个常数。所以枚举变量的大小,实质是常数所占内存空间的大小(常数为int类型,当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节)
- 枚举值默认从零开始并从先前的值开始向上计数
- 定义枚举类型的主要目的是:增加程序的可读性
- 如果某个枚举符的值均为非负,该枚举的表示范围就是[0:2k-1],2k是能使所有枚举符位于此范围内的最小的2的幂;如果存在负的枚举符值,则该枚举的取值范围就是[-2k:2k-1].这样就定义了一个最小的位段,其中能保存所有的枚举符值的常规2补码表示;例enum Number{one=1, two=2, four=4, eight=8};的取值范围是 0~15
C++篇:第七章_结构体、共用体和枚举_知识点大全的更多相关文章
- C++结构、共用体、枚举
一.结构 结构是C++OOP的基石.学习有关结构的知识僵尸我们离C++的核心OOP更近. 结构是用户定义的类型,同一个结构可以存储多种类型数据,这使得将一个事物的不同属性构成一个对象成为了可能.另外C ...
- 5、数组&字符串&结构体&共用体&枚举
程序中内存从哪里来 三种内存来源:栈(stack).堆(heap).数据区(.date): 栈(stack) 运行自动分配.自动回收,不需要程序员手工干预: 栈内存可以反复使用: 栈反复使用后,程序不 ...
- C语言高级-结构,共用体,文件,链表
C语言结构 标准声明方式 struct student{ int age; char sex; }; 这个可以在main函数中定义: struct student ...
- Java语言程序设计(基础篇) 第七章 一维数组
第七章 一维数组 7.2 数组的基础知识 1.一旦数组被创建,它的大小是固定的.使用一个数组引用变量,通过下标来访问数组中的元素. 2.数组是用来存储数据的集合,但是,通常我们会发现把数组看作一个存储 ...
- 瘋子C语言笔记(结构体/共用体/枚举篇)
(一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student { int num; char name ...
- C++复合类型(结构,共用体,枚举)
•结构是用户定义的类型,而结构的声明定义了这种类型的数据属性. 一.关键字struct声明: 定义了一种新类型 struct inflatable{ char name[20];//结构成员 fl ...
- C语言基础 (11) 结构体 ,共用体 枚举 typedef
1 课堂回顾 作用域与生命周期 2 static 局部变量 2 打字游戏 3 内存分区代码分析 4 结构体基本操作 (复合类型[自定义类型 #include <stdio.h> #incl ...
- C ++ _基础之共用体
由以下代码来进一步学习共用体 #include <stdio.h> #include<iostream> void main() { union un { int a; cha ...
- 第23章 SEH结构化异常处理(3)_终止处理程序
23.3 终止处理程序 23.3.1 程序的结构 (1)框架 __try{ //被保护的代码块 …… } __finally{ //终止处理 } (2)__try/__finally的特点 ①fina ...
- 第23章 SEH结构化异常处理(2)_编译器对系统SEH机制的封装
23.2 编译器层面对系统SEH机制的封装 23.2.1 扩展的EXCEPTION_REGISTRATION级相关结构:VC_EXCEPTION_REGISTRATION (1)VC_EXCEPTIO ...
随机推荐
- 可视化-vscode安装pandas
pandas 是基于NumPy 的一种工具,该工具是为解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.pandas提供了大量能使我们快速 ...
- Spring Boot整合OAuth2实现GitHub第三方登录
Github OAuth 第三方登录示例 1.第三方登录原理 第三方登录的原理是借助OAuth授权来实现,首先用户先向客户端提供第三方网站的数据证明自己的身份获取授权码,然后客户端拿着授权码与授权服务 ...
- 18.2 使用NPCAP库抓取数据包
NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库.它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用.与WinPcap一样,NPCAP库提供了一些 ...
- Redis 7.0 源码环境搭建与阅读技巧
天下武功,无坚不摧,唯快不破!我的名字叫 Redis,全称是 Remote Dictionary Server. 有人说,组 CP,除了要了解她外,还要给机会让她了解你. 那么,作为开发工程师的你,是 ...
- DOM级别
DOM1 DOM1级由两个模块组成:DOM核心(DOM CORE)和DOM HTML.其中,DOM核心规定的是如何映射基于XML的文档结构,以便简化对文档中任意部分的访问和操作.DOM HTML模块则 ...
- c#组合模式详解
基础介绍: 组合模式用于表示部分-整体的层次结构.适用于希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象的情况. 顾名思义,什么叫部分-整体,比如常见的前端UI,一个 ...
- Chromium VIZ工作流
在 Chromium 中 viz 的核心逻辑运行在 GPU 进程中,负责接收其他进程产生的 viz::CompositorFrame(简称 CF),然后把这些 CF 进行合成,并将合成的结果最终渲染在 ...
- centos7安装glibc_2.28和gcc 8.2
centos7默认的gcc版本是4.8.5,无法编译高版本的glibc 2.28,需要升级到gcc 8.2版本 注:gcc高版本和glibc 2.28不兼容 ## 查看自带默认的glibc strin ...
- Kubernetes:kube-apiserver 之准入
kubernetes:kube-apiserver 系列文章: Kubernetes:kube-apiserver 之 scheme(一) Kubernetes:kube-apiserver 之 sc ...
- 轻松一刻|Walrus CLI与CI/CD工具集成,轻松部署2048游戏
Walrus 是一款开源的基于平台工程理念.以应用为中心.以完整应用系统自动化编排交付为目标进行设计开发的云原生应用平台,简化和自动化应用部署与发布流程并与现有的 CI/CD 流水线无缝集成.今天我们 ...