【四圣龙神录的编程教室】第5章、研究下声明的方法吧

来源:互联网 发布:学校奖学金算法 编辑:程序博客网 时间:2024/04/30 16:31

原文地址:

http://dixq.net/rp/5.html


在上一节,main文件已经乱作一团,这有个变量定义,那又有个extern什么的,已经有点看不懂了。

于是,我们来研究一下变量定义和extern 声明的方法吧。

等等,在这先对上一章做一下概括吧。

・(这次设计的场景)全局变量,定义在主文件 main.cpp 里面了

・ 从其他的文件引用这里的全局变量的时候,在其他文件里要用extern声明。

就是酱紫呢。

但是,在主文件里定义,然后在其他文件里使用extern调用同样的变量时,感觉是个效率比较低的方法。

那么,我们在所有文件里都调用同一个头文件,在这个头文件里面,

根据在哪里被调用写个条件分支,然后给出适当的声明。如果这样做的话,效率就比较高了。

稍微看一下下面这段程序吧。

——————————————————————————————————————————————————————

#ifdef GLOBAL_INSTANCE


#define GLOBAL


#else


#define GLOBAL extern 


#endif


GLOBAL int img;

————————————————————————————————————————————————————————

(以下这段翻译里的“调用”,指的是GLOBAL int img; 这行代码被预处理后实际变成的样子。也就是说,这个“调用”指的是预处理操作)

这段代码的含义是,

如果定义了GLOBAL_INSTANCE的话,GLOBAL就被替换成空白

如果没有定义GLOBAL_INSTANCE的话,GLOBAL就被替换成extern

然后,我们这样写

GLOBAL int img;

会怎么样呢?是的,这样的话,用和不用extern, 就被区分开了。

因为从main.cpp调用的时候,必须是定义,所以不加extern 。

也就是说,定义了GLOBAL_INSTANCE之后,调用就很方便了。(自动去掉GLOBAL)

另一方面,从其他文件调用这个img全局变量,我们得加上extern。

也就是说,不定义GLOBAL_INSTANCE,也啥都不用写,很方便。(自动会把GLOBAL变成extern)

这里我们看一下main 文件的最上面吧。那里写着

#define GLOBAL_INSTANCE 
#include "../include/GV.h"

这里定义了GLOBAL_INSTANCE,调用的时候,就是对变量的定义。

其他文件没有定义这个,调用的时候,就会加上extern.

这样,就实现了从其他文件来调用main里定义的全局变量的方式。


这样的话还有一点。已经实现的函数被其他文件调用的时候,同样也需要在main文件里声明一次。

声明了extern的话,在程序实现的地方和调用的地方都有好处。

在main文件里只要用extern声明了,不管在哪里实现的,可以调用到。(此处翻译有点不够到位,求指正)

然后,在根据不同的条件,在 GV.h 的引入 function.h也用上述同样的GLOBAL来声明看看吧。

其实,看了就应该很容易明白了,像下面这样添加上去吧。

————————————————————————————————————————————————————————

//--function.h改动--//graph.cpp        //描画 main        GLOBAL void graph_main();//key.cpp        //现在的键位输入状态        GLOBAL int GetHitKeyStateAll_2();        //根据键的序号,返回输入的状态        GLOBAL int CheckStateKey(unsigned char Handle);//laod.cpp        //数据载入        GLOBAL void load();
————————————————————————————————————————————————————————


————————————————————————————————————————————————————————

//--GV.h改动--#include "../../../include/DxLib.h"#include "define.h"#ifdef GLOBAL_INSTANCE#define GLOBAL#else#define GLOBAL extern #endif#include "function.h"           //函数声明//图片变量声明GLOBAL int img_ch[2][12];       //自机的图片9张 X2(变身用)//构造体变量声明GLOBAL ch_t ch;                 //构造体数据声明
————————————————————————————————————————————————————————


然后在「main.cpp」「graph.cpp」「load.cpp」的在这些变量的定义部分,把extern 都去掉。

编译一下,如果没有错误,结果和第四节一样的话,就OK了。

以后,添加全局变量,就往GV.h  里面添加,

需要在 main 文件调用,在其他文件声明的方法,就往 function.h 里面添加吧。


(注:看得出来,这章主要是总结集中了全局变量和方法的声明和调用的方法。熟悉C/C++的应该很容易懂吧)

(我是还没怎么看明白,所以有些地方翻译的没能很好表达清楚意思。等我把第四章和第五章的程序改动读一遍,再来这修改一下吧)

研究了一下项目预处理之后的文件,大概推断出了#include 和上面 #ifnef  这些的作用了。

首先我们理一下这一章和上一章的变动。

原先,是在main 里面定义了两个全局变量。然后用extern 声明需要写在其他文件里面的函数。

同时,其他文件要调用main里定义的全局变量也要加extern。弄得很乱。

(补充一点关于extern,其实main里调用其他函数时写的声明,可以去掉extern的。

但其他文件用extern声明main里面定义的,这个extern不能去掉,不然就重复定义了)

修改后, 

GV.h 加上ifndef 判断,然后,函数声明都加上GLOBAL放到 function.h 里面,include 到GV.h中。全局变量也加上GLOBAL,在GV.h里声明。

相当于,所有函数和全局变量,都加上GLOBAL声明,放在GV.h里面。

其他文件包含GV.h了,就可以去掉对 全局变量单独写引用声明了。

然后,

由于main.cpp定义了GLOBAL_INSTANCE , 预处理的时候,GV.h全部包含进来后,会去掉extern。这样,变量就变成定义,函数去掉extern也还是声明。

其他文件没有定义GLOBAL_INSTANCE ,预处理GV.h全部包含进来后,会保留extern。这样就 声明了定义在别处的 全局变量和函数。


本人CSDN博客目录:

http://blog.csdn.net/tidus5