C语言中有许多关键字,例如static,const等等,每个关键字都有其不同的用处,本期介绍一个常用的关键字——extern

extern字面意思为外部,像static,const一样,用以修饰变量。被extern修饰的变量则称为外部变量。就如static修饰的变量则为静态变量,const修饰的变量则为常量一样。

为什么要用extern?

我们举个例子:假设我有三个文件,首先是main.c这个是用来存放我们mian函数的文件。其次是test.h是我们用来测试的头文件,最后是test.c则是对于test.h的.c文件。

假如我们有一个函数并不会在main.c文件中执行而只会在test.c文件中执行(例如嵌入式的中断服务函数)或者我们举个例子

我们在test.c文件中,我们首先定义了一个变量a ,再定义了一个TestF函数,其内容是a递增,那么我在main函数中如何获得这个a的值呢?

我们通常的做法是将TestF的函数类型修改成int 型,使其每次返回我们对应的a值,或者重新定义一个函数,其作用就是返回a的值。

那还有没有其他的方式呢?或者说我能不能直接获得这个a的值,直接调用a ,修改并使用呢?

在这之前,我们首先要介绍一下声明和定义的区别。

首先,我们通常定义一个变量通常的写法是 int a = 0 ;这样子的写法,事实上,我个人更倾向于将这种称为 声明并定义 ,但是又是不对的,因为即便是int a 或者int a = 0; 变量a都已经被分配了空间。

而我认为,真正的声明则是如下图这样子,并且如果我们不去定义函数(补全)则会提醒我们未定义。在这种情况下,TestFF这个函数并没有被分配空间,但是计算机知道可能会有这样子的一个函数,但是没找到它的定义。


实际上这句话很重要,知道有这么个东西但是没找到定义顶多是警告,但是不知道有这么个东西那可是不仅仅是警告这么简单了。

我们观察下面两份代码

仅仅只是交换一下位置程序就运行错误。

其实我们可以简单的认为C语言的运行逻辑是从上至下的,main函数为入口,找到main函数为止。

既然是从上到下的,第一份代码中先经过了TT()函数,在找到的main函数,其实这时候系统已经“认识”了TT()函数,当我们需要调用TT函数的时候,系统知道该做什么事情。

而第二份代码中,TT函数在main函数之后,因此事实上系统压根并不认识TT函数(你谁啊)

因此我们需要有一个步骤来让系统认识这个函数,即函数声明。

当我们声明这个函数,相当于先告诉编译器有这个函数,之后如果我们遇到了这个函数,那么肯定是有这个函数的,全局里面慢慢找找。

因此声明是C语言必不可少的一项功能。

言归正传,声明和extern到底有什么关系呢?

其实,大家不觉得这二者很像嘛,我调用其他文件中的变量,和我调用其他文件中的函数。本质上报错的原因,不都是:编译器不认识这个变量或者函数。

那能不能通过一种类似声明的方式,使得系统能够提前认识这个变量呢?

没错,那就是extern

我们首先在需要调用的函数里面声明我们的extern int a ,注意这时候不要给a赋值,因为我们是单纯的来声明a的,告诉系统,我的整个文件里面是由a的,但是具体在哪你自己找找,这个a 是定义在其他文件中的。

如果我们写成extern int a = 30 ;实际上这个语句是声明并且定义了变量a,而test文件中也有int a 的定义,就会出现重复定义的报错。

因此在使用extern的时候尤其要注意不同文件之间的使用千万不要造成重复定义。

嘉立创PCB

还没有评论,抢个沙发!