00:01
还是按照我们以前的老规矩,我们再来看一下作用于的注意事项,以及它的细节问题。呃,首先我们来看一下作用域的这个第一点,就全局变量。那么全局变量呢?对应的英文单词叫global variable。它保存在内存的全局存储区。全局存储区,也就是说在我们内存里面呢,有一个空间叫做全局存储区,它会把全局变量放在这儿,占用的是静态的存储单元。那么它的作用域呢?作用于默认是整个程序,也就是所有的代码文件,包括源文件和头文件都可以去使用全局变量。那待会儿呢,老师给大家画一个内存布局图哈,待会儿再说。第二个局部变量,局部变量叫local variable,它保存在占里面,也就是说在我们内存里面呢,还有一个空间叫占,它保存我们局部变量函数被调用,调用的时候才动态的为变量分配存储单元,它的作用域呢,仅限于函数内部,待会儿呢,我们仍然画一个图。
01:17
C语言好,我我现在有了这两个过后呢,我给大家画一个C程序的内存布局图,这个非常重要的。这很重要,我给大家画一个图,帮助同学们理解。来看一个。写到这叫C程序。C程序的内存布局图。OK,那么这个图呢,是能够更加清晰的从一个底层的角度来说明我们不同的变量。它存储在我们内存的哪个地方啊,C程序的内存布局图写错了内存。
02:00
内内存布局图。好,那现在呢,我们开始画图了,比如说呃,首先呢,这个我们可以理解成是我们的一个计算机的内存。那么这个内存里面分成几大块呢?来同学们梳理一下哈,我们原先已经看看过了,第一大块就是我们前面学过的什么呢?占。各位,第一大块我们称之为战区。战区。站。占去。那么这一块呢?我们存放的是什么东西呢?存如刚才所说的那样局部变量。我们的局部变量呢,都会存放在这个战区。OK。我们也就说在这里面,我们存放的是局部变量。那么除了这个局部变量之外,呃,这个战区之外呢,我们还有个空间,各位同学在这里面还有个空间呢,同学们现在还没听过,我直接给大家说是哪块呢?OK,告诉大家哈,还有一块空间呢,我们称之为堆曲。
03:08
对。堆区。那么这个堆堆区呢,它将来是存放什么呢?就是存放我们使用一个函数来动,来指定分配的一个空间,后面会讲就是我们不是在后面还有一个这样的内容吗?同学们看到。往下面拉。哎,我可以简单先给大家提一下哈。提一下。好,我看看是在哪个位置。往下看。往下看,诶,这动态分配内存。就是说将来如果我们用的是ma。用这个函数就是如果我们使用这个ma在内存中动态存在内存的动态存储区分配一个长度为多少连续空间,那么这个会干什么呢?它会把这个空间分配的这个空间分配在堆区。
04:11
哎,就是用这个函数来分配的。就是我们这样写到叫动态内存分配的时候用这个。迈克。写字就是什么呢?用这个函数。函数动态分配,分配的数据放在放在哪里呢?放在一个堆区。堆中。OK,那还有什么区呢?同学们接着往下走,还有一个空间,对,注意听好,不着急,还有一个空间呢,我们把它称之为叫做什么静态。静态存储区。静态存储区。存储去。啊也也可以放什么呢?全局区也也有些地方叫,有些地方叫全局区也可以的,那在这个这个空间里面呢,可以放两种数据,两种数据,哪两种数据呢?OK,我给大家写到这里来,第一种呢,就是同学们,我们我们现在正在学习的第一种呢,就是我们的全局数据。
05:17
全局变量。就说全局变量呢,会放在这个空间。会放在这,诶这个地方有点小了哈。哟。全局变量会放在这个一。算了,我我放另外一个图形,这个图形太太糟糕了。放这个图形。就是在这个区间呢,我们可以存放的是全局变全局变量。选举量对。还可以存分耶,这个怎么回事?这个全局变量还可以是什么呢?还可以使我们的静态变量。后面马上会讲到的静态数据啊,静态数据。
06:04
静态数据,那也就是说在这个,如果我们将来在一个程序里面,我们定义了一个全局变量,或者是静态变量呢,它会放在这个区里边。他放在这个空间里边。对,那还有一个区呢,再给大家说最后一个,还有一个就是我们的代码区。所以这个大家明白了以后呢,对我们理解程序它它的一个运行的机制非常有帮助,这块是什么呢?是代码区。代码区听其名而知其意,就是干什么呢?存放我们代码的,或者存放我们这个存放我们这个存放代码的,就这样理解代码。存放代码。呃,说白了就是一堆堆的指令,就是我们的指令,就代码的指令。大家看这几个区看懂了没有。这就是我们计算机内存的一个完整的分布图,哪几个呢?局部变量,如果没有局部变量,它直接把这个变量放在这个站区。
07:06
如果将来我们使用这个麦。这个函数来动态分配数据呢,它把这个函数分配的数据存放的数据呢,存在这个堆区里边。如果是我们定义的一个全局变量,它会放在这个里面去。因为他的生命周期更长,它的作用率更更大,所以说它会放在这个地方,后面我们学这个静态数据,静态的变量或者静态内容的时候呢,静态数据它会放在这一块,也会放在这块,它的生命周期也比较长。另外一块呢,就是我们的代码,比如说我们写了一段程序,我们写了一段程序,这些指令他会放在这个区,放在这个代码去,那有些同学就要问了,说老师为什么C程序的设计者,他要把一个空间,把一个程序的空间分成这么一些,然后把不同的数据或者不同的这个变量放在不同的区里面呢?原因非常简单,因为每一种数据的性质和它的作用范围,它的它的一个机制都有些变化,所以说它会放在不同的地方,明白我的意思吗?就好比同学们,你可以这样想象,就好比你你你去你买了一套房。
08:19
你买了一套房?你为什么要把这套房是100平米,100平米,你为什么要把这个套这套房分划,划分成不同的风干空间呢?这个是客厅。会客用的对吧,哎,你还你还画一个空间,这个是什么呢?是你的卧室,是你睡觉的地方,比如睡房。啊,睡觉的地方你还有什么呢?还有这个厕所。是一上厕所的地方,还有什么呢?还有你的这一个,比如说阳台是来晾衣服的地方,或者是餐厅用来吃饭的地方,为什么你会把一个一百一百平米的房子划分成不同的空间呢?就是因为每一个空间的作用是不一样的,是不是这个道理?
09:04
那同样道理啊,我们这个C程序,它不同的变量会有不同的作用域,会有不同的使用方式,那么它就,那么我们这个C程序的设计者呢,他就会根据他的需要,在这个内存里面划分不同的空间,存放不同的数据。明白这个意思了吧?好,你这么去理解就可以了,好的,那明白这个道理过后呢,那还回到前面我们继续讲解好吗。我们继续讲解,刚才讲到哪里了呀,是不是讲到这了啊,这不是这是这个位置是不是好,我们接着往下继续看。那么第三点就是C语言规定只能从小的作用域向大的作用域去寻找变量,而不能反过来。即不能使用更小作用域的变量。什么意思呢?这句话什么意思呢?我给大家简单的解释一下,比如说吧。同学们看,呃,我我我我拿这个,其实这个一听就明白了哈。
10:03
一听就明白了。比如说。嗯,打个比方。嗯,这样说吧,我写了一个函数,我写了一个函数,贸易的F11 f20,假设是20。各位听我讲。假设20呢,这边我在这里边定义了一个变量,叫number等于90。Number等于90,各位同学,现在这是这是,呃,这是一个函数。这是一个函数,它它内部定义的变量呢?定义的变量变量就是局部变量。绝不变量是这样子的吧。那我问大家,我们在F20这个里面能不能使用DEF和A呢?是可以的,也就是说这个是全局变量。这是全局变量。那这里面的呢,定义的就是局部变量,那我如果在函数F20里面,我去使用。
11:03
P。各位同学可以看到,我比如说要使用A等于百分D,我在这这里使用A是可以的。我在这里使用A是可以的,为什么呢?因为我这个里面你可以理解是一个局部区域区域,我在这个局部区域里面,我去使用这个A呢,相当于是从小的一个范围里面,向大的这个范围里面去找。那我找到A了吗?我找到A了就OK。但是不能反过来。不能怎样反过来呢,比如说你这里有一个number,你这里有个number,你这个number呢,就不能在外面去使用。明白这意思吧,就是说我可以从一个小的作用域里面去找一个大的作用欲,但是不能反过来,可以这样,也可以这样理解,这好像是两个圈。这样好用,这个呢是我们的一个局部空间。这是一个全局的空间。好,那在这里面呢,我们去使用一个变量,比如这边有很多变量哈,有很多变量我在这里面,在这个内部去使用外部的是可以的,我我可以把这些东西拿进来使用,但是不能反过来,比如说我在这,我想把你这个局部变量空间里面的拿到外面去,这是不允许的。
12:17
这不允许的,也就是说你这个number不能在外面使用。但是这个A呢,因为它是全局的,所以它可以在其他函数里面使用,就是这个意思,理解到理解了哈,就是说只能从小的作用域向大的作用域去寻找变量,而不能反过来。还有一点,在同一个作用域中,变量名是不可以重复的,注意它这个有个前提,在同一个作用域。那如果不在同一个作用域呢?变量是可以重复的,变量名是可以重复的,在不同的作用域,变量名可以重复。使用编译器的就近原则,我举个例子吧,同学们还是以这个为例。咱们看。嗯,在这个F20里面,我定义一个number。
13:01
那我问大家一个问题,我能够再定一个number。值吗?显然这个就不行。你这样写,大家看我进行一个编译哈,我把这个注销,它会告诉我什么呢?它会告诉你这个number已经重复定义了,我们来看一下,我生成一下解决方案。大家注意观察,在第十行,第第九行,第十行,它一定会有一个信息提示大家看,这里果然提示了。是不是在这里啊,他说number定义,呃,重复了,重定义了吗?这是不允许的。但是呢,这个为什么,因为你你这个是在同一个作用域里面嘛,都在F20这个作用域,但是如果这样写就没问题,比如说我写个F30。比如说我还有一个函数F30,我在这里边呢,定义了一个number,哎,这个是可以的,比如说我这里写个80。这个是可以的,你看我把这个去掉了啊。这个就不冲突,说老师那不对啊,你这是个number,这是number名字不是一样的吗?是的,他们名字是一样。
14:06
但是人家不在同一个作用域啊。就好比我们有两个教室,A教室和B教室,A教室有一个人叫张三,B教室有一个叫张三,老师是可以区分的,是不是,但是如果A教室有两个人都叫张三,那老师提问的时候说张三,那到底叫哪个,是不是区分不了,但是你在不同的空间,那就无所谓了,你这有个叫AA变量,这个A变量这是可以的,你看我给同学们编一下,不会有任何错误提示。我们可以看到呢,这个代码是OK的,是不是OK的呀,你看。全部生成成功的,没有任何问题。这点请同学们注意好不好?那么还有一点呢,由大括号包围起来的代码块也拥有独立的作用欲。这个是什么意思呢?不是,前面已经讲过了,也就是说我们用这个for或者if Switch等等,我们也有独立的作用力,前面其实我讲过这个东西是不是在这在最前面我就讲过了,这个不再多说了,就是大括号包起来的代码块,它也有自己独立的作用域。
15:12
这这在前面我讲讲变量的时候已经提到这个点了,我就不再多说了,好不好好现在呢,我们图也有了。图也有了,我们这注意事项也有了,老师就说到这儿,这第五点我再多说一句啊,比如说我这样写。大家看,大家认为会不会报错,同学们看一下。呃。比如说哈。比如说我在这个地方。For,这里面有个for循环。或者if吧。If。错。为真哈,然后呢,我在这里面定一个number等于。900。大家觉得这个时候,呃,苏老师,诶,那你看啊说老师,那你看这个地方有一个number,这里面也有一个number,大家觉得这个时候他会不会会不会报重复定义呢。
16:05
大家觉得会不会报重复定义,我们来编一下。那各位同学我们编一下,我们看一下它会怎么提示我们。OK啊,你看有报错吗,同学们。你看有报错吗?没有报错,全部重新啊,生成已成功,应该没有报错啦,应该没有报错吧。因为上面整个这个是OK的,没有任何错误,为为什么这个没有错误呢?是因为是因为你的这一个是一个独立的作用域,相当于你可以理解成,你可以理解成好像对这个if而言来说,它是一个全局的,但我说的是对这个if块来说啊,就它的范围呢,这个外面这个number等于90的作用率比我更大。我呢是一个我在这个这个块里面呢,我是一个更小的作用域,它是能够区分的,就好比如果说我们画一个图来说,好比这有个A教室。这有个A教室。
17:00
那么这个A教室里面呢,我们划分了几个小组?哎,划分了几个小组,比如这是一一组,这是二组,这是三组,这是四组,那么我们分别授课,那这个时候在这个里面的变量和外面变量,它是有不同的作用域的,是可以区分的,但是同样道理啊,你不能说苏老师我在这里面再来定一个,那又又不行了。因为你再定义一个的话呢,你你在这里面又重复了,明白这个意思吗?你看我再给大家生成一把,就是仍然报错的,你看它会报一个重复定义。好,你是失败了,失败在哪里?失败了呢?我们ear往上走,我们发现在这里。是不是他说13行你重定义了呀,诶就这个意思,好吧,同学们。那关于这点呢,老师就给大家讲解到这,我相信同学们应该都能理解,并不难。好,我把这一个呃,简单的给同学们板述到这里,非常的简单,几句话的事儿好不好?好,但是很重要,这块其实很重要。同学们作用于我把它。
18:06
编一个号。我们一共整理了有这么四点。对不对,一点点的,那尤其是C程序的内存布局图,我要好好的跟他聊一下,这个内存布局图是一定要掌握的,同学们,因为你只有掌握了这个内存布局图呢,后边我们就是一马平川,我把这个图拿过来,好吧,这是老师画的这个图。这个图呢,我给大家放到我们的笔记中去,便于各位同学的复习。好,这个图是很有指导意义的,大家一定要有一个深刻的印象,下面很多很多东西呢,在解释原理原理的时候,都要依赖于这一个内存布局图。好,这些规则大家有一个印象好不好?那么这儿还有几个小案例,这个案例呢,我就。呃,其实这不不需要拿了,因为这个很好理解的,因为这这里面这几句话,这里面的语言已经把它说的非常清晰了,你看只能从小的作用域向大的作用域去寻找,不能反过来,这个是肯定很好理解了,然后呢,在同一个作用域变量不能重复。
19:12
这个很好理解,不同的作用域呢,变量可以重复,是不是也举例了呀?啊,还有这个大括号。同学们所说这个大括号呢,它也有独立的作用域,所以说你这样写的话呢,在这里是OK的,这个代码是可以的。我写的对,来哈。大家举个例子吧,说下面的代码是可以的举例。我举例说明,举例说明,把这个小案例放过去就可以了,好,这边我们写到这是OK的,可以了,OK。好,各位同学,那关于我们变量作用域的内容,还有我们C程序内存布局图,就给大家讲解到这里。
我来说两句