一、原因(附参考链接)
①外部链接性
首先明确一点全局变量是具备 外部链接性的,何为外部连接性呢?外部链接性的变量通常简称为外部变量,作用域为整个文件。可以在文件中位于外部变量定义的后面的任意函数中使用它,因此也称为全局变量。
②头文件的作用
当.c
或者.cpp
引用头文件的时候,无非是将头文件的内容拷贝入本.c
或者.cpp
。当我们在头文件中定义一个全局变量,而又在多个.c
或者.cpp
文件中引用它,就会引发全局变量重定义。话不多说看图:本图中B.cpp
和C.cpp
都引用了a.h
等价于在B.cpp
和C.cpp
中都声明了全局变量。而全局变量的作用域是整个文件,故而出现了全局变量重定义的问题。
③回顾static
关键字
不多说,直接参考人家的文章:文章链接
二、解决办法
2.1 定义和声明
①变量声明和变量定义
变量定义: 用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。
变量声明: 用于向程序表明变量的类型和名字。
[注意]
变量在使用前就要被定义或者声明。
在一个程序中,变量只能定义一次,却可以声明多次。
定义分配存储空间,而声明不会。
C++程序通常由许多文件组成,为了让多个文件访问相同的变量,C++区分了声明和定义。
2.2 区分定义和声明
①.extern
告诉编译器变量在其他地方定义了。
extern int i;//声明不是定义
int i;//定义
②如果声明有初始化式,就被当作定义,即使前面加了extern
。
只有当extern
声明位于函数外部时,才可以被初始化。
extern double pi=3.1415926;//定义
③函数的声明和定义
函数的声明和定义区别比较简单,带有{ }
的就是定义,否则就是声明。
extern int fun();//声明
int fun()//定义
{
}
④除非有extern
关键字,否则都是变量的定义。
extern int i;//声明
int i;//定义
三、经验
1.永远不要在.h
文件中定义变量,这样容易导致重复定义错误。
2.尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全局的。
3.可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量。
4.头文件(.h)
中 是对于该模块接口的声明,接口包括该模块提供给其它模块调用的外部函数及外部全局变量,对这些变量和函数都需在.h
中文件中冠以extern
关键字声明。