extern用在变量或函数的声明前,用来讲明“此变量/函数是在别处定义的,要在此处引用”。函数
extern修饰变量的声明。post
举例:若a.c中需引用b.c中的变量int v,能够在a.c中声明extern int v,而后就能够引用变量v;须要注意的是,被引用的变量v的连接属性必须是外spa
连接(external)的,也就是说a.c要引用到变量v,不仅是取决于在a.c中声明extern int v,还取决于变量v自己是可以被引用到。这里涉及到另一个话指针
题---变量的做用域。可以被其余模块以extern引用到的变量一般是全局变量。code
extern int v能够放在a.c中的任何地方,好比能够在a.c中函数func()定义的开头处声明extern int v,而后就能够引用到变量v了,blog
只不过这样只能在func()做用域中引用变量v。作用域
另一点要说明的是在b.c中须要对int v 作什么处理吗?那就是不能定义成静态变量static int v,不然不能使用。原型
fileb.cit
static int A;io
int main()
{
...
}
filea.c
extern A;
{
A = A*n; //出错
}
另外有人会有疑问为何不在b.v文件中声明extern A;这样能够表示出A的特殊性,仔细想一想真的不须要。
extern修饰函数的声明。
本质上讲,变量和函数没有区别。函数名是指向函数二进制块开头处的指针。若是文件a.c要引用b.c中的函数,好比在b.c中原型是int func(int m),那么就能够在a.c中声明extern int func(int m),而后就能使用func()来作任何事情。就像变量的声明同样,extern int func(int m)能够放在a.c中的任何位置,而不必定非要放在a.c的文件做用域的范围中,
对其余模块中函数的引用,最经常使用的方法是包含这些函数声明的头文件。使用extern和包含头文件来引用函数的区别:extern的引用方式比包含头文件要间接得多。extern的使用方法是直接了当的,想引用哪一个函数就用extern声明哪一个函数。这大概是kiss原则的一种体现。这样作的一个明显的好处是,会加速程序的编译(确切地说是预处理)的过程,节省时间。在大型C程序编译过程当中,这种差别是很是明显的。
此外,extern修饰符可用于指示C或者C++函数的调用规范。好比在C++中调用C库函数,就须要在C++程序中用extern "C"声明要引用的函数。这是给连接器使用的,告诉连接器在连接的时候用C函数规范来连接。主要缘由是C++和C程序编译完成后再目标代码中命名规则不一样。
0x05
简要例子:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int x = 0;
5 int y = 5;
6 int func1()
7 {
8 extern p, q;
9 printf("p is %d, q is %d\n", p, q);
10 return 0;
11 }
12
13 int p = 8;
14 int q = 10;
15 int main()
16 {
17 func1();
18 printf("x is %d, y is %d\n", x, y);
19 }
输出结果: