cpp: extern的作用
转自:https://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html
1.基本
它是用来声明变量或者函数,说明在其他文件中被定义,那么链接时就在其他模块中寻找。
用来说明“此变量/函数是在别处定义的,要在此处引用”。
1.1 第一种用法
在头文件中用extern,将全局变量的声明和定义分开。
(1) 在test1.h中有下列声明:
#ifndef TEST1H #define TEST1H extern char g_str[]; // 用extern声明全局变量g_str void fun1(); #endif
(2) 在test1.cpp中
#include "test1.h" char g_str[] = "123456"; // 定义全局变量g_str void fun1() { cout << g_str << endl; }
(3) 以上是test1模块,如果还有test2模块也想使用g_str,只需要在原文件中引用就可以了:
#include "test1.h" void fun2() { cout << g_str << endl; }
这样的话g_str就是全局变量,一般这么来声明,而不能用static在头文件中声明+定义,那样会造成其他文件的污染。
如果在头文件中直接声明不加extern,那么多次包含head文件,就会产生重定义的错误。
1.2 第二种用法
在头文件中用extern声明+定义,在cpp文件中用extern。
(1)test1.h文件:
extern char g_str[] = "123456"; // 这个时候相当于没有extern
test1.cpp中的g_str定义需要去掉,
(2) test2.cpp
//#include "test1.h" //需要去掉这个,不能包含test1.h文件 extern char g_str[]; void fun2() { cout << g_str << endl; }
此时编译器就知道g_str是引自于外部的一个编译模块,不会在本模块中再重复定义一个出来。但无法在test2.cpp中使用#include "test1.h",那么test1.h中声明的其他函数你也无法使用了,除非也用都用extern修饰。所以最好使用第一种方法,在头文件中只声明即可。
2.定义与声明
1.定义也是声明,extern声明不是定义,即不分配存储空间。extern告诉编译器变量在其他地方定义了。
extern int i; //声明,不是定义 int i; //声明,也是定义
2.如果声明有初始化式,就被当作定义,即使前面加了extern。只有当extern声明位于函数外部时,才可以被初始化。
extern double pi=3.1416; //定义
3.函数的声明和定义区别比较简单,带有{}的就是定义,否则就是声明。
extern double max(double d1,double d2); //声明 double max(double d1,double d2){}//定义
4.除非有extern关键字,否则都是变量的定义。
extern int i; //声明 int i; //定义
4.总结
1. 不要把变量定义放入.h文件,这样容易导致重复定义错误。
2. 尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全局的。(static修饰的变量作用域就是当前文件)
3. 可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量。