C语言应用笔记(六):C语言extern关键字及其使用

C 语言中,修饰符 extern 用在变量或者函数的声明前面,用来标识变量或函数的定义在别的文件中,提示编译器遇到此变量或函数时,在其他文件中寻找其定义。下面对 extern 关键字的几种用法进行说明。


(1)extern 修饰变量的声明

extern 关键字可以用来修饰变量,表示该变量在别的文件中已有声明。例如,我们在文件 file1.c 中声明变量:

/* file1.c */
int var;

然后我们又需要在 file2.c 中使用该变量,则可以在文件 file2.c 中声明:

/* file2.c */
extern int var;

这样就可以在 file2.c 中使用变量 var 了。显然,使用 extern 关键字修饰的变量都是全局变量,因为在其他文件中引用局部变量是没有实际意义的,也超出了局部变量的作用域。

说到作用域,需要说明的是,尽管使用 extern 关键字修饰的变量,其原本都是全局变量,但如果 extern int var; 声明处于某一函数体内,那么其作用域就在该函数体内。这其实与一般变量的作用域是相同的。

 

(2)extern 修饰函数声明

从本质上来讲,使用 extern 关键字函数和变量没有什么区别。如果我们在文件 file1.c 中定义函数:

/* file1.c */
void function(int var){...}

而我们想要在文件 file2.c 中使用这个函数,那么我们可以在 file2.c 中声明:

extern void function(int var);

当然,应用其他文件中的函数,更常用的方式应用相应的头文件。那么使用extern 关键字与直接引用头文件有何不同呢?首先,引用头文件是一种预处理,而 extern 关键字声明在链接层实现;其次,对于大批量引用自然是使用头文件比较方便,但如果我们只是使用个别函数,这时使用 extern 更为直接。

(3)extern 用来进行链接指定

extern 关键字用来进行链接指定一般用于混合编程,如果我们要在 C++ 程序中调用 C 代码,则我们就需要使用 extern "C" 来声明,这样链接器就会使用 C 的规范来链接这部分代码。

 

(4)extern 与 static

从某种意义上来说,extern 关键字与 static 关键字是相反的,extern 关键字是声明想要调用的外部变量和函数,而 static 关键字声明的是为本源文件使用。当然使用 static 关键字声明一个变量时,同时也定义了该变量,而 extern 关键字声明一个变量时,仅仅是声明,因为该变量早已在其他地方定义。


示例代码:

/* test.h */
#ifndef _TEST_H
#define _TEST_H

extern uint8_t a;
extern uint8_t b;
void output(void);

#endif
/* end of test.h */
/* test.c */
#include "test.h"
#include "stdio.h"
uint8_t a = 12;
uint8_t b = 34;
uint8_t c = 56;

void output(void)
{
    printf("a+b+c = %d\r\n", a + b + c);
}
/* end of test.c */
/* main.c */
#include "stdio.h"
#include "test.h"
int mian(void)
{
    printf("a+b = %d\r\n", a + b);
    output();
    return 0;
}
/* end of main.c */

extern "C"

#ifndef _TEST_H
#define _TEST_H

#ifdef __cplusplus
extern "C" {
#endif

/* ... */

#ifdef __cplusplus
}
#endif

#endif

__cplusplus 为 C++ 定义的一个宏,此时 extern "C" 后的部分的代码按 C 语言的格式进行编译,而不是 C++。

C++ 语言在编译的时候为了解决函数的重载问题,会将函数名和参数联合起来生成一个中间的函数名称,而 C 语言则不会,因此会造成链接时找不到对应函数的情况,此时 C 函数就需要用 extern "C" 进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。

C++ 语言的创建初衷是 "a better C",但是这并不意味着 C++ 中类似 C 语言的全局变量和函数所采用的编译和连接方式与 C 语言完全相同。作为一种欲与 C 兼容的语言,C++ 保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数。但是,C++ 毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++ 对全局函数的处理方式与 C 有明显的不同。

 

欢迎关注微信公众号『OpenSSR』

上一篇:MFC中定义全局变量


下一篇:关于extern "C"(详细剖析)