• 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. nginx虚拟机及热部署(在线升级)

    实现热部署(在线升级): 热部署方案一 (有弊端,不利于回滚) 查看nginx版本及源编译差数: /usr/local/nginx/sbin/nginx -V 预编译/ 编译/ 安装:在预编译之前,先 ...

  2. 欧拉序求LCA

    使用欧拉序 st 表 O(1) 求 LCA 欧拉序 st 表求 LCA 一开始是从某篇题解里看到的,后来百度了一下就会了( 这是一种预处理 O(nlogn) ,查询 O(1) 的优秀算法. 什么是欧拉 ...

  3. [vue]精宏技术部试用期学习笔记 III

    精宏技术部试用期学习笔记(vue) 父子通信 什么是通信 / 为什么要通信 通信即在不同组件之间传输数据 当在 复用组件 时,需要传递不同数据达成不同的表现效果 能够根据其他组件的行动,响应式 的做出 ...

  4. Go语言基准测试(benchmark)三部曲之三:提高篇

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 -<Go语言基准测试(benchmar ...

  5. SMC

    记一次入门反调试技术 找到关键函数,先分析F5伪代码,发现了virtualprotect函数,联想到了SMC代码保护技术 但是到了后面分析发现分析不下去了,然后找了wp发现是代码反调试技术 然后细细看 ...

  6. 机器人的运动范围(dfs)(leetcode 4.8 每日打卡)

    地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] .一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左.右.上.下移动一格(不能移动到方格外),也不能进入行坐标和列 ...

  7. JavaSE面试题01:自增变量

    JavaSE面试题:自增变量 来源:https://runwsh.com/ 代码 public static void main(String[] args) { int i=1; i=i++; in ...

  8. AtCoder Beginner Contest 329 (ABC329)

    A. Spread 不说了,代码. B. Next 不说了,代码. C. Count xxx Description 给定一个长度为 \(N\) 的字符串 \(S\),求 \(S\) 中非空连续,并且 ...

  9. WPF 纯XAML实现NumericUpDown 控件

    本文由 飞羽流星(Flithor/毛茸茸松鼠先生/Squirrel.Downy)原创,欢迎分享转载,但禁止以原创二次发布原文地址:https://www.cnblogs.com/Flithor/arc ...

  10. 【漏洞分析】Reflection Token 反射型代币攻击事件通用分析思路

    在本篇文章中,我将通过一个攻击事件引出 Reflection Token 攻击事件的一个通用分析思路. 关于 Reflection Token 的其他案例分析,可以参考BEVO代币攻击事件分析及复现一 ...