目录
1.static关键字是什么?
2.static关键字修饰的对象是?
3.static修饰后改变了什么?
4.static修饰操作演示
(1) 局部变量
如果加了static修饰局部变量i会怎么样?
全局区(静态区)
(2)全局变量
如果给全局变量加上了static修饰呢?
二者区别?
这样用有什么用?
(3)函数
5.总结
static修饰局部变量
static修饰全局变量
static修饰函数
6.补充
后言
1.static关键字是什么?
· static关键字在c语言中还是比较常用的,使用恰当能够大大提高程序的模块化特性,有利于扩展和维护。但是对于c语言初学者,static由于使用灵活,并不容易掌握。
本文就static在c语言中的应用进行总结,供参考使用。
本文会提及C/C++中的内存分区,内存讲解也是点到为止。对此不了解的小伙伴的可以百度一下,后面会出一期内存分区详解。
2.static关键字修饰的对象是?
1.局部变量
2.全局变量
3.函数
3.static修饰后改变了什么?
1.改变了生存周期:就是一个变量、函数从分配内存到回收内存的过程
2.改变了作用域:就是可以在哪些文件里可以使用该函数或者变量
4.static修饰操作演示
(1) 局部变量
void test(){int i = 1;i++;printf("%d ", i);}int main() {int j = 0;while (j < 5){test();j++;}return 0;}
通过上面的代码可以看出,test函数会被调用5次。
因为局部变量是存放在“栈区(stack)”,栈区内存的特点是:由编译器自动分配、释放。
所以test中局部变量 i在每次进入这个函数时都要被创建一次,然后i++,最后输出,当前test函数结束,局部变量 i 内存被释放。
由此可见,每次进入test都是一个全新的局部变量 i,结果如下。
如果加了static修饰局部变量i会怎么样?
我们可以发现 i 的值经过多次test函数的调用,没有销毁。这说明了用了static关键词修饰的局部变量 i 的生命周期被延长了。这也说明了静态局部变量 i 肯定和局部变量的 i 的存放位置不一样。接下来,就讲的是“全局区”。
全局区(静态区)
static关键字修饰的局部变量 i 是存放在“全局区”,全局区内存的特点是:在整个程序结束后,由操作系统自动释放。不同于普通的局部变量i,生命周期只在test函数结束就消亡了。static修饰下的i是要整个程序结束才释放。
因此,以 i 为例子,栈区和全局区在本代码可视化为上图。(不严谨,本图仅供参考)
相信上面的例子,应该可以对你建立基本的了解。
以上为汇编代码,可以看到,普通变量 i 是回通过编译成汇编转二进制的。而静态变量不会
(2)全局变量
上面代码是在同一个项目下的两个.c 文件,在左边.c文件声明了一个普通的全局变量,用extern来声明外部符号来声明g_val的存在,是可以正常访问的。如下图
如果给全局变量加上了static修饰呢?
可以看到“无法解析的外部符号 _g_val”,这说明了静态全局变量只能在当前.c文件中访问。
二者区别?
·普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。
·静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。
这样用有什么用?
在定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用。
(3)函数
函数和全局变量的情况其实基本一致,所以简单讲一下吧。
同样是外部定义普通的swap函数,用extern声明外部函数(当然也可以用头文件的方式),可见可以正常访问。
但用了static修饰后,也只能在本.c文件中使用了。外部不可访问。
5.总结
static修饰局部变量
应用:在函数内,我们想保留某些变量上一次的值,就可以用static去修饰该变量。比如:想统计该函数被执行的次数时,就可以定义被static修饰的int型变量,每执行一次该变量就++。
总结:用static修饰的局部变量,改变了生存周期,但是没有改变其作用域。改变其生存周期的原因是被static修饰的局部变量被存放在.bss段(未初始化)或者 .data段(初始化),但两者都是在(全局区)静态区,而普通的局部变量是存放在栈上的。
static修饰全局变量
应用:当一个全局变量不想被其他.c文件引用时,可以用static修饰,这样其他的文件就不能通过extern的方式去访问,这样主要是为了数据安全。
总结:改变其作用域,没有改变生存周期。
static修饰函数
应用:有些函数并不想对外提供,只需要在本文件里调用,这时候就可以用static去修饰。
总结:改变了作用域,没有改变其生存周期。
6.补充
用static修饰全局变量和函数,除了上面说的数据安全,防止被误引用。
还有一个作用是解决重名问题。当用static修饰了全局变量和函数后,其他文件里再定义同名的全局变量和函数也是可以的。
一般来说,如果不是要对外提供的函数和全局变量,最好都用static修饰。
后言
本篇基本介绍了C语言中static关键字的概念,基本应用场景,应用实例,和总结。相信可以给初学着在理解和使用上有一定的帮助。本篇有着内存分区,生命周期和作用域方面的知识。后面会出单篇详解,希望大家支持。因个人能力有限,如果有错误的地方,请大家指出。