6月1日 14:39

C语言 extern 关键字有什么用?跨文件共享变量怎么做?

extern 告诉编译器"这个变量/函数在别的地方定义了,别报错,链接时再找"。核心作用就是跨文件共享变量和函数声明。

追问

extern 声明和定义有什么区别?

定义分配内存,声明只是说"有这个东西"。一个变量在整个程序里只能定义一次,但可以声明多次:

c
extern int count; // 声明:不分配内存,告诉编译器 count 在别处定义 int count = 0; // 定义:分配内存

常见坑:extern int x = 10; 虽然语法合法,但一旦在头文件里这么写,多个源文件 include 后就会重复定义,链接报错。extern 声明不要带初始化。

extern 和 static 为什么不能一起用?

矛盾的东西。extern 说"外面能找到我",static 说"只有我这个文件能用"。编译器不知道该听谁的,所以直接报错。不过 static 全局变量和 extern 声明可以出现在不同文件里——这时候链接器找不到 static 变量,报 undefined reference。

extern "C" 是干嘛的?

C++ 支持函数重载,编译器会给函数名加后缀(name mangling),比如 void foo(int) 变成 _Z3fooi。C 语言不做这个变换。当 C++ 代码要调用 C 编译的库时,得告诉 C++ 编译器"按 C 的方式链接这个函数名":

c
#ifdef __cplusplus extern "C" { #endif void c_library_init(); void c_library_cleanup(); #ifdef __cplusplus } #endif

这个模式在所有 C/C++ 混编项目的头文件里都会出现。

头文件里写 extern 有什么讲究?

标准做法:头文件里只放 extern 声明,.c 文件里放定义。这样多个源文件 include 同一个头文件时,各自拿到声明,链接时汇指向唯一的定义。如果头文件里直接写定义(不加 extern),多个 .c 文件 include 就会产生重复定义错误。

实际项目中 extern 用得多吗?

直接用 extern 声明变量的情况越来越少了,现代 C 项目更倾向用"头文件 + 函数接口"来暴露模块功能,而不是暴露全局变量。但 extern "C" 在 C/C++ 混编项目中几乎必用,比如嵌入式开发里 C++ 调 C 驱动库。

写段代码

c
// config.h — 只放声明 extern int max_connections; extern const char* get_version(); // config.c — 放定义 int max_connections = 100; const char* get_version() { return "1.0.0"; }
标签:C语言