简要介绍C/C++中的两个extern

C语言中有一个extern,C++中也有一个extern,两者是不同的。

首先C语言中的extern

先补充一个知识点:C语言中是单文件编译的,即先单个文件自上而下完成编译,然后再将编译得到的.o文件同库文件一起链接成可执行文件(源文件到可执行文件的四个阶段:预处理,编译,汇编,链接)。

当一个工程中有多个文件时(多文件编程),要使用全局变量,往往需要使用extern修饰声明。

全局变量本身是全局可用的,即在所有的.c文件中均可以使用,但因为C语言是单文件编译的,在main.c文件中使用other.c文件中声明的全局变量必须前加extern修饰,形如:other.c中定义的int a = 100; main.c中使用要extern int a; 后一句旨在告诉编译器该变量在其他文件中已经定义,以通过编译。

所以extern存在的意义在于解决多文件编程中跨文件使用全局变量编译不能通过的问题。

注意:1.extern只能修饰全局变量,不能修饰局部变量,因为extern本身就是解决全局变量使用中存在的问题;

           2.main.c中使用other.c中定义的全局变量,使用extern修饰声明,不能再初始化,只是声明;

          3.main.c中extern int a;只是保证编译通过,而在链接阶段要去找这个a,如果other.c中真的定义了a则链接成功,否则链接失败,会报错。

然后C++中的extern

C++中的extern要简单一些,准确说是extern "C"。

我们知道C++是完全兼容C语言的,就意味着完全兼容C的标准库及自制库。那如何实现呢?就是通过extern "C"。

C++中默认在预处理阶段对所有函数名采用Name Mangling(命名倾轧),来改变函数名,以此区分参数不同的同名函数。

对于一个函数来说,它的声明和定义要么都倾轧,要么都不倾轧,否则在链接阶段就会出现错误。

我们在C++中使用C的标准库或者自制库(不存在命名倾轧)时,要保证其对应的头文件或者函数声明不参与命名倾轧,否则链接失败。如果是单个函数声明,则在前面加上extern "C"就能避免倾轧,如果是多个,则extern "C"{ }。如果在C++中包含C库对应的头文件则是:extern "C" { #include "xxx.h" },我们知道头文件中全是函数声明。

总之,C库是不存在命名倾轧的,C++使用C库时,要让对应的函数声明或者整个头文件避免命名倾轧,就要加extern "C"。

PS:本人还是C/C++领域中的学徒,内功不够深厚,即使对于一些个简单的知识点表达的也不是很全面,难免有疏漏之处,还请读者朋友见谅,提出改进意见。希望能和更多喜欢C/C++技术的朋友交流!

发布了34 篇原创文章 · 获赞 22 · 访问量 7201

猜你喜欢

转载自blog.csdn.net/lizun7852/article/details/86775922