同一项目中,不同文件间的同名同类型全局变量是不能互相使用的,那这时我们就可以使用extern、static来解决。
同时,虽然extern、static均可以修饰全局变量,但他们的意义却是大不相同。
目录
一.使用方式
extern:
当我们在某一文件中定义了一个全局变量,只需要在其他文件中使用extern来声明该变量即可。
//文件1
int num = 5;//定义
//文件2
extern int num;//声明
注意:变量只能定义一次,即文件2中不能出现这样的代码:
extern int num = 3;//这是定义,与文件1冲突
而且,不要在头文件中定义。因为,假如源文件中需要头文件定义的变量num,但源文件没有包含头文件,那么程序就会报错。
static:
static定义的变量,可以直接在其他包含同头文件的文件中使用。
//文件head.h
static int num = 5;
//文件2
#include"head.h"
void func()
{
num++;
cout << num << endl;
}
二.区别
1.static修饰的全局变量没有外部属性,extern修饰的具有外部属性。
这句话该怎么理解呢,假如我们有一个int类型全局变量num。
当用static修饰时,同项目不同文件中虽然都可以直接用num,但在一份文件中改变的num值不会影响到其他文件。这是因为本质上各个文件中的num是不同的,即地址不同。
例:
//以下属于head.h文件
static int num = 0;
void func();
//以下属于文件1
#include"head.h"
void func()
{
cout << "文件1中num初始化值:" << num << endl;
num++;
cout << "文件1中num++后值:" << num << endl;
cout << "文件1中num地址:" << &num << endl << endl;
}
//以下属于文件2
#include"head.h"
int main()
{
func();
cout << "文件2中num初始化值:" << num << endl;
cout << "文件2中num地址:" << &num << endl;
return 0;
}
我们发现,文件1与文件2的num地址是不同的,所以文件1中num值加1,但文件2中num值却没有改变。
但extern与之不同,改变某一个文件,其他文件中的num值也会改变,因为本质上是同一个地址。
例:
//以下属于head.h文件
extern int num;//声明
void func();
//以下属于文件1
int num = 0;//定义
void func()
{
cout << "文件1中num初始化值:" << num << endl;
num++;
cout << "文件1中num++后值:" << num << endl;
cout << "文件1中num地址:" << &num << endl << endl;
}
//以下属于文件2
extern int num;//声明
int main()
{
func();
cout << "文件2中num初始化值:" << num << endl;
cout << "文件2中num地址:" << &num << endl;
return 0;
}
extern中,文件1与文件2的num地址相同,所以当文件1中num加1后,文件2中num也跟着改变了。
2.static必须是不同文件间都包含带有static的文件,extern可以是不同文件。
假如是不同文件的文件间想相互使用变量,要用extern。
假如包含同一头文件的文件间想相互使用变量,但又不希望其他文件的操作改变本文件变量,使用static。
3.static修饰全局变量不入符号表,extern修饰变量入符号表。
因为static修饰变量只在本文件中使用,但符号表中的是可以被其他文件调用的。也正是如此,在链接时,文件之间的static变量不会相互冲突。
细心的话我们会发现,假如在一个文件中定义一个全局变量num,其他文件中也定义的话会出现一个重定义错误。
//以下属于文件1
#include"head.h"
int num = 0;
//以下属于文件2
#include"head.h"
int num = 2;
int main()
{
//func2();
cout << "文件2中num初始化值:" << num << endl;
cout << "文件2中num地址:" << &num << endl;
return 0;
}
这就是因为在汇编时,两个文件中的num都进入符号表。导致链接时发生了冲突。这时用static就能解决。
“代码胜于雄辩。”——林纳斯·托瓦兹(Linus Torvalds,Linux之父)
如有错误,敬请斧正