extern是计算机语言中的一个关键字,可置于变量或者函数前,以表示变量或者函数的定义在别的文件中。提示编译器遇到此变量或函数时,在其它模块中寻找其定义,另外,extern也可用来进行链接指定。
1声明变量
声明extern关键字的全局变量可以使得它们能够跨文件被访问。一般我们把所有的全局变量放在.cpp文件中,然后用与之同名的.h文件把需要在其他文件使用的全局变量和全局函数用extern加以声明。
Fibonacci.h
/*Fibonacci.h*/
#pragma once
extern int num;
Fibonacci.cpp
/*Fibonacci.cpp*/
int num=0;
int fac(int n)
{
num+=1;
if(n<=2)
return 1;
else
return fac(n-1)+fac(n-2);
}
main.cpp
void main()
{
printf("%d \n",fac(10));
}
extern int a; //属于声明 extern int a = 10; //属于定义,同下
extern char g_str[]=”123456”; //这个时候相当于没有extern
如果在一个文件里定义了char g_str[] = "123456";在另外一个文件中必须使用extern char g_str[ ];来声明。
不能使用extern char* g_str;来声明。extern是严格的声明。且extern char* g_str只是声明的一个全局字符指针。
注:声明可以拷贝n次,但是定义只能定义一次。
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 */**
extern “C” 包含两个含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。让我们来详细解读这含义。
被extern "C"限定的函数或变量是extern类型的;
extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用,下列语句:
extern int a;
仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。
引用一个定义在其它模块的全局变量或函数(如,全局函数或变量定义在A模块,B欲引用)有两种方法,
一、B模块中include模块A的头文件。
二、模块B中对欲引用的模块A的变量或函数重新声明一遍,并前加extern关键字。
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数。
与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。
被extern "C"修饰的变量和函数是按照C语言方式编译和连接的;
extern和const
const可以与extern连用来声明该常量可以作用于其他编译模块中,
在.h文件中
extern const int ar[10];
在实现文件.cpp中也要
extern const int ar[10]={1,2,3,4,5};
这样才能在main.cpp中使用