本文主要通过实践,总结出extern关键字的作用。
全局变量
extern只是声明了变量,并未定义变量,即没对变量分配内存空间。如下例子,我只编译main.cpp:
main.cpp:
#include<iostream>
using namespace std;
extern int i;
int main() {
++i;
cout << "i: " << i << endl;
return 0;
}
编译:g++ main.cpp -o run
会报错未定义i
。
那么在other.cpp中定义i
,在编译时加上other.cpp呢?
other.cpp:
int i = 3;
编译:g++ main.cpp other.cpp -o run
执行:
编译和执行都是ok的。
既然i
的定义可以在其他源文件,那么可不可以在当前源文件末尾呢?
main.cpp:在末尾加上int i = 3;
#include<iostream>
using namespace std;
extern int i;
int main() {
++i;
cout << "i: " << i << endl;
return 0;
}
int i = 3;
编译执行:
看来extern是让编译器去其他地方(其他源文件,本源文件的其他行)寻找定义。
那么extern关键字是必须的吗?
回到包含main.cpp和other.cpp的案例,试着把extern去掉,再编译:
报错显示重复定义了。因此在去掉extern之后,即int i
也是定义。
顺着这个思路,那把other.cpp去掉,int i
就满足定义的需求了,是不是main.cpp自己就能编译了?
只编译main.cpp:
ok,编译执行都没问题,看来int i
是定义了变量i
,并默认赋值为0。
因此,extern的作用一是:在当前源文件中声明全局变量,告知编译器,这个变量的定义在其他地方(其他源文件,或本源文件的其他行)。
看了下网上一些案例,extern通常是在other.h中声明,再由main.cpp中include “other.h”。
函数
extern之于函数的用处又如何呢。
demo中有main.cpp、other.h、other.cpp:
main.cpp:
#include<iostream>
#include "other.h"
using namespace std;
int main() {
int i = GetValue();
cout << "i: " << i << endl;
return 0;
}
other.h:
extern int GetValue();
other.cpp:
int GetValue()
{
return 3;
}
编译和执行时没问题的:
那么去掉extern呢?
在other.h去掉extern之后,编译和执行也是没问题的:
还记得上面全局变量的案例中,去掉extern之后,就会报错重复定义变量i
。
那是因为变量在无extern时声明默认会分配内存(定义),而函数声明则只是声明,只要无函数体就不是定义。
因此函数声明去掉extern之后,并没有重复定义的问题(仍然是声明)。
综合以上,其实extern的作用就是强制表达式作为声明,而并不进行定义。
其他概念
extern “C”
extern “C”,用于在C++中调用C语言的函数。截图自博客:
extern数组
参考自博客(这个博客写得也比较全面):