c/c++全局变量在多个源文件中的使用

来源:互联网 发布:中软博通软件 上海 编辑:程序博客网 时间:2024/05/16 01:08

转载 :http://blog.sina.com.cn/s/blog_74a459380101rjh4.html
转载 :http://blog.csdn.net/jiadebin890724/article/details/40509333

例子:

头文件:state.h 源文件:state.cpp

其它源文件:t1.cpp t2.cpp t3.cpp, 这些源文件都包含头文件state.h。

需要定义一个全局变量供这些源文件中使用:方法如下

1、在 state.h声明全局变量: extern int a;

2、在state.cpp中定义该全局变量:int a = 10;

这样其它源文件就可以使用该变量啦

这里需要的是“声明”,不是“定义”!根据C++标准的规定,一个变量声明必须同时满足两个条件,否则就是定义:
(1)声明必须使用extern关键字;(2)不能给变量赋初值
extern int a; //声明

int a; //定义

int a = 0; //定义

extern int a =0; //定义

  头文件中应使用extern 关键字声明全局变量(不定义),如果这个变量有多个文件用到,可以新建一个cpp,在其中定义,把这个cpp加入工程即可。头文件请不要定义任何变量,那是非常业余的行为……一般在头文件中申明,用extern, 在cpp中定义。 如果在头文件中定义,如果这个头文件被多个cpp引用,会造成重复定义的链接错误。头文件只能申明全局变量(extern),不可定义(不推荐使用)     .cpp里,在最外层定义即可(int gi),直接引用

如果在.cpp里使用static定义,则该变量只在当前cpp文件中有效,在别的文件中无效
在.h里使用static定义,不会进行编译(.h文件不编译),只会在其每个include的cpp文件中包含编译,相当于在.cpp里使用static 定义。

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

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

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

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

[cpp] view plain copy
print?在CODE上查看代码片派生到我的代码片

#include "def.h"  #include  <iostream>  using namespace std;  int main()  {      cout<<var<<endl;      return 0;  }  

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

[cpp] view plain copy
print?在CODE上查看代码片派生到我的代码片

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

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

[cpp] view plain copy
print?在CODE上查看代码片派生到我的代码片

#ifndef  _DEF_H  #define _DEF_H  extern int var;  #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函数的头文件;

[cpp] view plain copy
print?在CODE上查看代码片派生到我的代码片

static  int  snum=22;  static  int  sme;  void fun();  

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

[cpp] view plain copy
print?在CODE上查看代码片派生到我的代码片

#include "def.h"  #include  <iostream>  using namespace std;  void fun()  {      snum=33;      sme=3;      cout<<snum<<", "<<sme<<endl;  }  

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

[cpp] view plain copy
print?在CODE上查看代码片派生到我的代码片

#include "def.h"  #include <iostream>  using namespace std;  void fun2()  {      cout<<snum<<", "<<sme<<endl;  }  

main.cc:执行入口;

[cpp] view plain copy
print?在CODE上查看代码片派生到我的代码片

#include "def.h"  #include "mod.h"  #include <iostream>  using namespace std;  int main()  {      cout<<snum<<", "<<sme<<endl;      fun();      fun2();  }  

输出结果:

22,0

33,3

22,0

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

注意:

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

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

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

0 0