C++ - extern关键字的用法
extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定
1. 定义和声明的区别
声明用来告诉编译器变量的名称和类型,而不分配内存,不赋初值。
定义为了给变量分配内存,可以为变量赋初值。
注:定义要为变量分配内存空间;而声明不需要为变量分配内存空间。
extern int i; //声明
int i; //定义
2. extern用法
2.1 extern 变量
如果文件b.c需要引用a.c中变量int a,就可以在b.c中声明extern int a,然后就可以引用变量a。能够被其他模块以extern修饰符引用到的变量通常是全局变量。
注意,extern int a可以放在a.c中的任何地方,具体作用范围和局部变量相同。
extern的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”
举例
test.h
//声明外部变量
extern int a;
extern int b;
test.cpp
#include "test.h"
//定义外部变量、外部变量初始化
int a = 520;
int b = 1314;
main.cpp
//使用外部变量
#include <stdio.h>
#include "test.h"
/*#include"test.cpp"*/ //不可以这样引用,否则警告LNK2005、LNK1169
int main(void)
{
printf("a = %d , b = %d\n", a, b);
return 0;
}
运行结果:
2.2 extern 函数
使用extern 关键字声明函数表示引用全局函数。
优点:不会引入大量头文件,进而不会引入大量的无关函数。这样做的一个明显的好处是,会加速程序的编译(确切的说是预处理)的过程,节省时间。
举例
global_function.h
#pragma once
//声明
extern int add(int a, int b);
extern int sub(int a, int b);
global_function.cpp
//实现
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
main.cpp
#include <stdio.h>
#include "global_function.h"//使用全局函数只需要包含头文件
int main(void)
{
int a = 66;
int b = 20;
int value1 = add(a, b);
int value2 = sub(a, b);
printf("a + b = %d , a - b = %d\n", value1, value2);
return 0;
}
调试结果:
2.3 extern 类
使用extern 定义全局类对象,打印输出日志文件
log.h
#pragma once
class Log
{
public:
enum Type
{
Info,
Warning,
Error,
Failed,
typeSize
};
Log();
~Log();
void Output(Type type, const char* string);
private:
};
log.cpp
#include "log.h"
#include <iostream>
using namespace std;
Log::Log()
{
cout << "test" << endl;
}
Log::~Log()
{
}
void Log::Output(Type type, const char* string)
{
cout << "string: " << string << endl;
}
global_info.h
#pragma once
#include "log.h"
extern Log* g_pLog;
extern int GetSkin();
global_info.cpp
#include "global_info.h"
Log* g_pLog = nullptr;
int GetSkin()
{
int iIndex = 0;
return iIndex;
}
test.h
#pragma once
#include "global_info.h"
class Test
{
public:
Test();
~Test();
private:
};
test.cpp
#include "test.h"
#include <iostream>
using namespace std;
Test::Test()
{
g_pLog->Output(Log::Info, "测试一下!");
int skintype = GetSkin();
cout << "skintype = " << skintype<<endl;
}
Test::~Test()
{
}
main.cpp
#include <stdio.h>
#include <iostream>
#include "global_info.h"
#include "test.h"
using namespace std;
int main()
{
//构建对象
char LogPath[255] = "C:\\Users\\Administrator\\AppData\\Roaming\\Log\\log.txt";
g_pLog = new Log();//创建全局对象
g_pLog->Output(Log::Info, "你好");
Test* t1 = new Test();
return 0;
}
运行结果:
2.4 在C++文件中调用C方式编译的函数
比如在C++中调用C库函数,就需要在C++程序中用 extern “C” 声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同。
示例代码
1. 处理被调用的C头文件
my_module.h文件
#pragma once
#include<stdio.h>
#ifdef __cplusplus
extern "C"{
#endif
void func1();
int func2(int a,int b);
#ifdef __cplusplus
}
#endif
my_module.c文件
#include "my_module.h"
void func1() {
printf("hello world.");
}
int func2(int a, int b) {
return a+b;
}
main.cpp文件
#include "my_module.h"
#include<iostream>
using namespace std;
int main()
{
func1();
cout << func2(10, 20) << endl;
}
#pragma once
#include <stdio.h>
void func1();
int func2(int a, int b);
my_module.c文件
#include "my_module.h"
void func1() {
printf("hello world.");
}
int func2(int a, int b) {
return a+b;
}
main.cpp文件
#include <iostream>
using namespace std;
extern "C" {
#include "my_module.h"
}
int main()
{
func1();
cout << func2(1, 2) << endl;
}
3. 通俗讲解extern
在定义变量的时候,这个extern可以被省略(定义时,默认均省略);
在声明变量的时候,这个extern必须添加在变量前,所以有时会让你搞不清楚到底是声明还是定义。
或者说,变量前有extern不一定就是声明(首先声明必须要有extern,但是定义也可以不省略extern,编译器也没报错,但是尽量不要采用这种定义方式), 而变量前无extern就只能是定义(因为声明必须要有extern,没有extern只能是定义省略extern的情况)!!!
一般来讲,定义默认省略extern,判断有extern int a;这种格式的语句即为声明
注意事项:无论是否有extern修饰,赋初值==定义。如下两种方式是等价的,必为定义!!!
//如果在声明的时候给变量赋值,那么就去掉extern直接定义变量赋值是等价的
extern int a = 10;//尽量不要写这种定义方式
int a = 10;//上述两条语句等价
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具