static和extern的详细介绍和使用
static和extern都是C语言中的关键字。
static是静态的意思。
1.static修饰局部变量
2. static修饰全局变量
3. static修饰函数
4.extern:用来声明外部符号。
在讲解这两个关键字之前,我们还需要了解两个概念:作用域和生命周期。
作用域:通俗的来讲就是限定一个变量可用性的代码范围就是这个变量的作用域。
- 局部变量的作用域是变量所在的局部范围(花括号内部)。
例如:
#include <stdio.h> int main() { { int a = 20;//局部变量 printf("1:%d\n", a); } printf("2:%d\n", a); return 0; }
运行结果为:
这是因为我们定义的变量a是局部变量,只能作用于它所在的花括号内,出了这个花括号,变量就销毁了,生命周期也结束了。
- 全局变量的作用域是整个工程(项目)。
例如:
#include <stdio.h> int a = 20;//全局变量 int main() { { printf("1:%d\n", a); } printf("2:%d\n", a); return 0; }
运行结果为:
这时的a是一个全局变量,它可以作用于整个项目。
生命周期:指变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。
- 局部变量的生命周期是:进入作用域变量创建,生命周期开始;出作用域生命周期结束。
- 全局变量的生命周期是:整个程序的生命周期(main函数的生命周期)。
1.static修饰局部变量
代码1:
#include <stdio.h> void test() { int i = 0; i++; printf("%d ", i); } int main() { int i = 0; for (i = 0; i < 5; i++) { test(); } return 0; }
运行结果是:
这是因为我们循环5次调用test函数,第一次调用test函数时,创建了一个局部变量i,生命周期开始,i++之后i=1,打印1,出了test函数之后i被销毁,生命周期也结束了。第二次调用时仍要重新创建i,如此循环5次,最终打印结果是5个1。
代码2:
#include <stdio.h> void test() { static int n = 0;//static修饰局部变量 n++; printf("%d ", n); } int main() { int i = 0; for (i = 0; i < 5; i++) { test(); } return 0; }
运行结果是:
从输出结果来看,i的值有累加的效果,这是由于static的修饰,test函数中的i创建好后,出了函数也没有被销毁,重新进入函数时也不会重新创建变量。
结论:
static修饰局部变量改变了变量的生命周期,生命周期的改变本质是改变了变量的储存类型,本来一个局部变量是储存在内存的栈区,但是被static修饰后储存在内存的静态区。
储存在静态区的变量和全局变量是一样的,生命周期就和程序的生命周期一样了,只有程序结束,变量才销毁,内存猜回收。但是作用域不变的。
2.static修饰全局变量
4.extern是用来声明外部符号的
如图,我们在同一个项目里创建了两个源文件,当我们要使用外部文件里的g_val时,会报错。
但是,当我们用extern进行外部声明时,程序成功运行。
但是如果我们用staatic修饰全局变量时,程序仍会报错。
结论:一个全局变量被static修饰后,使得这个全局变量只能在本源文件里使用,不能在其他源文件里使用。
3. static修饰函数
static修饰函数和static修饰全局变量的情况是一模一样的,此处不再重复赘述。