00:00
各位,我们接着来看下一个内容,叫共用题。共用体我们还是老规矩,我们先看一个需求,引出我们要讲解的共用体。说现在呢,有这么一张关于学生信息和教师信息的表格,就下面这个表格。对。学生的信息呢,包含姓名、编号,性别、职业,还有分数。教师的信息呢,包含姓名。编号、性别、职业和教学科目,大家有没有发现?这学生和老师他唯一不一样的就是后边这个这个呃,成员不一样。对吧,也就是说学生和老师呢,都有编号性别职业,但是学生呢,第五一个。成员是分数,而老师的第五个成员呢,是教学科目,所以说这个表格呢,就变成这样子了,比如说我们有一个人叫孙二娘,他的编号501,她是一个女的。
01:06
呃,女的,我们用F表示学生,用S表示,他的职业是一个S是个学生,那么后面就存的是分数,再比如说有个叫有一个叫这个顾大嫂的这个人,那么他是老师,用T表示,他呢,后面这个成员呢,就是。他能够教授的科目,英语。现在的问题摆在我们面前,请大家去思考,我们设计一个怎样的数据结构来保存学生,还有老师呢?他你你发现他们前面这些都是相同的。就这一节。都是相同的。而后面呢,有一个不相同。对不对,所以说我们来看一下解决方案。如果我们用传统的方案来解决,如果我们用传统的方案来解决,那么我们可以这样定义结构体,根据人员的职业不同,使用对应的成员变量,比如说我们前面这个都一样。
02:09
前面四个都一样,名字,编号,性别,还有他的职业,然后呢,这定义一个score。定义就是说如果学生呢,我们就用这一个成员成绩,如果是老师呢,我们就用这一个。呃,那个这个。Course。这个courses呢,就是代表他能够教授的课程。这样子设计其实是可以的,对不对,至少能够完成前面的需求。但是这种方案呢,有一个问题,就是他会造成空间的浪费,比如说如果是学生,他只会使用到score这个成员。但是呢,他也会占用。Cos成员的20个字节。说是反过来也一样啊,如果你是老师,你会用这个字符数组,但是你不会用到score这一个。
03:05
这一个float变量对不对,所以说它会造成空间的浪费。那你怎么解决呢?那你这个传统方案又不好,所以说你只能这样解决了,那么你就分开写。Student和teacher分成这两个。但是这样又带来一个新的问题,什么呢?如果我们的职业比较多,就会对应多个数据。结构体的类型,不利于管理。是不是这样子的同学们?那这样子的话,我们就引出了共用体这个概念,共用题可以比较完美的解决这个问题。共用题可以完美的解决问题,那么怎么来解决呢?我们来看一个基本介绍,什么是共用体?所谓公用体呢,它的概念是这样子的。叫union,属于构造类型。大家回忆一下,我们在讲。数据类型的时候,是不是讲过结构体还有共用体都是属于构造类型?
04:05
对于共用体而言呢?它可以包含多个类型不同的成员。和结构体非常类似,但是也有不同的地方。什么地方不同呢?待会儿我们在举案例的时候还会具体说哈。共用体,它还有另外几个叫法,叫联合,或者叫联合体,所以说如果别人问你会不会使用联合体,其实指的就是共用体。对于共用体来说,它的定义的一个方式,定义的格式其实很像结构体,你看前面是union这个关键字变化了,后面跟的是共用体的名称,然后是成员列表。那。到底共用体跟结构体有什么区别呢?下面我们用一句话来描述它的区别。结构体和共用体体的区别在于结构体的各个成员会占用不同的内存。互相之间不会有影响。
05:00
而共用体所有的成员注意听共用体所有的成成员占用同样一段内存,修改一个成员会影响其他所有成员。当然了,我知道我们这样用一个语言来描述,同学们是很难理解的。就是我我说完这个这句话呢,其实你也不知道老师在说什么。那只能通过什么呀,只能通过一个案例来。更详细的、更透彻的理解这句话。那同学们,我们来看。同学们,我们先来看一个快速入门,好吧,现在呢,大家看这有一段代码。定义共用体和共用体变量的三种方式,我们先看一下好吧。Union data。然后这面有。一个成员,第二个成员,第三个成员。我们第一种方式就是先定义共用体变量啊,共用体数据这个数据结构啊,数据类型,然后呢,在。
06:03
定义。共用体的变量变量是吧,就是union ABC,其实我就定义了ABC3个共用体变量,这是一种方式,还有一种方式呢,就是我们在定义。共用体这种数据类型的时候,同时就定义它对应的三个变量,这也是可以,这是第二种形式。前面是第一种形式。第三种形式呢,跟我们结构体也是一样,假如我们定义一个,我们有一个共用体。这样的数据类型,但是呢,我们只希望使用一次,里面有三,我也就说这个共用题,这种数据类型呢,我们只希望有三个变量,我们就可以直接这样写ABC就完了,但是呢,这个地方没有给共用体名称,这个其实就叫匿名共用体,跟我们前面学的匿名的结构体其实很相似。那这个我就不去举例了,因为特别简单,一看就明白了,下面呢,我们看一个案例,看一个使用公用型的案例,来看看他到底有什么区别哈,案例很简单,我们来跑一个。
07:13
来,同学们往下拉,现在这是我们的第一个共用体的案例,我取个名字叫UN。写到这里来。Union demo01。往这一放,然后呢,我们在这边哈,我们在这边呢,把这个后缀改一下。Okay。Include std IO。然后VO的主函数。贸易的主函数。在这里面呢,我们写上这么一,诶这个就不要主函数我们都不要了,好,我们来做一个解释,同学们看,这是data。Battle。带着就是。就是什么呢?就是一个共用体数据类型了。
08:05
它就是一个共用体,里面呢,包含了三个。成员包含三个成员。三个成员哪三个呢?就是这三个。下面呢,看这句话,这里就相当于说我定义了一个什么呢,共用体,共。共用体变量。哪一个呢,就是A,就是共用体变量,这个是个A,然后大家可以我们先把这个给大家注销,大家先看一下。我在这里输出了A这个共用体的占用的空间,而且呢,我也直接像这种方式来看我们这个共用体这种数据类型,它占用空间你们知道是多少吗?大家看啊。我们知道T呢,占四个字节。Char呢有一个字节,Short有两个字节。
09:01
对吧,如果说他们加起来其实应该等于七。至少是七,但是实际上你会发现非常奇怪,这两个输出的结果都是四。为什么是四呢?这说明他们并不是像我们想象的三个成员都都分别占用不同的空间,其实他们是共用的。也就是说。这三个成员,他们共用共用一共用数据空间。数据空间。数据空间,那么这个数据空间以什么呢?以最大的那一个,以最大的那一个数据类型占用的字节数为准,该空间的大小。该空间的大小以什么呢?以最呃占用,占用最大的。
10:00
成员。成员变量成员为准。为准,那也就是说我们这里面哪个占用的最大呀?是不是int占用的最大,Int占四个字节,而差只能占一个字节,Short占两个字节,那也就是说当你去统计的时候,你会发现它返回的是四。返回的事是不是四呢,我们运行一下。我们发现呢,的确它会输出两个四哈,就是不管你这个是一个具体的变量,还是这个数据类型,其实它都是四。我们运行看这的结果,你们发现是四,那我问同学们一下,假如说我把这个删掉了。假如说我把这个删掉了,同学们思考一下,它会返回几呢?现在哪一个不知道char是不是占一个字节,Short占两个字节,这个时候它就应该返回几呢?返回二,因为short现在是。占用空间最大的成员了,所以它会返回一个二,看一下是不是这样子的。是不是二啊哦,现在可能大家多少懂一点什么叫共用题了吧,简单的讲就是你下面所有的成员其实是想共共享。
11:13
或者共共享或者共有都可以共享吧,更更准确点。共享数据空间,而不是你一份我一份,好,那这样子呢,我们再来看下面这段代码,看分别输入什么。同学们看好,这边呢,我给a.N a.a这个N负了一个0X40,大家想这是不是16进制的呀。这个是16进制。16进制,那么这个地方呢,我输出我输出这个NCH和M的值,你会发现当你给N赋值了。当你给N复制了,其实下面这几个呢,也有值了,很奇怪的。我这边再给A附了一个,附了一个叉,这边又给点am,你看我这边修改了CH这边给附了一个值,再给N负了一个值,你会你会发现非常奇怪的事情发生了,大家看一下。
12:14
你会发现一个非常奇怪的事情发生了。你看。我们运行过后呢,发现这个结果长得跟我们想的是完全不一样。大家首先看第一个。第一次我们付了个0X40,这个是16进制,大家看清楚了,那也就是说,也也就说这个地方a.N呢,它的确输的就是64,为什么是64呢?因为你0X40这个16进制翻译成十进制就是64嘛。这个没问题,但是你会发现你给这个N赋值的时候,CH也有值了,但是呢,它是一个未知的符号。你你还会使惊奇的发现so头你没有负值,但是呢,它也有值了,它也是64,看到没有,后面你修改了CH。
13:00
你a.CH按理说a.CH负值不应该影响到这个N。更不也不会影响到CH,但是你会发现赋完值过后呢,你看同学们看,当你赋完值以后,你你给这个CH付了一个。九这个字符你会发现A很奇怪的事情发生了,An这个n an的这一个变量呢,或者叫成员也变化了,而M这个变量也变化了。怪吧,好,各位同学,关于为什么就是我们这一个赋值了过后其他会变化,以及我们这个共用体的内存布局,就是这里面肯定要讲一下它的内存布局嘛。它的内内存布局是什么样的呢?是关键,只要我们把它的内存布局搞清楚了,你就会非常清晰的知道,为什么你给N赋值了a.M也有值了,为什么你给CH改变了一个值A,你会发现a.N也变了,a.M也变了。
14:06
对不对?这里面就涉及到一个内存布局的问题,那么关于内存布局是怎么处理的呢?我们放在下一个视频我来讲,因为那个内容会相对的绕一点,我们干脆单独的拿一个章节来讲好不好?好各位同学那关于共用题的一个基本介绍和快速入门就先给大家讲解到这里。
我来说两句