00:00
来,我们继续刚才我们讲的这个数组的使用呢,都是面上的东西,没有深入到内存对不对?现在呢,我们来看一下数组的定义和数组内存布局。就说我们数组在内存里面到底长什么样子,它是怎么分布的,这点对我们要把数组彻底的掌握非常的。非常的重要,我们来看一下数组定义呢,刚才同学们也看了一下,它是这样子的,VR是一个关键字数组名,然后呢,这边有数组的,数组的大小和数据类型。比如说刚才我们用的VRAAA就是一个数组的名称。五代表我这个数组最多存放五个数据。Lit代表这个数组能够存放的数据类型是什么?注意听好,那么复出值就是A0就代表给第一个元素复出值,A1就代表给第二个元素复出值,这个前面已经讲过了,我就不再多说,我这里重点就是想给大家画一下数组在内存里面的布局这个图好,数组定义这块呢,我们把它整理一下放到这里来,这是数组定义和布局。
01:12
好,整理一下。来,走一个。这是我们的第。二个是吧,这是我们第二个标题。处理一下第二个标题数组的定义,我们给它来一个这样的东西。对不对,付出指针,那么现在呢,我们要讲的是数组在内存的布局。这个比较重要。诶,这个比较重要,我把它标成一个红色的。那我呢,给大家画一下这个图。我给大家画一下这个图。好,我们写一段代码,我们写一段代码,通过这个代码呢,来给大家画图,那我们新建一个。文件夹叫阿瑞。2DEMO0几呢?零二。
02:03
零二好,我们新建一个文件main点。Go。Package。Me,然后呢,我们来import一下。Format对不对?Format,然后我们我们写个主函数me。好,我们再看看内存布局,我们写一个这样的例子,同学们注意看啊,为了容易画出来呢,我定义这么一个数组。就是in int吧,存放int的,这样好好看,然后呢,这个数组大小呢,我们定稍微小一点,因为这个定太大了,我待会画图呢比较比较麻烦,我就定小一点,定一个可以存放三个数据的这么一个数组映。好,洗完了。OK,然后呢,我在里面给他复习初始值。其实我可以先这样子啊,同学们,其实这个数组定完了过后,它本身也有默认的值,能理解吗?也就是说这个地方你不用付出值,其实已经有默认值了,说一下这个地方就是当我们定义完定义完数字这个数组后。
03:11
数组后,其实其实注意听,其实数组的各个元素,各个元素已经有默认值了。元素有默认值。默认值这个后面讲细节,我还会说默认值是什么值呢?就是零。OK,我们可以打打印给他看一下。Inch,好,我们可以打印出来看一下,来跑一个吧。我们就说先不要给它复出值,先看,先让大家看到定义过后会是什么样子好不好,然后呢,我们上一集CD到ADEMO02,然后go run main点勾跑起来,我们可以看到这里面有三个元素,它们都是零。000看到没有。0003个元素,那么究竟这个东西在内存里面怎么布局的呢?来,朋友们请注意我把这一段代码。
04:06
注意听啊,这块很重要。我把这一段代码放在我们Excel表里边去。放在Excel表里面去。OK,然后呢,我这里来画一个图。比如说这个是我们的内存图。这是我们的内存。注意听内存好了,那么当我们的代码执行完这句话过后。执行完这句话过后,在我们内存里面会出现一个什么东西呢?只有把这个理解了,同学们就彻底明白,OK,他是这样子的,听我说。当你执行当当我们的这个编译器执行,呃,当我们这个程序执行完VAR过后。在这个情况下,在内存里面会出现这么一个东西,听我说。有个叫int的变量,Int变量。
05:05
好,我把它放这来,然后这个变量呢,因为它是直类型,注意听它是直类型,所以说它在这个地方。会有一个数组。好。OK,那我为了好看,我干脆把它换成深一点的颜色好吧?换成深一点颜色,这样因为它是白色,字体好看。好,那么这个里面,因为它的数据是存放三个数据,所以说这个空间是有几个呢。好,这个这个画的太大了,稍稍微把它说一下。也就是说在我把这个再缩小一点,可能看起来就轻松了,诶这样看看起来很舒服的啊,很舒服看就说这一块空间就给你分配好了,而这个空间里边呢,每一个元素也有了,默认就是零。默认就是零。
06:00
好,这个地方我把它缩回来一点。One就是你。然后我们的这一个。Int int呢就指向了这个位置,因为它是直类型,就直接指过去了。他们就。关联上了。锻炼上了,那么问题来了,说老师,那你能不能让我我们看一下in特瑞它的地址是什么?可以,我可以告诉大家它的地址,这个宿主名,注意听宿主名,宿主的这个名字,他的地址就是这个宿主的首地址。那我们来看看,我们来往深的研究一下,注意看这句话。Print f,我们打印出数组的地址的地址来,我们输出来。B。我们。要他输出。取一下他的地址。
07:00
取消他的地址,我们看一下是什么东西。执行一把。我们可以看到他的地址是这个。看到没有,是不是这个地址。好,也就是说,也就是说这个家伙。T,其实它。它指向哪里了呢?它指向这个地址,那问题在说这个地址到底是谁呢?告诉大家,这个地址就是我们这个宿主的首地址。就是就在这个地方,这个数组的首地址就这,而且还有一点,数组的首地址其实就是第一个元素的地址。待会我在做做整理,我把这句话整理到这里,待会说啊,第一个,刚才我们得到一个就是宿主的宿主名,宿组名。的这个地址。这样就说就说宿主的地址吧,宿主的地址就是什么呢?就是。哎,这样说宿组的地址就是可以通过,可以通过数组名,数组名来获取。
08:07
来获取。怎么获取的呀,就是at。对不对,然后呢,是int就可以了,你看刚才我们就这样获取的,这是第一个,第二点呢,我们还有个结论就是。数组的第一个元素。它的第一个元素,第一个元素的地址。就是宿主的首地址。守弟子。那有些同学,有些同学老师你给我证明一下没问题,我给你们证明一下,大家再来看,我们还用它来玩一把,看到我们说一下第一个数组的地址是不是。林娜,他的弟子。他的地址我们也把它输出来。我们看一下它的地址是多少呢。来,走一个INT0。那么如如果你要取地址的话,你得加个艾特符,如果你不加艾特符,就直接把它值取出来了,知道吧,我们看第一个地址的就是。
09:07
第一个元素的地址。第一,第一个元素的地址是不是跟数组的首地址是一样的呢?我们看一下。保存一把。看效果。我们可以看到。两个是完全相同的。来看这里。这是数组的地址。这个是第一个元素的地址,大家有没有发现他们是同一个?其实这个也可以理解,这个也可以理解,就是我们有一个有一有一有一有些小朋友在排队,小排队那第一个排排在第一个的同学,排在第一个同学,他既是这个队,他既是第一个同学的弟子,同时也是整个队列里面的首弟子,能理解吧。诶,他就是这样规定的,你看完全是这样子的。完全是这样,那么我们再来走一个,同学们思考,我们打出第二个元素的地址呢?同学们思考。
10:01
如果第二个元素的地址。我换一行好不好,第二个元素地址我们也输出来。大家猜一下是多少?你们能猜出来吗?你们能不能猜出来,其实不用猜了,其实你们不用猜第第二个元素的地址,其实就是第一个元素的地址基础上加上。这个元素占用的字节数再说一遍,第二个元素的地址就是第一个元素的地址加上这一个数组类型的。这个这个数组这个类型占用的字节数,比如说int是占八个字节。印的是不是按八个字减,那么如果说我我不用打我就能吹出来,这个是多少呢?如果根据这个情况来说。下一个元素就应该是。0XC04204A0AJ8。就A后面是个八,你信不信?为什么这么敢敢这么肯定呢?因为。
11:02
它是按照这个连续分布的,而一个元素是一个int,而一个int占八个字节。Int占八个字节。是不是占八个字己,因此我们可以推出来这个元素一定是前面这个元素加一个八就行了,那我们看看跟老师分析的对不对。完全没问题。看效果,同学们看老师完全没有忽悠大家。你看这。是不是A0,这个是A8,是不是记住加了一个八一,后面以此类推。以此类推,如果说你们再要找下一个例子,在这个基础上,在这个基础上再加一个八,我们再看一下是不是老师这样分析的对不对。看效果。这是第三个元素,第三个元素地址,我们也把它输出来。好,数出来,写个几,写个二。好写完,但是这个地方这个逗号我给错了,给成刚才改成中文的了,看效果啊,它们是连在一起的。
12:03
大家看同学们看到是不是这样子的,同学们注意观察,你这个地方是零,我加一个八,在A8的基础上再加一个八,是B0的,因为它是16进制的,就再加一个八,再加一个八,八加八等于16 16的话,16进制就进位,然后这个A变B。这个8B0是B0。所以通过这个地方,我们还可以看到一个非常重要的特点,就是数组元素的地址,其实它是连续的。对不对,这也是构语言里面的一个特点,因此有些高手就是我记得我们在我记得以前我做开发的时候啊。那个我们的领导是cec这个新浪第一任CEO啊,CTO技术很牛,他当时给我讲了一个方法,说咱们想想快速的定位一个呃,一个值,其实最快的方法就是在地址上加,比如说我在这个地上加一个八,就马上取得下一个下一个元素的地址,然后取值速度是最快的。
13:00
当时给我讲完了过后,我就觉得真的是很厉害啊,就是说有些时候你用地址来,用地址的方式来取值,速度是最快最快的,你看,但是你要找到它的规律。对吧,那我再问大家一个问题,如果说我把这个改成三二。我把这个改成三二,请同学思考,那么他们之间的地址是不是还是连续的?而且他们弟子之间每个相差几呢?相差四,因为三二是四个字,四个字节是不是这样子的,看一下。我们彻底把它搞懂。我们可以看到,我们可以看到,看这首地址仍然是8080,但是你看再下一个地址是不是加了个四啊。再加一个488,为什么?因为你的每一个元素的占用的你你INT64每一个元素,呃呃三二啊,每一个元素占的是几个字节,四个字节。所以说他每个就加一个四,理解了吗。啊,理解这个东西啊,同学们一定要注意好了,那我还把它撤回去好不好,还把它撤回去好,同学们那通过这个地方呢,我们这个内存图也就完全画画完了,大家看这地方我们就可以推出来它的地址是多少。
14:11
我为了好看啊,我在下面画,因为我都在上面都粘在一起了,推出来这个是几,这个是八。是不是第二个元素地址是八,第三个元素是几?第三个元素大家还记不记得?第三个元素就是在这个基基础上加一个八,变成B0。变成B0。完事。你看那每个地的地址都有对应关系,也就是他。它是指向第一个元素的。诶,这个怎么看不到线呢。好,这个地方我就不画了啊,这个这个地址就是我们第二个元素的地址,这个地址。这个地址就是我们第三个元素地子,而数组的首地址其实就是第一个元素的什么呀地子能理解吗?
15:01
能理解,所以说这就是为什么我在这输出的时候,大家有没有看到。大家有没有看到我在这输出一个。我我把这个数组的名字往这一填,他为什么能够把他为什么能够把这个元,这个数组的所有元素都取出来呢?就是因为他找到这个首地址过后,然后每次加八个就把所有数据取出来了。加八个字节就把所有的数据就取出来了,能能理解吧,因为他是首地址,它就按照一串全部给你取出来了,好,这个就是我们这一个。数组内存图的分布就是对应刚才老师画的这个图,看懂了吗?啊,那当然我们也可以改变它,比如说。比如说现在呢,我把这个值稍微的改变一下,我赋值了in。零。零,好,我给他一个十。第二一个元素我给他一个20,第三个元素我给他一个30,那同学们想一想,此时此刻我们再去一执行的话,同学们看到。
16:06
是不是这些地方还是没有变化,但是只发生变化,诶为什么没变,呃,是因为我没有在什么呀,没有在后面输出对吧。这样输出一下就可以看到了,看效果。前面是000,后面是十二十三十,那也就是说通过这个元素的访问呢,我们也可以改变各个元素里面具体放的值,那也就是说我们就可以把它改成。十。对吧。可以把它改成十,可以把它改成20,可以把后面这个改成30,是不是这个道理?好,同学们,那么我们就把这个图画完了,内存图就全部画完了,大家看看看能不能理解这个图,一定要深深深刻的理解啊,如果你理解这个图了,我跟大家讲后面学习的东西相对很轻松,因为首先从这图透露很多信息,第一个我们可以看到很明确的看到数组它是什么类型,它是直类型。
17:06
因为如果是引用类型的话,他这个不会直接指向这个数据空间,而是指向一个地址,但是你看老师画的图是让这个名字直接指向数据空间的,说明它是什么样子类型,第二个我们可以看到它的内存里面每个元素。它的地址是连续分布的,而且这个每隔多少取决于数组的类型。对不对。而且怎怎么去访问各个元素,这也体现出来了,好,这几句话我把它整理一下。这个很重要啊,同学们,我把这个内存图给同学们放到笔记里面去。放到笔里面去,OK。来,走一个。对吧。做一个,然后我把它放到笔记这块,然后针对这个图呢,我们有几句话要说。来,走一个。
18:00
对。对上图的一个总结,总结的这几句话其实在这儿我已经写好了,但是呢,我还把它拿过来。对吧,我要把它拉过来。诶,这块。没切好,重新来想。一。第一点。第二点。诶,这个算第二个,还有我们可以看到数组元素的地址间隔多少,取决于数组的类型。数组的每个元素,各个元素。的地址。地址大小啊,大小是大小,间隔啊间隔。间隔。是。根据什么呢?依据。依据。数组的类型来决定的类型决定。比如比如你是INT3,你是这个int类型的,Int类型其实就是INT64嘛,对吧,因为在我这个系统系统里面,我是操作系统是64位的,所以它是比如说64位,它间隔就是八个字节。
19:14
对不对,如果你是INT32,它的间隔就是什么呢?就是四个字节,以此类推。以此类推,好同学们,那关于我们说的数组的定义和内存布局呢,老师就给大家讲到这里,大家要深刻的理解和掌握。OK,我看这个代码要不要拿过来这个呢,一样把这个源代码再再再给大家拿过来好吧。也放到这,大家要知道怎么去打印地址呢?这块有个细节,多说一句,要用百分P这样取,好吧,就百分号P代表是取出它的地址pointer嘛。Pointer OK。好的。好,那同学们关于这块内存布局,我们就介绍到这里。
我来说两句