如同字面意思:static代表不流动,extern代表流动;
说实话,这俩东西给本菜的感觉像是类里的public、private关键字,都是对作用域的限制;
如果我们定义一个变量为static变量,那么就声明了这个变量只能在本文件在被链接,对函数也是如此。extern不一样,当你用他声明一个变量时,系统并不是在真正创建一个变量,而是在向其他文件寻找同名变量,并调用;
现在我们有两个文件,value.cpp,源.cpp
源.cpp:
//源.cpp
#include<iostream>
int var = 1;
int main() {
std::cout << &var << std::endl;
std::cout << var << std::endl;
}
value.cpp
//value.cpp
#include<iostream>
int var = 1;
void show_var() {
std::cout << &var << std::endl;
}
这个时候会报错:
这个是因为我们在讲文件链接起来的时候,发现一两个相同名字的变量,这很离谱。
因为这两个变量的作用域是全局的。【在别的文件在调用要用extern关键字】
我们只要稍稍做改进:
将源.cpp改为:
#include<iostream>
extern int var;
void show_var();
int main() {
std::cout << &var << std::endl;//展示源.cpp里var的地址
std::cout << var << std::endl;
var++;
show_var();//展示value.cpp里的var地址
}
然后就可以过编译了;
但是我们运行的时候我会发现一个非常有意思的现象:
先看一下运行结果:
哦吼吼,原来var这个值是通过共享地址在不同文件中使用的;
其实我们还有一个方法可以改进这个bug,那就是将两个文件中的var变量定义为static,这个意思就是告诉链接器:你虽然看见两个一样名字的变量,但是这两个变量只在各自的文件中可以被调用,决不越雷池半步;
居然作用域不同,那么当然不会产生重名冲突,这里可以类比两个在同一文件中的两个独立函数,如果我们在这两个独立的函数中定义两个一样名字的变量,那么我们知道肯定不会出bug,因为他们的作用域没有交集;
改变后的文件如下:
//源.cpp
#include<iostream>
static int var;
void show_var();
int main() {
std::cout << &var << std::endl;//展示源.cpp里var的地址
std::cout << var << std::endl;
var++;
show_var();//展示value.cpp里的var地址
}
//value.cpp
#include<iostream>
static int var = 1;
void show_var() {
std::cout << &var << std::endl;
std::cout << var << std::endl;
}
这个时候我们运行,就会发现:
这两个var分别是独立的;
如果我们在value的show_val函数在声明一个extern int var;
然后就有:
#include<iostream>
static int var = 2;
void show_var() {
extern int var;
std::cout << &var << std::endl;
std::cout << var << std::endl;
}
运行一下:
这说明extern找到的是本文件中的var变量;
如果我们将value.cpp中的var删除,那么会报错:
这是什么原因呢?明明源.cpp中有一个var,且我们在value.cpp中让系统在别的文件中找var;
这只能说系统没找到,因为源.cpp中的var是静态的,static的,var只能在源.cpp中被调用,故系统找不到合法的var;
但是如果我们再定义一个文件:second.cpp,里面定义一个var,那么会怎么样呢?
//second
int var=1;
然后我们运行:
可以过了!