不枉初心,砥砺前行

皮皮祥的博客

欢迎留言,评论

导航

C语言中extern?

C语言中的变量有哪些存储类型,你还记得吗?extern如何使用你都掌握了吗?看了本文你就清楚了。

1、 回顾C语言变量

C语言中变量值的存储位置有两类:CPU的寄存器和内存。变量存储类型关系到其存储位置,除了register型存储在CPU寄存器中,C语言提供的其它三种存储类型(auto型、static型、extern型)的变量均存储在内存中。存储位置不同,决定了变量的生存期和作用域。

从时间角度来说,C语言中变量分为静态存储和动态存储两种情况。静态存储指的是变量存储在内存的静态存储区,程序编译时就为其分配空间并初始化,占有固定存储单元直至程序结束。而动态存储指的是变量存储在内存的动态存储区,一般用于存储函数中的临时变量(声明为static型的变量除外),只有函数被调用,此类型变量才被分配空间,函数调用结束时该变量空间将会被释放。

从空间角度来说,C语言中变量分为局部变量和全局变量,其有效作用范围称为作用域。局部变量通常定义在函数内部或符合语句内,其仅在函数内部或符合语句内有效,程序编译阶段不会给其分配空间,仅在运行阶段临时分配,运行结束即释放空间。全局变量指的是在函数以外定义的变量,其作用范围为从定义处开始到所在程序文件结束。编译阶段开始分配固定空间,程序运行期间始终占有该空间不变。

整体来讲,全局变量和声明为static型的局部变量存储在内存的静态存储区;局部变量存储在内存的动态存储区。

2、 extern的变量声明

我们知道,在函数外部定义的变量称为全局变量,其存储方式为静态存储,生存期为整个程序的运行周期,作用范围即作用域为从定义处到所在文件结束。那么我们想在全局变量作用范围之外使用它该怎么办呢?事实上,C语言中extern关键字就是用作“外部变量声明”,起到扩展外部变量作用域的作用。

通常C语言是以源文件为编译单位的,一个程序可以包含一个或多个源文件,每个源文件包含一个或多个函数。但是程序不管有几个源文件,extern的用法都是相同的,我们分这两种情况来说明。

1) 单个源文件的情况

对于单个源文件的程序,如果某个全局变量不是在文件开头定义,而是在中间某个位置,那么如果在定义位置之前的函数想使用这个全局变量,则可以采用extern来声明变量。例如,下面示例程序中全局变量g_a定义在main函数之后,要想在main函数中使用已经超出了g_a的作用域,这里就可以采用extern声明,即可使用,程序输出结果为10。

#include <stdio.h>

void prtValue(int x);

int main(void)

{

extern int g_a;

prtValue(g_a);

return 0;

}

int g_a = 10;

void prtValue(int x)

{

printf(“%d”,x);

}

2) 多个源文件情况

假定某程序包含file1.c和file2.c两个文件。file1.c文件中定义了一个int型全局变量g_b,如果file2.c文件中某函数想使用g_b变量,只需要在file2.c文件的使用位置之前(通常为文件开头位置)通过“extern int g_b;”语句进行外部变量声明即可使用。

如果某程序包含多个源文件(模块),一个源文件中定义了全局变量,其它多个源文件均需要使用该全局变量,只需要在各使用此全局变量的文件中通过extern对全局变量进行声明即可使用。值得注意的是,这种情况下涉及到多个文件对一个变量的操作,某个文件修改了变量的值,可能会影响其他文件的使用,需谨慎使用。

3、 其它使用

此外extern也可用于函数的外部链接声明。我们知道函数的声明(定义)也可以包括存储类型,但只有extern/static两种。当函数声明为extern,说明函数具有外部链接,其它文件可以调用此函数;当函数声明为static,说明函数是内部链接,即只能在定义函数的文件内部调用函数;当不指明函数存储类型,则默认该函数具有外部链接。通过如下声明语句,我们看到函数fun1和fun3都具有外部链接,因此,如果不限定函数为内部链接的情况下,也无需通过extern特意声明为外部链接,因为它默认已经具有外部链接了。

extern int fun1(int x); //外部链接

static int fun2(char c); //内部链接

int fun3(int i); //外部链接

posted on 2022-11-29 19:47  皮皮祥  阅读(152)  评论(0编辑  收藏  举报