extern是一种“外部声明”的关键字,字面意思就是在此处声明某种变量或函数,在外部定义。
下面的示意图是我的理解。
extern关键字的主要作用是扩大变量/函数的作用域,使得其它源文件和头文件可以复用同样的变量/函数,也起到类似“分块储存”的作用,划分代码。如图所示,在一个头文件里做了外部声明,就能把变量的定义部分和函数体的实现部分转移到其它地方了。
extern声明的格式如下,只是在变量声明时前面加上个”extern“:
extern int a; extern double b; extern const struct box *box_ptr extern double box_volume(box box_ptr)
下面是个例子,程序提示用户输入一个盒子的长宽高,存储在结构体内,然后用函数输出该盒子的体积,再用一个函数将盒子的三维长度扩大一倍,最后再次输出它的体积。
主函数:
//main.cpp #include<iostream> #include"box_manu.h" using namespace std; int main() { make_box(); //引导用户输入一个新盒子的的信息 cout << "Volume of this box:" << box_volume(new_box) << endl; //输出该盒子的体积 bigger_box(); //把该盒子的三维加一倍 cout << "done. "; cout << "Bigger volume:" << box_volume(new_box) << endl; //输出改造后的体积 system("pause"); }
Extra.h里定义了box的结构体,做了相关变量和函数的外部声明。
//extra.h struct box { double length; double width; double height; double volume; }; extern const struct box * box_ptr; extern box new_box; extern double box_length; extern double box_width; extern double box_height; extern double box_volume(box box_ptr); extern void make_box();
box_make.cpp里定义了box结构类型的new_box变量,以及长宽高,但没赋值。给出了输出体积和提示输入的函数的原型。
//box_make.cpp #include<iostream> #include"Extra.h" using namespace std; box new_box; double box_volume(box box_ptr) { box_ptr.volume = box_ptr.height*box_ptr.length*box_ptr.width; return box_ptr.volume; } double box_length; double box_width; double box_height; void make_box() { cout << "Input length for the box:"; cin >> box_length; new_box.length = box_length; cout << "Input width for the box:"; cin >> box_width; new_box.width = box_width; cout << "Input height for the box:"; cin >> box_height; new_box.height = box_height; }
box_manu.h给出了扩大盒子三维的函数原型,并被main.cpp包括。
//box_manu.h #include<iostream> #include"Extra.h"
void bigger_box() { new_box.length = 2 * new_box.length; new_box.height = 2 * new_box.height; new_box.width = 2 * new_box.width; }
程序运行结果:
Input length for the box:2 [enter]
Input width for the box:2 [enter]
Input height for the box:2 [enter]
Volume of this box:8
done.
Bigger volume:64
值得注意的问题:
1.主函数include的box_manu.h已经include了Extra.h,如果再include一遍Extra.h。会报大量不兼容和重定义等错,应尽力避免重复引用头文件。
2.在extra.h里面声明的长宽高变量必须要在其它哪里给出定义,哪怕没有初值(例子中写到了box_make.cpp里面)。如果没有这么做,编译时会报LNK200“无法解析外部命令”的错。
3.多个头文件或源文件使用同一些变量,尝试把extern去掉后编译就会报“重定义”的错。