【四圣龙神录的编程教室】第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
- 【四圣龙神录的编程教室】第5章、研究下声明的方法吧
- 【四圣龙神录的编程教室】第2章、首先运行下看看吧
- 【四圣龙神录的编程教室】第0章 开始
- 【四圣龙神录的编程教室】
- 【四圣龙神录的编程教室】第6章、定制一下主循环里的调用函数吧
- 【四圣龙神录的编程教室】第9章、试试操作人物的移动吧
- 【四圣龙神录的编程教室】第11章、用Excel制作敌人的登场数据吧
- 【四圣龙神录的编程教室】第12章、来制作大量敌人的行动模式吧
- 【四圣龙神录的编程教室】第14章、来制作各种各样的弹幕数据吧
- 【四圣龙神录的编程教室】第15章、来制作凹梦的弹幕吧
- 【四圣龙神录的编程教室】第16章、来制作洩矢大人的弹幕吧
- 【四圣龙神录的编程教室】第18章、给自机的子弹加上碰撞检测吧
- 【四圣龙神录的编程教室】第3章、使用全局变量看看吧
- 【四圣龙神录的编程教室】第4章、画个自机形象看看吧
- 【四圣龙神录的编程教室】第7章、把面板表示出来吧
- 【四圣龙神录的编程教室】第10章、把敌人表示出来看看吧
- 【四圣龙神录的编程教室】第13章、给敌人加上射击功能吧
- 【四圣龙神录的编程教室】第17章、让自机可以发射子弹吧
- 一个简易的8位计算器,可实现加减乘除,testbench写的较为简易,代码覆盖率有点低。方法比较笨,综合之后的频率不高。
- 该死的servlet,为什么我重定向不了
- java awt简单示例1
- R 语言画图的基本参数
- eclipse单独下载sdk api
- 【四圣龙神录的编程教室】第5章、研究下声明的方法吧
- 在android源码framework里添加的资源文件!
- 静态链表
- R语言-Knitr包的详细使用说明
- hdu oj 2012
- codeforce B. Road Construction
- Apache Drill: 大数据集互动分析的分布式框架
- 使用PL/SQL Developer连接oracle数据库报“无法解析指定的连接标识符”错误
- 关于spring+hibernate的FlushMode的记录