00:00
同学们,我们来看一下,为什么就是说咱们这一个就是这样一个案例,他会输出这样一个结果,什么结果就是同学们刚才啊,我们这是在上次视频里面讲解的这个结果,我们来看一下,把原因给他分析出来好吧。那首先呢,我们再看一下这个结果,具体来具具体对照这个结果,待会我们分析好,先把这个结果放这,然后呢,我把这个代码按照我们以前的规则把它放到这边来,好吧,也就是说我们要对照这个代码呢,画出它的内存图来进行分析,好这个还不行。这边我们仍然要进行一个乱码的转换。用edge plus打开,把乱码的处理一下。好,同学们,我们现在就是粘贴。同样这个下面的底给它换成另外一个颜色。
01:02
各位同学,现在呢?我们开始来分析一把。好的。首先呢,仍然是。同学看,首先仍然是我们的一块内存。拿下来。好,这是我们的一块内存。那现在呢,我们来分析一下这个代码它会怎么执行哈,首先。首先我们代码从这里开始执行的,在这里呢,我们定义了。定义了一个哈。我们这是定义了两个,定义了一个,我们定义了一个共用体变量A,就是这个data a这个共用体,那么这个共用体它一旦创建好了过后,在我们内存里面它是。它是怎么存在的呢?好,我们来给他看一下,它是这样子的A。
02:00
A名,名称。指向一个空间。指向一个空间,这个空间呢,它是怎么放的,关键是在这里要理解一下,看这里哈,这是一块内存。那这个内存里面到底有多大呢?我们刚才已经讲过了,对于这个A来讲,它它其实它一共有几个字节呢,取决于。他的这个成员里面,哪一个成员是他占用的。空间最大显然最大,所以说所以说它这里面有四个字节。好,我用这个表示,为了好看呢,我们一个块,就是同学们现在看到的这一个块,就代表一个字节。好,那为为了待会老师讲课比较方便,我把它拉成这样一个形式,好吧,就是我就不竖着放了,我怎么样了,我横着放。我横着放,这样待会利于我讲课,其实我也可以竖着放,但是呢,我横着放,这样利于我去跟大家把这个讲清楚。
03:07
好。对面看清楚了哈,也就是说现在呢,这个一共有四个。一共有四个字节,有四个字节。一个块代表一个字节,能理解哈。好,这个事情就做完了。做完以后这边当然一输出就输出一个四,也很好理解。那么当我们执行a.N的时候,a.N的时候负了一个16进制0X4,零,它会怎么存放呢?各位同学,首先我问大家一个问题。这个0X是零。0X40,它是16进制的。那么我们以前讲过,16进制是四个就一位。如果转成二进制的话,我问大家四零转成二进制应该是等于多少?
04:02
如果把它转成一个二进制,是不是它占一个字节?他占一个字节,那就应该是。第一个领。就是四个零,能理解吧,1234,而我们的这个四。而我们这个是应该怎么存放,同学们是不是?是不是就应该是。零。100是这样子的吧。就说我们这第一个零代表是这个。这个是是用这个,那也就是说在我们这个内,在这个低位,因为我们我们这个字节数呢,肯定是从低位开始存放的。这边是低位。这个是低位,这个往这边走是高位,对不对,所以它存放的,存放过后呢,其实存放的就是这个值。就是在我们的第一个字节里面存的就是这个字。
05:01
好,我把这个呢放进去。这个大家能否理解?因为我们在原先在讲二进制的时候,其实这个已经是说过的了,对不对。是这样子的,就是说在我们第一个职业里面,那前面这些呢,我们可以认为全部都是零,可以认为全部都是零,对,也就是说这个时候我们可以认为这都是零。1234好,这个往这边放,因为它是一个正数嘛,现在你存的这个0X上面没有,没有表示正负的时候,它是一个正数,好那就零,那这样好,12341234。好,这边还是不够,往这边挪一点点。这边也是八个01234 1234没问题吧。好的,那我问大家,问大家此时此刻,此时此刻,当我们去打印这个in特N的时候,也就是说输出输出这个a.X的时候,显然它就按照这四个字节来看,为什么四个字节,因为你T这四个节,所以说在打印N的时候呢,它就这样看。
06:08
你这个应该输出多少,显然这个你你想一想同学们,这个二进制对应下来是不是就是64啊,为什么是64呢?因为你看这个一嘛,其实是一乘以二的多少次方啊。是不是以前讲过呀,是这个一所在的位数,所在的这个位数减一,它现在是在第几位,是在第几。是在第七位,那就是七减一的六就一乘以二的六次方,那二的六次方二就是六个二相乘。是不是乘以二再乘以二,再乘以二,哎,这个就等于64嘛,能理解不60,所以说这边第一个输出就是64,就这么来的。那紧接着他又输出这个C,输出这个这个char char呢,它是按照这个C字符来输出的,那就那就要看这个64对应的这个阿斯克玛的那个字符是多少,我们打开。
07:07
我们打开这个阿斯克玛来看一下。阿斯克玛我们在前面实际上是使用过的,我们打开这个阿斯克玛找一下64对应的这个字符是多少,它就应该输出多少找一下。64。OK。同学们可以看到,如果是64的话呢,就应该是一个艾特符号。那么看看是不是输出的符号呢?果然是爱的符号。所以说,这时他在。它在这个地方呢,就会输出一个艾的符号,明白了吧,然后它又按照这个short来输出short是不是占两个字节呀,两个字节就看前两位,那前两位还是64,所以说这个就输出64了,明明白了吧。好,紧接着呢,看下面这句话,a.CH等于九。
08:05
呃呃,出出一个九这样的嗯字符,那么九它对应的这个十进制是多少呢?就是字符九对应的十进制是多少呢?我们来看一下九对应的这一个是57。大家看到这是九,这个字符对应的十进制是57,它的二进制是00111001,看清楚没有,所以说它就应该是存的这么一个值。他会把原先的给给覆盖掉,变成00111001。好,那么这个时候,当这句话执行完毕过后,就是。001看一下。零零。00111001。
09:03
00111001,也就是说此时此刻我们这个第第一位的第一个字节,因为你现在一个差是占一个字节,所以它动的呢,它在进行修改的时候,他也只会去修改它第一位的第一个字,为什么不修改第二个字节呢?因为你这个CH就占一个字节。所以说他就只动第一个字节,那这个字节就变成了同学们刚才看到的这个玩意儿。好,我把这个呢复制过来。好,此时此刻,此此刻它往下面打印,这个时候打印的这个A点点仍然看这四个字节,这四个字节就看这个二进制对应一个多大的十进制呢?显然是57。对,那这个时候这字符就看这个二进制对应的时,对应的那个字符是多少,显然是我们的九。这个字符,然后呢,Short short,看这两个字节对不对,它还是57,所以说这边输出的就应该是多少呢,应该是五十七九五十七正确注意这个九号,同学们一定要理解,这个九可不是十进制的那种九是。
10:17
这个字符的九,因为你是按照这个字符方式来输出的,好,紧接着我们再继续往下看。紧接着呢,它又执行了一个a.M等于0X2,零。2059,那我问同学们一个问题,这个2059翻译成二进制是多少呢?翻译成二进制是不是,因为它是16进制嘛,所以说它应该对应两个字节。第二对应两个字节,那么翻一下九,这个九对应的二进制应该是多少呀?九对应的二进制是不是这样写的?我们这次偷一个懒哈,这次偷一偷一个懒,我们直接呃从这边拿过来用,我们自己推导也可以,那就这样推吧,第一个一。
11:06
第第二第一个是二,那就是0000。0010。哎,不对不对啊,不对,第一个二就应该是零。0010,这个对应200000好。因为一位对应四,四个bit,四个位好五五对应一个四位的二进制应该是多少呢?是0101没没问题吧,01019呢。九应该对应多少呢?九我们看一下这边是四好,四这边就应该是一个。八那就是1000。这个诶同学们1001是不是对应一个。对对应个九啊,因为这个是二的。
12:03
呃,我看这个这个是二的二次方,这个是二的三次方,对,那就应该对应这个,那也就是说0X2059,它对应到这个二进制呢,它应该占用前面的两个字节。为什么是两个字节,因为你0X2059,它这个按照16进制来看,它就占用16个位,16个位就是两个字节,所以说这样子呢,我们就可以找到它的值了,好把这个换一下。来,那现在呢,我们把这个拿过来哈。来这第一个字节存放的就是这个数。第二个字节存放的就这个数。现在大家明白什么意思了吧?讲讲到这儿,我相信同学们应该有点感觉了,哦,原来是这么回事,明白了哈,那这个时候再去往下输。好,当他输出a.N的时候呢,他还是看这个四个字一,那就看这个二进制,就是同学们看到的这一个二进制。
13:01
这个二进制它对应的,它对应的这一个十进制是多少。这个是多少呢?这个是多少好,所以说如果你要看这个二进制对应十进制,我们可以打开我们这个计算器,我们来梳理一下。来看。好,我先输个二进制啊,那就是一个个输吧,一个输一个一个的输,我们就输前面这几位就可以了。呃,从一开始输。幺啊零零,它是不会给你动的,所以说直接输1000。零零是不是这个前面这这几位,因为这个零呢,它本身没有实际的值嘛,所以说你这其实输前面六位就可以了,后面再来零。101。还有1001,我们看这个值翻译成。翻译成我们的这一个十十进制到底是多少呢?我这一点就出来了。
14:03
是不是8281啊,也就是说这个时候他在输出呃,这一个N这个成员变量时候,它应该是八二。821看看。828281。8281就出来了,同样那这个C呢,C其实它只看一个字节,就看这边,就看这个二进制,它对应的这个阿斯克玛是多少。那这个对应的二进制,我们再来重新算一下来,那就是看这七位就是101。11011001,好,我们,诶这个不好意思,这个写错了,要先按二进制来放,1011001翻译成十进制89对,那就看89对应的这个阿斯克玛是多少,那阿斯克玛的字符89应该是在这个位置。
15:03
89在这儿。那也就是说这个时候他应该输出一个大写的Y。大写的Y,也就是说这边应该输一个大写的Y。那么紧接着他又输出a.ma点,要看这两个字节,这两个字节刚才我们不是算出来是8281吗?说它仍然输出八二。818281,我们看一下第三排输出的对对内容跟我们是不是一样,看一下。同学们可以看到此时此刻哈。8281。8281大写的Y大写的Y8281881可以了,好,到此为止,我就讲了,我就下面这个我就不去举例了,这个一样的自己去推好,这个呢也是16进制。按照刚才老师的那个方案去推就行了。按照这个方案对,那你其实可以看到下面这个值,我可以简单给你看一下,为什么是1042,这个其实就是这个16进制对应的这个16进制对应的十进制是多少,那其实你可以马上看到。
16:05
好,比如说我把这个三踢到这儿来。你看一转成十进制,其实就是这个值,就是同学们这看到的1042这个值。其他我就不一个举了哈,其他我就不一个举了,同学们自己去看,那通过这个案例。通过这个案例呢,我相信同学们对我们这一个共用体,它的一个什么呀。内存的布局就应该有一个深刻的理解,那最后呢,我们再来看一个内存布局的一个示意图,我这边还有一段文本,看一下就可以了。实际跟老师刚才讲的是一样的。比如说我们刚才讲的,以上面那个data为例,各个成员在内存分的分布,你看这个是低位。CH呢,它就占其实就占其中的第一个字节,M呢,可以看到M就占两个字节。
17:02
而我们这个T呢,看到没有,Int这个N占四个字节。看到没有?其实跟我老师分析一样,跟我分析,只是我我在讲的时候,为了大家好好看呢,我是横着。我是横着放的,这边这个给的示意图呢,是竖着放的,但是竖着放大家知道低位,这是上面这个是低位哈。上下面这个是高位。也就是由低到高这样去看就行了。最后我们整理一下成员NCH和M在内存中对齐到一头,对CH赋值修改的是前一个字节,对M修改的是前面的两个字节。为什么是两个字节?因为M是short带两个字节,对N赋值修改是全部字。明白吧,也就是说,Chm会影响到N的部分数据,而N呢,会影响到CH和N的全部数据,完事了。
18:00
就是这么一个示意图,好了,同学们,我相信讲到这儿大家应该是理解了。如果还没有理解呢,就把老师画的这个内存图再仔细的看一遍,各位我们梳理一下我们讲的内容,好的,那关于共用体的内存布局和前面案例我们就说完,我们举我们来把这个前面讲的内容梳理一把。来,走起来。那我们共用题我们讲了哪些呢?我们来看一看。共同题我们是这样讲的,首先先给同学们提出了一个需求,是这样子说的吧,先提了一个需求,就是说我们有这么一个情况,有学生和老师。有学生和老师他们的,他们的信息已经很相同了,对前面的三四个成员都一样。四个成员都愿,但是呢,有一个不一样。造成我们对这个数据的设计有一些有有一些这个麻烦,所以说我们就提出了一个什么呢,共用体的概念。
19:07
把这个拿过来。放到这里好,同学们认真听,放这里过后呢,我们怎么分析,我们说诶如果用传统方法解决会有什么问题。传统方法呢,确实是能够解决的,不是说不能解决,但传统方法呢,它带来的问题是这样子的。对不对,所以说解决方案我们是在这提出了,但他的问题呢,就是会造成我们数据的一个浪费,对吧,就是数据浪费,这边说的传统问题会造成空间浪费,如果我们呃用两个结构体来做呢,又不利于我们的管理,所不管怎么样都觉得有点不太方便,所以说我们就说使用共用体,那既然说到使用共用体,我首先呢,给各位同学就说了一下共用体它是一个什么东西,做了一个基本的介绍来拿过来。这是共用体的基本介绍,放这儿好。
20:02
共用体基本介绍,那这边呢,是它的一个基本语法。这个要看清楚,对。这是共用体基本介绍,共用共用体的基本介绍,我们这儿还是标一个符号吧,好,这边。这是一个对吧。这个呢,是我们的又一个。好,这是有一个。三点,把这个共用体基本介绍说完以后,我们就给他来了一个快速入门。就是体用,呃,体会了一下这个共用体是怎么使用的,来把它画过来。把这个快速入门案例我们搬过来,好吧。OK,那快速入门案例呢,它的这个代码在哪里呢?代码在这里。代码呢,就是刚才老师在这儿写的。我把代码给大家放过来。针对针对这个代代码呢,我们画出了它对应的内存图,对上面代码,上面代代码说明代代码的内存。
21:07
布局图。这个代码的内存布局应该说是非常重要的,所以说呢,我们把这个给他拿过来,就是先针对这个案例把它布局说了一下。好的。我把它放在这里哈。放在这里。把这个布局说完了过后呢,我们又给大家看了一个幻灯片,就是在。专门提出共用体的一个。一个说明。共用体布局的一个说明,那我把这块拿过来就行了,好吧,就这一块,诶刚才我们不是这有一个图吗?我就从这截取一个。好,就以这个为例来讲解,那讲解呢,这个地方有一个结论,它是比较重要的,就这块结论。对,这块结论比较重要哈,给。我放在这里。好,各位同学,那关于这一个共用体,它的内存布局,还有这个案例呢,我们就给大家分析到这里,大家好好的体会一下。
我来说两句