目录
1.引言
static 和 extern是C语言众多关键字中的一个,下面我就来介绍下这两个关键字。
2.作用域和生命周期
2.1 作用域
作用域是程序设计概念,通常来说,程序中定义的标识符(变量,函数,类)并不总是可用的,而限定标识符的可见性和有效性的范围的就是这个标识符的作用域。
局部变量的作用域是:变量所在的局部范围
全局变量的作用域是:整个项目内部
上面代码运行后会报出右侧图片的错误。
变量 a 的作用域是main函数内部范围,所以for循环里边可以使用,for循环外面也可以使用,
变量 b 的作用域是for循环内部范围,出了for循环后就不能使用了。
2.2 生命周期
生命周期是指从变量创建(申请内存)到变量销毁(释放内存)的一个时间段。
局部变量的生命周期是:进入作用域,生命周期开始,出作用域,生命周期结束。
全局变量的生命周期是:整个程序的生命周期 = main函数的生命周期
变量a的生命周期是从进入main函数开始到main函数运行完结束。
变量b的生命周期是从进入for循环开始到出for循环结束。
3. extern
extern是用来声明外部符号的,如果一个全局变量想在其他.c文件中使用的话,可以通过extern来进行声明,然后使用。
在A文件中定义了一个变量 a,想要在B文件中使用,就需要用到extern在B文件中声明,便可以使用了。
4. static
4.1 static修饰局部变量
左图是变量 n 未加static修饰,变量 n 在每次进入print函数时候,创建变量(向内存申请空间)并赋值 0 ,然后++,打印 1,然后出函数的时候变量 n 销毁(释放内存),一共循环了5次,所以打印了 5 个 1。
右图是变量 n 加static修饰后,变量 n 在每次进入print函数时候,创建变量(向内存申请空间)并赋值 0 ,然后++,打印 1,然后出函数的时侯变量 n 没有被销毁,而是在下一次继续累加,打印出来 1 2 3 4 5 。这是为什么呢?
因为内存里面存在 栈区,堆区,静态区 等区。
static修饰局部变量改变的是变量的生命周期,生命周期改变的本质是改变了变量在内存中存储的位置,由原来的栈区变成了静态区,跟全局变量在一个区内,因此被static修饰的变量跟全局变量一样,只有在程序运行结束后,才会被注销(释放内存)。 但此局部变量的作用域不会改变,只会改变生命周期。
4.2 static修饰全局变量
在A文件中,用static修饰全局变量a,即使用extern在B文件中声明了,运行B代码仍然会爆出上图的错误,这是为什么呢?
static修饰全局变量,使得这个全局变量只能在本文件(A文件)中使用,再其他文件不能使用,因为全局变量默认具有外部链接属性,用static修饰后外部链接属性变成内部链接属性,只能在自己所在的源文件中使用,在别的源文件中即使用了extern修饰也无法使用。
建议:如果一个全局变量,只想在所在的源文件内部使用,不想被其他文件发现,就可以使用static修饰。
4.3 static修饰函数
static修饰函数跟static修饰全局变量差不多。
static修饰函数,使得这个函数只能在本文件(A文件)中使用,再其他文件不能使用,因为函数默认具有外部链接属性,用static修饰后外部链接属性变成内部链接属性,只能在自己所在的源文件中使用,在别的源文件中即使用了extern修饰也无法使用。
建议:如果一个函数,只想在所在的源文件内部使用,不想被其他文件发现,就可以使用static修饰。