c++中extern的用法

一、一般用法:

    extern表示声明一个在其他地方定义过的全局变量。如果想声明一个变量而不是定义它,就在变量名前添加extern。                   

extern int i;//声明而非定义

int i;//定义

extern int i=0;//定义

         如果想要在多个文件中使用同一个变量,得必须将变量的声明和定义相分离,变量的定义出现且只能出现在其中一个文件当中,而其他用到该变量的文件则必须对其进行声明,不可再重复定义。即extern int f(); 和int f();没有区别。

    如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。


二、extern关键字:
    extern关键字看起来更像static的反义词,extern有两个作用一是它将后面的变量名指明是外部链接的,比如const和typedef在默认情况下都是内部链接(静态链接)的(c++primer解释为:默认情况下,一个const对象仅在本文件内有效,我们用extern去修饰可让它变成外部链接,让其他程序文件可见。二是用extern修饰后的变量名可表示为一个变量声明,且仅仅是声明,它的定义和声明不在一起,可能是在别的文件中已经定义了该变量,我们在本文件中使用extern声明仅仅是告诉编译器,我们有这么个名字的变量要用到,它的定义来自于别的源文件(而不是头文件)中。                     

三、辨 析:

        1、声明与定义的区别:为了支持分离式编译,c++语言将声明与定义分开来。声明使得名字为程序所知,可以被多次声明(类成员函数、静态数据成员不能重复声明);而定义负责创建与名字相关联的实体(类型、实例、函数),即给变量申请存储空间(还可能给变量赋予一个初始值),在同一作用域内不可重复定义一个实体。

    2、static和extern的区别: (1) extern 表明该变量在别的地方已经定义过了,在这里要使用那个变量; (2) static 表示静态的变量,分配内存的时候, 存储在静态区,不存储在栈上面。static 作用范围是内部连接的关系, 和extern有点相反。它和对象本身是分开存储的,extern也是分开存储的,但是extern可以被其他的对象用extern 引用,而static 不可以,只允许对象本身用它。 具体差别首先,static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变;其次,static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它。

    3、extern和const的关系:C++中const修饰的全局常量具有跟static相同的特性,即它们只能作用于本编译模块中,但是const可以与extern连用来声明该常量可以作用于其他编译模块中, 如extern const char g_str[];所以当const单独使用时它就与static相同,而当与extern一起合作的时候,它的特性就跟extern的一样了!

四、注意事项:

        1、在函数内部,如果试图初始化一个由extern关键字标记的变量,将引发错误。                

        2、 extern 变量在一个源文件里定义了一个数组:char a[6];在另外一个文件里用下列语句进行了声明:extern char *a;请问,这样可以吗?

   1)、不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]。

  2)、例子分析如下,如果a[] = "abcd",则外部变量a=0x61626364 (abcd的ASCII码值),*a显然没有意义

  显然a指向的空间(0x61626364)没有意义,易出现非法内存访问。

  3)、这提示我们,在使用extern时候要严格对应声明时的格式,在实际编程中,这样的错误屡见不鲜。

  4)、extern用在变量声明中常常有这样一个作用,你在*.c文件中声明了一个全局的变量,这个全局的变量如果要被引用,就放在*.h中并用extern来声明。

    3、三种定义方法:    

    1)只需要在某一个.cpp中定义,在使用的地方,extern声明即可。【可以。但如果变量很多,就会有很多个extern声明。

    2)头文件中定义。【不可以。易产生重复定义。】

    3)在某一个.cpp中定义,在头文件中声明,在使用的地方,包含头文件。【建议采纳。】

4、 注意 extern声明可以使用来自于别的 源文件(而不是头文件)中定义 的变量。在头文件中,在不包含它的文件中是不可调用的,即使声明了extern 也于事无补。
// 1.cpp 
int x = 10; 
// 2.cpp 注意没有包含1.cpp 
#include <iostream> 
using namespace std; 
extern int x;
int main () 
{ cout << x << endl; } 
//则输出10 
两个文件同在一个项目(project)中,你不包含某个文件(cpp)而可以用它内部定义的变量(这里是.cpp而不是.h, 因为在.h中定义的数据不能在.cpp中用除非这个.cpp包含这个.h文件)。 
例: 
// 1.h 
#include <iostream> 
void print() 

std::cout << "hello!" << std::endl; 

// 2.cpp 
#include <iostream> 
using namespace std; 
// 以上两句在这个例子中可以不要 
extern void print(); 
int main () 

print(); 

就会出错因为1.h中的void print();在不包含它的文件中是不可调用的,即使在声明了extern 也于事无补,如果你将这个例子中的1.h名字换成1.cpp就对了! 
从这些可以看出来,extern在这里起的作用是告诉编译器,你这个print()已经在某个.cpp中已经定义了,这里只不过是声明一下有这个东西,然后拿来用一下。定义只能出现一次,声明却可出现多次,也就是说extern声明可在多个文件中用(包括.h) 。
还有,你还可以屏蔽extern声明,如第二个例子中的第二个.cpp文件可以改成 
#include <iostream> 
using namespace std; 
// 这里以上两句不能省略,因为,这里extern void print();函数已经不起作用了,在这里调用的是本文件中定义的void print()函数,其中用到了cout,endl;他们来源于std::<iostream> 
extern void print(); 
void print() 

cout << "world!" << endl; 

int main () 

print(); 

// 输出结果为world!
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值