extern使用方法总结

来源:互联网 发布:男士风衣 知乎 编辑:程序博客网 时间:2024/06/05 17:31
在c语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此次引用”。

一、extern基本使用方法
1、函数
函数的声明中使用extern关键字是可有可无的,因为函数本身不加修饰的话就是extern的。(函数和全局变量本质上没有区别,函数名时指向函数二进制块开头处的指针,而全局变量时在函数外部声明的变量,函数名也是在函数外,因此函数也是全局的)
2、变量
全局变量在外部使用声明时,必须要有extern关键字(如果变量无extern修饰且没有显式的初始化,则就变为变量的定义编译器在此标记存储空间在执行时加载内存并初始化为0)。
局部变量的声明不能有extern修饰,且局部变量再运行时才在堆栈部分分配内存空间。

二、头文件
头文件里面存放的是关于函数、变量、类的声明(不是定义,不要再头文件里面定义什么东西)。

#ifndef _XXX_头文件_.H
#define _XXX_头文件_.H
...
int A;
#endif

这里的int A是一个全局变量的定义,所以如果这个头文件被多次引用的话,那么A就会被重复定义,显然语法上出现了错误。只不过有了#ifndef的条件编译,所以能保证这个头文件只被引用一次,不过也许还会有问题。若多个c文件包含这个头文件时,因为宏名有效范围仅限于本c源文件,所以在这个多c文件编译时是不会出错的,但在链接时就会报错,说你多处定义了同一个变量。所以在头文件中最好不要定义变量等。

三、extern使用时最让人迷惑的地方是让人搞不清楚使用extern的地方是声明还是定义。下面分别就变量和函数举例说明。

(1)变量
<1> extern int a;     //声明一个全局变量a
<2> int a;            //定义一个全局变量a
<3> extern int a = 0; // 定义一个全局变量a,并赋初值0
<4> int a = 0;        // 定义一个全局变量a,并赋初值0

(2)函数
函数定义的时候使用extern,说明这个函数是可以被外部引用的,声明的时候用extern说这是一个声明。但由于函数的定义和声明有区别,定义韩式要有函数体,声明函数没有函数体,所以函数定义和声明时都可以将extern省去,反正其它文件也是知道这个函数是在其他什么地方定义的,所以不加extern也行。

四、总结:

1、对于变量而言,如果你想在本源文件中使用另一个源文件中定义的变量,就需要在使用前用extern声明该变量,或者在头文件中用extern声明该变量;


2、对于函数而言,如果你想在本源文件中使用另一个源文件中定义的函数,就需要在使用前声明给函数,声明函数加不加extern都没有关系,所以在头文件中函数可以不用加extern。

3、extern用在变量声明中常常有这样一个作用,你在*.c文件中声明了一个全局的变量,这个全局的变量如果要别引用,就放在*.h中并用extern来声明。

4、如果函数的声明中带有关键字extern,仅仅说明这个函数可能在别的源文件里定义,没有其他作用,既如下两个函数声明没有区别:
extern int f();和int f();

5、如果定义函数的c/cpp文件在对应的头文件中声明了定义的函数,那么在其他c/cpp文件中要使用这些函数,就只需要包含这个头文件即可。如果你不想包含头文件,那么就要在本c/cpp文件中声明该函数。一般来说,声明定义在本文件的函数不用extern,声明定义在其他文件中的函数用extern,这样在本文件中调用别的文件定义的函数时就不用包含头文件。

使用extern和包含头文件来引用函数有什么区别呢?
extern的引用方式比包含头文件哟啊简洁的多。extern的使用方法是直接了当的,想引用哪个函数就用extern声明哪个函数。这样做有一个明显的好处是,会加速程序的编译(预处理)的过程,节省时间,在大型c程序的编译过程中,这种差异很明显。

6、此外,extern修饰符可以用于指示C或者C++函数的调用规范。比如C++中调用C库函数,就需要在C++程序用extern "C"生声明引用的函数。这是给连接器用的,告诉连接器在链接的时候用C函数规范来链接。主要是C++和C程序编译完成后在目标代码中命名规则不同。
0 0
原创粉丝点击