我们续接上节内容,继续学习有关函数的相关知识。
目录
1.static和extern
我们现在先来学习两个关键词:static和extern。
1.1 作用域和生命周期
对于一个变量来说,我们可以按照作用域的不同分为局部变量和全局变量,而他们的存储的位置是有所不同的。其中局部变量存储在栈区,而全局变量存储在静态区。
局部变量也就是只能在一个固定的范围内进行使用,这个范围被称为作用域,正常情况下局部变量在作用域内创生,出作用域时销毁,这个过程被称为局部变量的生命周期。
这里也补充一下,如果一个局部变量没有初始化,那么值默认为随机值;而一个全局变量如果没有初始化,那么默认为0,比如下面这个例子:
我们可以看到,a没有初始化,但是a在main函数外部,属于全局变量,全局变量的作用域是整个项目(工程)。所以,a的值默认为0。而且需要注意的是,当局部变量和全局变量同时初始化,局部变量优先,例如:
在这段代码中,main函数里还初始化了局部变量a,局部变量的作用域是变量所在的局部范围,即main函数内部。所以这里我们得到的结果为20。
对于生命周期,我们也需要知道,对局部变量来说,它的生命周期是进入作用域变量创建,生命周期开始,出作用域生命周期结束。 对全局变量来说,它的生命周期是整个程序的生命周期。
1.2 static修饰局部变量
如上述所说,一般局部变量是存储在栈区的。而如果一个局部变量被static修饰之后,其存储空间就会变为静态区。造成的结果就是:被static修饰的局部变量的生命周期被扩大为了全局变量的生命周期,但是其作用域不变。我们来举个例子:
我们可以看到,对于这个例子来说,n是局部变量,其作用域是function内,出了function那么n就会被销毁,所以结果会是5个1。那我们如果把n用static修饰会怎么样呢?
我们可以看到,n被static修饰,那么生命周期被延长为整个程序的生命周期,也就是出了function后n并不会被销毁,所以反复执行function的过程中,n不会被重新定义为0,而是保留上一次的值,所以得到的结果就是1 2 3 4 5了。
1.3 extern声明外部符号
大家想一下,一个程序中必然是包括多个源文件的,不同的源文件可能有不同的功能。那如何在源文件A中使用源文件B内部的符号呢?就要用到extern。
那能用extern声明的符号必须有一个大前提,就是它必须是全局符号,这样才能使它的生命周期与整个程序相等。如果是局部符号,出了作用域就被销毁了,是没有办法被声明的。我们来看一下下面的例子:
我们可以看到,我们再test.1.cpp中定义了year为2023,我们现在想要在test.2.cpp中使用,就要用到extern来声明:
我们用extern来声明一下year,就可已在test.2.cpp中使用了。
1.4 static修饰全局变量
我们上面说到,extern可以声明全局符号,使得该源文件可以引用别的源文件的全局变量。但是我们思考一下,如果这个全局变量被static修饰,那会怎么样呢?
实际上,如果一个全局变量被static修饰,那么这个全局变量就只能在该源文件中进行使用了。即使extern对它进行声明,也没办法引用。我们来看看:
我们在test.1.cpp中对全局变量year用static修饰。
我们再编译的时候就能发现,VS无法解析外部命令,因为它只能在它所在的源文件中使用。
1.5 static修饰函数
我们知道,如果一个函数在源文件A中,想要在源文件B中使用这个函数,可以用extern来进行声明。但是和static修饰全局变量一样,如果这个函数被static修饰,那么它只能在它所在的源文件中进行使用。
我们现在先在test.1.cpp中定义一个加法函数Add
现在我们再test.2.cpp中使用它
此时是可以实现的,我们将Add用static修饰
此时Add就没有办法在test.2.cpp中被调用了
相信大家现在已经明白了关键字static和extern的相关用法了,那函数部分的内容就先分享到这里,感谢大家的观看!