• C++篇为本人学C++时所做笔记(特别是疑难杂点),全是硬货,虽然看着枯燥但会让你收益颇丰,可用作学习C++的一大利器

七、结构体、共用体和枚举

(一)结构体

  1. C++的结构体中可以有构造函数,例:

    struct ListNode {
    
    int val;
    
    ListNode *next;
    
    ListNode(int x) : val(x),next(NULL) {}
    
    };
  2. class中的成员默认都是private的,结构体中的成员默认都是public的

  3. 结构体类型是可以用户自定义和声明的,因此,结构体的类型应该是无数多种

4. 结构体变量的操作:

① 可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量

② 只有结构变量的成员可以进行运算,变量之间不可以进行运算

③ 不能将一个结构体变量作为一个整体进行输入和输出,只能对结构体对象中的成员逐个进行输入或输出;例:student1和student2为结构体变量,并且它们已有值。不能cin>>student1;只能对结构体变量中的各个成员分别进行输入和输出

  1. 所有的成员在分配内存时都要与所有成员中占内存最多的数据类型所占内存空间的字节数对齐,例:最长的数据类型占 4 字节,所以是以 4 对齐

  2. struct 能包含成员函数,能继承,能实现多态,可以有无参构造函数,和class的区别在于默认访问控制类型不同

  3. struct成员类型不可以是它自己,因为会递归定义,理论上这样导致结构体的大小不能被计算(无限大小)。所以不能在结构体里的成员类型是结构体本身;但是成员可以定义为该结构体的指针

  4. 结构体对象可以进行赋值运算,但不能进行算术、关系运算等

  5. 将结构体对象作为函数实参传递到函数中,采用值传递的方法;将结构体数组和结构体指针作为函数参数,采用地址传递方式

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字节

  1. 结构体内什么数据类型占用内存最大,为n字节,则采用n字节对齐,例:

  2. 结构类型无法将自己的类型作为其成员的类型,因为自己的类型定义尚不完整,要在结束的大括号(})后才算定义完整

  3. 结构类型和其他基本类型或数组类型类似的用法,可以定义在函数之中或函数之外

14. 关于在结构体中用指针和用变长结构体(a[0])的区别:

① 在位置方面:指针可以放在任何地方,但是变长结构体的变长部分一定要放在结构体的最后。

② 在内存占用方面:指针会占一个指针的大小的内存空间,但是变长数组是不占内存的,它只是一个占位符。

③ 在内存布局方面:指针指向的内存和结构体的内存可以是不连续的,但是变长部分和结构体的内存必须是连续。

④ 在内存释放方面:使用指针,就要先释放指针所指的内存再释放整个结构体的内存,否则会照成内存泄露。

但是使用变长结构体直接释放整个结构体的空间就可以了

⑤ 一个限制:指针可以用在C++的类中,但是变长结构体就不可以了。因为有些编译器会将一些额外的信息放在类的最后,比如vptr或者虚基类的内容,使用了变长的类,就会把这部分的值改变,这种行为是未定义的,谁也不知道会发生什么

⑥ 故在结构体中定义变长数组,会出现编译器会认为这就是一个长度为0的数组,而且会支持对于长数组的越界访问的情况

(二)共用体

  1. 共用体(联合)是一种同一存储区域由不同类型变量共享的数据类型;结构体是用同一个名字引用的相关变量的集合

  2. 共用体的大小取内部最大的字节数

  3. union 是一种特殊的类, C与C++中都可以使用

  4. 定义格式:union 共用体类型名{成员列表};// 共用体类型名与union一起作为类型名称

  5. 定义共用体对象时只能按一个成员给予初值

  6. 所有成员的值是相同的,区别是不同的类型决定了使用这个值的全部还是部分

(三)枚举

  1. 声明枚举变量三种方法:

① enum 枚举类型名 {命名枚举量列表(例:枚举标识符=整型常数)} 枚举对象名列表;

// 例:enum DIR {LEFT,UP} dir=LEFT;(dir为对象名)

② enum 枚举类型名 枚举对象名列表;

③ enum {命名枚举量列表} 枚举对象名列表;

  1. 枚举变量是全局变量的情况下, 枚举值的缺省值是0,不是枚举的第一个值。 其他情况,其值是不定的,而且不限定于所列出的枚举值;初始化的话就: {......}x=123;

  2. 命名枚举常量(大括号中的元素)是一个整形常量值,故是右值不是左值

  3. weekday = weekday(2) // 其中weekday是枚举型,需要用此C++形式的强制类型转换才能赋值2

​ weekday = (weekday)2 // 此为C语言的强制类型转换

  1. 枚举变量的大小,即枚举类型所占内存的大小。由于枚举变量的赋值,一次只能存放枚举结构中的某个常数。所以枚举变量的大小,实质是常数所占内存空间的大小(常数为int类型,当前主流的编译器中一般是32位机器和64位机器中int型都是4个字节)
  2. 枚举值默认从零开始并从先前的值开始向上计数
  3. 定义枚举类型的主要目的是:增加程序的可读性
  4. 如果某个枚举符的值均为非负,该枚举的表示范围就是[0:2k-1],2k是能使所有枚举符位于此范围内的最小的2的幂;如果存在负的枚举符值,则该枚举的取值范围就是[-2k:2k-1].这样就定义了一个最小的位段,其中能保存所有的枚举符值的常规2补码表示;例enum Number{one=1, two=2, four=4, eight=8};的取值范围是 0~15

