static 和 extern
static 和 extern都是C语言的关键字。
static是静态的意思,可以用来:
- 修饰局部变量
- 修饰全局变量
- 修饰函数
extern 是来声明外部符号的
一、函数的作用域和生命周期
作用域是程序设计概念,通常来说,一段程序代码中所用的名字并不是在整个代码中都可以使用而具有限定范围( {大括号内} ),而限定这个名字的可用性的代码范围就是这个名字的作用域。
- 局部变量的作用域是变量所在的局部范围。
- 全局变量的作用域是整个工程(项目)。
生命周期指的是变量创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。
例如:
在自定义函数中所使用的变量不能够在main函数或者其他函数中使用
局部变量y的生命周期就是print( )函数的生命周期只在print( )函数中出现一次
main函数也是如此, main函数中的变量为局部变量只能在main函数中使用
局部变量b 的生命周期就是main函数的生命周期
同时全局变量可以在整个代码中和任意函数中使用
全局变量a的生命周期就是整个代码
总结:
全局变量生命周期和整个代码生命周期相同直到运行结束
局部变量生命周期和所在的函数生命周期相同
二、static修饰局部变量
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void test()
{
//static修饰局部变量保存i上次所赋予的值
static int i = 0;
i++;
printf("%d", i);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;
}
见执行结果为 12345,可知每次执行for循环中进入test( )函数时, static会存储 i 的值 i 的值为上次循环所赋予的 i 的值
未用static关键字修饰的,可知每次执行for循环进入test( )函数时, 都是从int i = 0 开始计算,不会存储 i 的值。
结论:static修饰的局部变量改变了变量的生命周期,生命周期的改变本质实际是改变了变量的存储内类型, 未用static修饰的局部变量是存储在内存的栈区的,但被static修饰后存储到静态区。存储在静态区的变量和局部变量是一样的,生命周期和程序的生命周期一样了,只有程序结束,变量才销毁,内存才回收。作用域是不变的。
三、extern声明外部符号
extern是用来声明外部符号的,如果一个全局的符号在A文件中定义,在B文件中想使用,就可以使用extern 进行声明。
源.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> extern void print(); int main() { print(); return 0; }
将 print.c 源文件引入到 源.c 文件中
print.c:
#include<stdio.h> void print() { printf("hello wrold! enjoy ours life!"); }
结果如图:
四、 static在多文件中修饰函数
多个文件中将A文件的一个函数传递到B文件中用static修饰该函数会出现怎样的后果呢?
如图显示 add(int x, int y) 可以正常运行,但static修饰函数 static int Add(int x, int y)则会出现问题。
原因如下:
static修饰函数如修饰变量一样只能在该文件内部中使用,其他外部文件不能正常的连接使用。
本质因函数默认是具有外部链接属性的,使用函数在整个工程中只要适当的声明就可以被使用,但static修饰就变成了内部链接属性,使函数只能在自己所在的源文件内部使用。
使用建议:一个函数只想在源文件内部使用,不被其他源文件使用可以用static修饰。