相信看到文章的题目,大家可能会疑惑扫雷小游戏和“全局变量能在头文件中定义吗?”这个问题有什么关系呢?实不相瞒,在我被这小小的问题恶心的不停更换编译器,反复调试代码之前,我也没想到这两者之间能有什么关系。😭😭😭
目录
先简单介绍一下主角——全局变量。
每个变量都有属于它的作用域,就是这些变量在什么范围内有效;?我们按照变量的作用域范围可以把变量划分为局部变量和全局变量。
一个源文件中可以包含若干个函数(main函数和各种自定义函数),在函数外部定义的变量就是全局变量或外部变量,全局变量为该源文件中所有函数所共有,它的作用范围是从变量定义的位置到源文件结束;
特别注意:
①全局变量在程序的整个执行过程中都占据着内存单元,而不是仅仅在使用时才开辟存储单元,换句话说,全局变量在整个程序运行过程中都存在,只有程序结束才释放所占据的内存单元;
②设置全局变量的目的是为了增加函数间数据联系的渠道,由于同一个源文件中的所有函数都可以引用全局变量,所以在任意函数中改变全局变量的值,这就会影响到其他函数中全局变量的值,也就是说所有函数中的同一全局变量占用同一块地址;
当我在创作上面这篇文章时遇见了这样的问题,如下图所示:
我当时眉头一皱,百思不得其解,我明明只在头文件中定义了一个全局变量win,为什么会显示win已经在SaoLei.obj中定义并且找到一个或多个多重定义的符号,它到底凭什么多重定义啊?谁又偷偷定义它了?(鬼知道本来在DevC写代码的我,一直运行不成功,调试了多久,掉了多少头发😭,结果VS告诉我win重定义。。。。。。)那么,这到底是什么情况?和我们文章的标题又有什么关系呢?
当我反复调试代码后,突发奇想把全局变量定义在使用它的源文件中,发现问题突然就解决了。如下图所示:
于是,我就开始思考为什么全局变量在头文件中定义会出现重定义的问题,但是源文件中定义就不会出现这种情况呢。然后,我发现问题在于,如果我在头文件中定义全局变量,那么因为不止一个源文件包含头文件,所以就会同时定义多个一样的全局变量,造成冲突。(具体体现就是编译器会提醒你有变量重定义)所以,在头文件中是不能直接定义全局变量的。
上面说了那么多,那么我们以后想定义全局变量该怎么办呢?
①如果我们在程序中只有一个源文件要使用全局变量,那么直接在该源文件中定义全局变量即可。
②如果我们在程序中有1个或多个源文件要使用全局变量(多个源文件使用的全局变量并不相通),那么我们可以在头文件定义全局变量,不过在全局变量前要加static修饰,确保各源文件该全局变量各不相通。(其实只是一个源文件要用,没必要这样,这样之所以不报错,因为编译器默认它们不一样。)比如扫雷中如下图这样改,就能运行:
③如果我们的工程中多个源文件需要这个全局变量,那么你就任找一个源文件,把这个全局变量定义到这个源文件中,然后新建一个头文件,在里面进行“extern?这个变量”的声明,最后在需要使用这个全局变量的源文件中include你新建的头文件就可以了。