C++篇:第七章_结构体、共用体和枚举_知识点大全的更多相关文章

  1. C++结构、共用体、枚举

    一.结构 结构是C++OOP的基石.学习有关结构的知识僵尸我们离C++的核心OOP更近. 结构是用户定义的类型,同一个结构可以存储多种类型数据,这使得将一个事物的不同属性构成一个对象成为了可能.另外C ...

  2. 5、数组&字符串&结构体&共用体&枚举

    程序中内存从哪里来 三种内存来源:栈(stack).堆(heap).数据区(.date): 栈(stack) 运行自动分配.自动回收,不需要程序员手工干预: 栈内存可以反复使用: 栈反复使用后,程序不 ...

  3. C语言高级-结构,共用体,文件,链表

    C语言结构 标准声明方式 struct student{        int age;        char sex;    }; 这个可以在main函数中定义:  struct student ...

  4. Java语言程序设计(基础篇) 第七章 一维数组

    第七章 一维数组 7.2 数组的基础知识 1.一旦数组被创建,它的大小是固定的.使用一个数组引用变量,通过下标来访问数组中的元素. 2.数组是用来存储数据的集合,但是,通常我们会发现把数组看作一个存储 ...

  5. 瘋子C语言笔记(结构体/共用体/枚举篇)

    (一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student { int num; char name ...

  6. C++复合类型(结构,共用体,枚举)

    •结构是用户定义的类型,而结构的声明定义了这种类型的数据属性. 一.关键字struct声明:   定义了一种新类型 struct inflatable{ char name[20];//结构成员 fl ...

  7. C语言基础 (11) 结构体 ,共用体 枚举 typedef

    1 课堂回顾 作用域与生命周期 2 static 局部变量 2 打字游戏 3 内存分区代码分析 4 结构体基本操作 (复合类型[自定义类型 #include <stdio.h> #incl ...

  8. C ++ _基础之共用体

    由以下代码来进一步学习共用体 #include <stdio.h> #include<iostream> void main() { union un { int a; cha ...

  9. 第23章 SEH结构化异常处理(3)_终止处理程序

    23.3 终止处理程序 23.3.1 程序的结构 (1)框架 __try{ //被保护的代码块 …… } __finally{ //终止处理 } (2)__try/__finally的特点 ①fina ...

  10. 第23章 SEH结构化异常处理(2)_编译器对系统SEH机制的封装

    23.2 编译器层面对系统SEH机制的封装 23.2.1 扩展的EXCEPTION_REGISTRATION级相关结构:VC_EXCEPTION_REGISTRATION (1)VC_EXCEPTIO ...

随机推荐

  1. 若依vue分离版(ruoyi-vue)跳过token验证,设置白名单

    找到SecurityConfig类的configure方法 如图所示 在设置白名单后还需要把接口上的权限标识符去掉.然后需要重启一下项目,热加载不行,会报错.

  2. 【对象存储】Minio本地运行和 golang客户端基本操作

    运行环境 OS和Golang版本: go version go1.21.0 darwin/arm64 安装 源码安装 下载最新版本的源码,地址https://github.com/minio/mini ...

  3. python 安装包时 ERROR: Failed building wheel for webrtcvad

    报错信息: error: subprocess-exited-with-error × Building wheel for webrtcvad (pyproject.toml) did not ru ...

  4. 鸿蒙极速入门(六)-加载请求状态管理-LoadState+观察者模式

    背景 1.在ArkTS的架构中,没有明确的可管理的加载请求状态的脚手架,在进行网络请求过程中,无法简单的进行交互响应. 2.参考Android中的LoadState写了一个简单的脚手架,以便在日常开发 ...

  5. fastjson反序列化Map对象为null?其实它只是一个地址,试试Map深拷贝

    今天遇到一个小问题,我用fastjson,把一个map对象转为实体类对象返回给前端的时候,map对象里面的一个属性既然为null. 由于前端需求,我们需要返回一个json里面,有两个属性是一样的(都是 ...

  6. Redis宕机恢复

    AOF(Append Only File) Redis持久化:AOF日志 用 AOF 方法进行故障恢复的时候,需要逐一把操作日志都执行一遍.如果操作日志非常多,Redis 就会恢复得很缓慢,影响到正常 ...

  7. 实现MyBatisPlus自定义sql注入器

    目标:新增mysql下的 插入更新的语法 INSERT INTO %s %s VALUES %s ON DUPLICATE KEY UPDATE %s 新增方法类,新增的方法名称为insertOrUp ...

  8. powerdesigner 生成sql语言

    首先要确定的是自己已经准备好一个概念模型 在概念模型界面点击上方工具栏中的Tools->Generate logical data model.. 生成逻辑模型 同样的操作生成物理模型 Gene ...

  9. AcWing 456. 车站分级

    原题链接AcWing 456. 车站分级 抽象出题意,停靠过的车站的等级一定严格大于为停靠过的车站的等级,且不存在环,例如车站\(A\)等级大于车站\(B\),则\(A >= B + 1\),不 ...

  10. MySQL锁粒度是什么意思?MySQL锁粒度是什么?

    MySQL锁粒度就是我们通常所说的锁级别.数据库引擎具有多粒度锁定,允许一个事务锁定不同类型的资源. MySQL数据库有三种锁的级别,分别是:页级锁.表级锁 .行级锁. 锁粒度 锁粒度就是我们通常所说 ...