前言
static和extern都是c语言中的关键字,在c语言的学习中不可忽视,尤其是static的作用,非常重要,经常被面试官当做问题来提问。extern的作用很单一,但因为经常和static一起讨论,这里就也一并说说。接下来就来讲讲这两个关键字各自有什么作用。
static的作用
1.static修饰局部变量
再讲static修饰局部变量前我们先来了解两个知识点:作用域和生命周期
1)作用域
通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
(1)局部变量的作用域是变量所在的局部范围;
(2)全局变量的作用域是整个项目;
作用域的好处:作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突。
2)生命周期
概念:指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。
(1)局部变量的生命周期:是进入作用域 生命周期开始,出作用域 生命周期结束;
(2)全局变量的生命周期:整个程序的生命周期;
3)static修饰局部变量
我们从两段代码认识static是如何修饰局部变量的。
1.
2.
可以看出,两段代码十分相似,只是第二段代码中test函数中创建的局部变量a被static修饰了,因此每次循环后a的值被保留了下来而不是被销毁了。为什么会这样呢?这就是static修饰局部变量的作用了,如图:
所以有了static修饰,那么在编译器上就有了a,而在这里就不会创建临时变量a = 1。但是a的作用域还是不变的,也就是说a还是只能在test函数中使用,出了这个函数就不行了。
2.static修饰全局变量
了解static修饰全局变量前,我们先来了解一个关键字:extern
2)extern
extern的作用只有一个:声明外部符号。什么意思呢?就是说一个全局符号是在A文件中定义的,而我想在B文件中使用它,那么用extern声明一下就行了。话不多说,上图:
我们创建两个文件,sub.c和test.c。在sub.c文件中创建一个全局变量a,若想在test.c文件中使用它,不用extern声明的情况是这样的,编译器无法识别a,报错了。
用extern声明后:
此时就行了。
2)static修饰全局变量
依旧是这段代码,在全局变量a前加上static修饰会咋么样呢?
可以看出,即使有extern声明,被static修饰的全局变量a依旧无法在test.c文件中使用。为啥呢?
首先我们得知道全局变量的一个特性:全局变量是具有外部链接属性的,也就是说只要被extern适当的声明,就能在其他的文件中使用。但是static改变了这一特性:static修饰全局变量将全局变量的外部链接属性变成了内部链接属性,也就是说被static修饰的全局变量只能在本文件中使用。
3.static修饰函数
static修饰函数和static修饰全局变量非常相似,这里就不过多赘述了,具体看下面这张图:
static修饰函数将函数的外部链接属性变成了内部链接属性,也就是说被static修饰的函数只能在本文件中使用。