在 C++ 中,对于使用extern 关键字,我们再熟悉不过了。接下来我们一起探讨一下关于extern 关键字的使用方法以及应用场景。
变量的声明
当你在多个文件中使用同一个全局变量时,你需要在使用它们的文件中用 extern 关键字进行声明,而在一个文件中定义它(分配存储空间)。假设你有一个文件 file1.cpp,它定义了一个全局变量。
// file1.cpp
int globalVariable; // 定义一个全局变量
现在你想在另一个文件 file2.cpp 中使用这个变量,你会这样声明
// file2.cpp
extern int globalVariable; // 声明存在一个名为 globalVariable 的全局变量
函数的声明
当你在多个文件中使用同一个函数时,函数的原型通常在头文件(.h 文件)中用 extern 声明(实际上,在 C++ 中函数默认是 extern 的,所以通常可以省略 extern 关键字)。
// file1.h
extern void foo(); // 声明函数foo,extern 关键字在这里是可选的
// file1.cpp
#include "file1.h"
void foo() {
// 实际函数定义
}
另一个文件可能这样使用该函数
// file2.cpp
#include "file1.h"
void bar() {
foo(); // 调用在 file1.cpp 中定义的函数
}
链接 C 语言代码
使用 extern “C” 链接 C 语言代码是一种常见的实践,特别是当你需要在 C++ 程序中使用由 C 语言编写的库时。由于 C++ 支持函数重载,编译器会修改函数的名字,这个过程称为名字粉碎(name mangling)。C 语言并不支持重载,因此,如果想要在 C++ 中链接到 C 函数,就需要阻止 C++ 编译器对这些符号进行名字粉碎。
extern “C” 就是提供这种阻止名字粉碎的机制,它告诉 C++ 编译器,被其修饰的代码(通常是函数声明)应该按照 C 链接约定进行处理。
my_c_function.h
// C 语言头文件
#ifndef MY_C_FUNCTION_H
#define MY_C_FUNCTION_H
#ifdef __cplusplus
extern "C" {
#endif
void my_c_function();
#ifdef __cplusplus
}
#endif
#endif
my_c_function.c
#include "my_c_function.h"
#include <stdio.h>
// C 语言的函数实现
void my_c_function() {
printf("C function called\n");
}
main.cpp
#include "my_c_function.h"
int main() {
my_c_function(); // 调用 C 语言函数
return 0;
}
链接 C 程序库到 C++ 程序
确保 C++ 编译器不会对 my_c_header.h 中声明的 C 函数进行短命操作,允许 C++ 代码链接和调用这些 C 函数。
extern "C" {
#include "my_c_header.h"
}
关于c语言中的extern
在 C 语言中,extern 关键字主要用于声明变量或函数,其真正的定义可能在程序的另一个位置或在不同的源文件中。是为了实现变量和函数的跨文件访问。
// File: shared.c
int sharedVar = 42; // 定义
void func() {
// 函数实现
}
// File: main.c
extern int sharedVar; // 声明,不是定义
extern void func(); // 声明,在另一个文件中定义
int main() {
sharedVar = 5;
printf("%d\n", globalVar); // 访问已在其他文件定义的全局变量
func();//调用在 shared.c 中定义的函数
return 0;
}