在比较大的项目中,如果需要使用全局变量,那么就需要注意一些全局变量声明、使用不当引起的问题了。

本篇文章主要内容有两个:普通全局变量、静态全局变量、全局常量。

1、普通全局变量:假设我们需要在多个不同的编译单元(比如两个.cc文件)中使用全局变量进行传值,如我们有如下三个源码文件:

main.cc:运行入口,有一个main函数,其中会打印出全局变量var的值;

  1. #include "def.h"
  2. #include  <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. cout<<var<<endl;
  7. return 0;
  8. }

def.cc:全局变量var的定义处;

  1. #include  "def.h"
  2. int var;    //可以赋初值,也可以这样

def.h: 全局变量var的声明处;

  1. #ifndef  _DEF_H
  2. #define _DEF_H
  3. extern int var;
  4. #endif

注意:

在linux里编译的时候def.cc和main.cc都要编译(我自己写的时候就是忘记编译def.cc了,傻傻的发现main.cc编译出错。。。);

在.h中用extern声明全局变量,在某一个.cc文件中定义该全局变量,且在定义处包含声明的.h头文件,这样保证该全局变量在整体上只定义一次(否则如果在.ht头文件中定义的话,编译时会遇到多重定义错误),然后再使用全局变量的其他编译单元的.cc文件中,只需包含该.h头文件即可;

extern 声明表示在此处引入外部定义变量的声明,而不是在本编译单元中再声明一个同名的局部变量;

2、静态全局变量:即使用static修饰的全局变量,他不能使用extern进行引入声明,即extern与static不可以一起使用;而且static全局变量与普通全局变量有很大不同,我们使用一个测试程序来说明;

def.h:定义static全局变量var以及fun函数的头文件;

  1. static  int  snum=22;
  2. static  int  sme;
  3. void fun();

def.cc:定义fun函数的源文件;

  1. #include "def.h"
  2. #include  <iostream>
  3. using namespace std;
  4. void fun()
  5. {
  6. snum=33;
  7. sme=3;
  8. cout<<snum<<", "<<sme<<endl;
  9. }

mod.h:输出全局变量值的另外一个头文件;

  1. #include "def.h"
  2. #include <iostream>
  3. using namespace std;
  4. void fun2()
  5. {
  6. cout<<snum<<", "<<sme<<endl;
  7. }

main.cc:执行入口;

  1. #include "def.h"
  2. #include "mod.h"
  3. #include <iostream>
  4. using namespace std;
  5. int main()
  6. {
  7. cout<<snum<<", "<<sme<<endl;
  8. fun();
  9. fun2();
  10. }

输出结果:

22,0

33,3

22,0

可以看出,调用了fun()之后,在fun2()中打印出来的值并没有改变,原因是:static修饰的全局变量的作用域只是其本身所在的编译单元(在本编译单元内更改生效),在其他单元中使用时,该变量会有新的内存地址,也就是说,每一个使用它的编译单元都给它开辟了单独的空间,并把它的初始值复制过来,这样如果某个单元中对它进行了修改,那么多个编译单元中它的值就可能不一样了;

注意:

static修饰的全局变量声明与定义是一体的,在头文件中声明了static全局变量,同时也是定义了它,不像普通的全局变量是分开的;

多个编译单元都包含static全局变量所在的头文件,不会引起重定义错误,因为每个编译单元都开辟了新的空间存储它;

3、const全局变量:const全局变量使用起来与普通全局变量一样,在.cc中定义并赋初值,在.h头文件中用extern进行声明,然后再需要使用的地方包含.h即可,在多个编译单元中其内存地址也不同(这一点与static全局变量类似),但是由于是常量,不能修改其值,所以即使内存地址不一样也没影响,值都一样。

参考致谢:http://blog.csdn.net/candyliuxj/article/details/7853938

最新文章

  1. 压缩javascript文件方法
  2. java第三周学习
  3. Sublime Text2 javascript格式化插件JsFormat
  4. Firemonkey 移动平台 Form 显示使用 ShowModal 范例
  5. 编写高质量JS代码的68个有效方法(二)
  6. android开发中的变量名称
  7. PHP判断客户端是PC web端还是移动手机端方法
  8. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.2.更换主题
  9. 用C语言简单加密解密
  10. MVC linq To SQL更新数据库操作
  11. 手把手教你使用 Imagepro plus - 宏操作【转】
  12. HTTP长连接实现“服务器推”的技术
  13. Linux概念架构的理解
  14. BZOJ2296: 【POJ Challenge】随机种子
  15. leetcode Binary Search Tree Iterator python
  16. EditText光标居上
  17. 2017/4/27-Gradle的配置与Spring的下载
  18. 多个activity跳转保留内存使用intent传递数据问题_新手
  19. 自己用的vim插件
  20. 12.k8s的存储卷创建过程

热门文章

  1. Oracle在Linux下使用异步IO(aio)配置
  2. xmpp4-总览
  3. hiho_1062_最近公共祖先
  4. java 多线程5(创建方式)
  5. [redis] 征服Redis系列
  6. PHP Warning: ob_start() : output handler &#39;ob_gzhandler conflicts with &#39;zlib output compression&#39;
  7. js打印图形
  8. windows下修改mysql用户名和密码
  9. Sql语句统计多表个数并求和
  10. Hadoop 添加删除数据节点(datanode)