大家好,今天和大家分享C语言中的两个关键字以及作⽤域和⽣命周期的有关知识,创作不易,三连支持一下吧!
一、作用域和生命周期
在了解static和extern之前,我们先了解一下作用域和生命周期。
1.作用域
作⽤域(scope)是程序设计概念,通常来说,⼀段程序代码中所⽤到的名字并不总是有效(可⽤)的,⽽限定这个名字的可⽤性的代码范围就是这个名字的作⽤域。
局部变量的作⽤域是变量所在的局部范围;
全局变量的作⽤域是整个⼯程(项⽬)。
如:
那我们又有疑问了,局部变量和全局变量都在怎么办——采用就近原则,就是优先使用该作用域的变量,也就是优先使用局部变量。但不允许同一个作用域定义多个相同的变量名,会产生冲突。
如:
2.生命周期
⽣命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。
局部变量的⽣命周期是:进⼊作⽤域变量创建,⽣命周期开始,出作⽤域⽣命周期结束。
全局变量的⽣命周期是:整个程序的⽣命周期。
我也可以理解为变量的存活时间。如:
作用域和生命周期与函数栈帧的创建与销毁有关,函数栈帧的创建与销毁我们在后面会具体学习。
二、static和extern
static和extern都是C语⾔中的关键字。
static是静态的 的意思,可以⽤来:
• 修饰局部变量
• 修饰全局变量
• 修饰函数
extern是⽤来声明外部符号的。
下面我们就具体学习它们的功能和用法。
1.static修饰局部变量
我们先来看两段代码:
我们可以看得到这两段代码的运行结果不一样,仅仅是因为多了一个static。
代码1的fun函数中的局部变量i是每次进⼊fun函数先创建变量(⽣命周期开始)并赋值为0,然后++,再打印,出函数的时候变量⽣命周期将要结束(释放内存)。
代码2中,我们从输出结果来看,i的值有累加的效果,其实fun函数中的i创建好后,出函数的时候是不会销毁的,重新进⼊函数也就不会重新创建变量,直接上次累积的数值继续计算。
所以我们得出结论:static修饰局部变量改变了变量的⽣命周期,⽣命周期改变的本质是改变了变量的存储类型,本来⼀个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。存储在静态区的变量和全局变量是⼀样的,⽣命周期就和程序的⽣命周期⼀样了,只有程序结束,变量才销毁,内存才回收,但是作⽤域不变。
接下来我们画图理解一下:
我们知道内存分为栈区,堆区和静态区,一般局部变量和函数参数存放在栈区,而静态变量和全局变量存在静态区,当局部变量前加上static后就变成了静态变量。未来⼀个变量出了函数后,我们还想保留值,等下次进⼊函数继续使⽤,就可以使⽤static修饰。
2.static修饰全局变量
我们还是先来看两段代码:
在这里,extern是⽤来声明外部符号的,如果⼀个全局的符号在A⽂件中定义的,在B⽂件中想使⽤,就可以使⽤ extern 进⾏声明,然后使⽤。
我们可以看到第一段代码可以正常运行,第二段代码报了错。
⼀个全局变量被static修饰,使得这个全局变量只能在本源⽂件内使⽤,不能在其他源⽂件内使⽤。
本质原因是全局变量默认是具有外部链接属性的,在外部的⽂件中想使⽤,只要适当的声明就可以使⽤;但是全局变量被 static 修饰之后,外部链接属性就变成了内部链接属性,只能在⾃⼰所在的源⽂件内部使⽤了,其他源⽂件,即使声明了,也是⽆法正常使⽤的。
所以:如果⼀个全局变量,只想在所在的源⽂件内部使⽤,不想被其他⽂件发现,就可以使⽤
static修饰。
3.static修饰函数
先来看两段代码:
第一段代码是能够正常运⾏的,但是第二段代码就出现了链接错误。
所以我们可得出结论: static 修饰函数和static 修饰全局变量是⼀模⼀样的,⼀个函数在整个⼯程都可以使⽤,被static修饰后,只能在本⽂件内部使⽤,其他⽂件⽆法正常的链接使⽤了。
本质是因为函数默认是具有外部链接属性,具有外部链接属性,使得函数在整个⼯程中只要适当的声明就可以被使⽤。但是被 static 修饰后变成了内部链接属性,使得函数只能在⾃⼰所在源⽂件部使⽤。
所以以后我们想要⼀个函数只想在所在的源⽂件内部使⽤,不想被其他源⽂件使⽤,就可以使⽤ static 修饰。
好了以上就是本文的全部内容了,感谢大家的观看,有错误的话欢迎指正。三连支持一下再走呗
标签:函数,局部变量,C语言,修饰,static,extern,全局变量,变量 From: https://blog.csdn.net/2301_79697817/article/details/137074201