C语言的extern声明辨析
副标题#e#
1 根基表明
extern可以置于变量可能函数前,以标示变量可能函数的界说在此外文件中,提示编译器碰着此变量和函数时在其他模块中寻找其界说。
别的,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 问题:extern 函数1
经常见extern放在函数的前面成为函数声明的一部门,那么,C语言的要害字extern在函数的声明中起什么浸染?
谜底与阐明:
假如函数的声明中带有要害字extern,仅仅是体现这个函数大概在此外源文件里界说,没有其它浸染。即下述两个函数声明没有明明的区别:
extern int f(); 和int f();
虽然,这样的用处照旧有的,就是在措施中代替include “*.h”来声明函数,在一些巨大的项目中,我较量习惯在所有的函数声明前添加extern修饰。
#p#副标题#e#
4 问题:extern 函数2
当函数提供方片面修改函数原型时,假如利用方不知情继承沿用本来的extern申明,这样编译时编译器不会报错。可是在运行进程中,因为少了可能多了输入参数,往往会照成系统错误,这种环境应该如何办理?
谜底与阐明:
今朝业界针对这种环境的处理惩罚没有一个很完美的方案,凡是的做法是提供方在本身的xxx_pub.h中提供对外部接口的声明,然后挪用方include该头文件,从而省去extern这一步。以制止这种错误。
宝剑有双锋,对extern的应用,差异的场所应该选择差异的做法。
5 问题:extern “C”
在C++情况下利用C函数的时候,经常会呈现编译器无法找到obj模块中的C函数界说,从而导致链接失败的环境,应该如何办理这种环境呢?
谜底与阐明:
C++语言在编译的时候为了办理函数的多态问题,会将函数名和参数连系起来生成一其中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的环境,此时C函数就需要用extern “C”举办链接指定,这汇报编译器,请保持我的名称,不要给我生成用于链接的中间函数名。
下面是一个尺度的写法:
//在.h文件的头上
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */
…
…
//.h文件竣事的处所
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */