
static和extern都是C语言中的关键字。
static 是 静态的 的意思,可以用来:
extern是用来声明外部符号的。
在了解这两个关键字之前,先来了解一下作用域和生命周期。
**作用域(scope)**是程序设计概念,通俗来说就是一个名称的适用范围就是这个名称的作用域。
生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。
先来看两段代码:
//不用static修饰
#include <stdio.h>
void test()
{
int a = 1;
a++;
printf("%d ", a);
return;
}
int main()
{
int i = 0;
for (i = 0;i < 5;i++)
test();
return 0;
}运行结果

//用static修饰
#include <stdio.h>
void test()
{
static int a = 1;
a++;
printf("%d ", a);
return;
}
int main()
{
int i = 0;
for (i = 0;i < 5;i++)
test();
return 0;
}运行结果

为什么会造成两种运行结果的不统一呢?
我们先来了解一下内存是如何储存的
栈区 | … | 堆区 | … | 静态区 |
|---|---|---|---|---|
局部变量、函数参数 | … | 动态内存管理 | … | 全局变量、静态变量 |
这是内存内部的一部分结构
结论: static修饰局部变量改变了变量的⽣命周期,⽣命周期改变的本质是改变了变量的存储类型,本来⼀个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。存储在静态区的变 量和全局变量是⼀样的,⽣命周期就和程序的⽣命周期⼀样了,只有程序结束,变量才销毁,内存才回收。但是作⽤域是不变的
如图1: 将初始化和函数主体放到两个文件中,用extern进行声明,不使用static来修饰全局变量

extern是⽤来声明外部符号的,如果⼀个全局的符号在A⽂件中定义的,在B⽂件中想使⽤,就可以使⽤extern 进⾏声明,然后使⽤。
如图2: 将初始化和函数主体放到两个文件中,用extern进行声明,使用static来修饰全局变量

结论: 如我们所见,使用static修饰全局变量以后,这个全局变量就只能在本文件内部使用了。这其实是因为全局变量本来是有外部链接属性的,而添加了static以后变成了内部连接属性,就只能在本文件内部使用了,其他文件即使声明以后也不能使用。
static修饰函数和static修饰全局变量是很类似的,因为函数本身也有外部连接属性,下面我们来看例子:
如图1: 将函数的定义和调用放到两个文件中,用extern进行声明,不使用static来修饰全局变量

如图2: 将函数的定义和调用放到两个文件中,用extern进行声明,使用static来修饰全局变量
