extern的用法解析

1 extern 关键字的基本作用

第一种用法:
在与"C"一起使用时,例如 extern "C" void fun(int a, int b),这告诉编译器在编译函数fun时按照C语言的规则进行编译,而不是C++的规则。C++对函数名的翻译可能导致fun这个名字变得面目全非,例如可能是fun@aBc_int_int#%$,具体取决于编译器的实现方式。为什么要这样做呢?因为C++支持函数的重载,这个问题不在此过多讨论,如果感兴趣可以进行网上搜索,相信你会找到满意的解释。

💡 告诉编译器用C的规则去编译这个函数!

第二种用法:
当extern不与"C"一起用于修饰变量或函数时,例如在头文件中 extern int g_Int,其作用是声明函数或全局变量的作用范围的关键字。声明的函数和变量可以在本模块或其他模块中使用,需要注意这是一个声明而不是定义。换言之,如果模块B想引用模块A中定义的全局变量或函数,只需包含A模块的头文件即可。在编译阶段,虽然模块B找不到该函数或变量,但不会报错;连接时会从模块A生成的目标代码中找到此函数。

💡 在A头文件中声明此变量或函数,则其他模块B包含A头文件后可直接使用此变量或函数,无需再在B中extern声明此变量或函数

第三种用法:
extern可以置于变量或函数前,以标示变量或函数的定义在其他文件中,从而提示编译器在其他模块中寻找其定义。此外,extern也可用于进行链接指定。

💡 若模块B想在不包含A头文件的前提下直接使用A的变量或函数,就需要单独使用extern type func();来声明。然而这种做法是不推荐的,详见下方解释。

2 注意!extern 声明

有些人喜欢把全局变量的声明和定义放在一起,这样可以防止忘记了定义,如把上面test1.h改为

extern char g_str[] = "123456"; // 这个时候相当于没有extern

然后把test1.cpp中的g_str的定义去掉,这个时候再编译连接test1和test2两个模块时,会报连接错误,这是因为你把全局变量g_str的定义放在了头文件之后,test1.cpp这个模块包含了test1.h所以定义了一次g_str,而test2.cpp也包含了test1.h所以再一次定义了g_str,这个时候连接器在连接test1和test2时发现两个g_str,也就是重复定义的错误。

如果你非要把g_str的定义放在test1.h中的话,那么就把test2的代码中#include "test1.h"去掉,换成:

extern char g_str[];

void fun2() { cout << g_str << endl; }

这个时候编译器就知道g_str是引自于外部的一个编译模块了,不会在本模块中再重复定义一个出来,但是我想说这样做非常糟糕因为你由于无法在test2.cpp中使用#include “test1.h”,那么test1.h中声明的其他函数你也无法使用了,除非也都用extern修饰,这样的话你光声明的函数就要一大串,而且头文件的作用就是要给外部提供接口使用的,所以请记住,只在头文件中做声明,真理总是这么简单

3 结构体外部声明

#include的方法

//a.h
struct Stu
{
	~
};
extern struct Stu s1; //声明
//a.c
#include "a.h"
struct Stu s1={ ~ };  //定义
//b.c
#include "a.h"
int temp;
temp=s1.~;            //外部直接调用

对于声明外部构造类型(结构体,共用体)变量,要注意两点,这两点也是和声明外部基本类型变量的区别:

一、声明外部构造类型变量时,该文件中必须要有构造类型的定义实体,否则会报错。

二、声明外部构造类型变量时,不能省略变量类型,否则也会报错。(声明外部基本类型变量时,却可以省略变量类型)。声明基本类型的外部变量时,如extern int A; 可以省略变量类型,直接写为extern A;。但是声明结构体的时候不可以,写extern s1; 编译会报错,必须写 extern struct Stu s1。

4 总结

4.1 include头文件的方式

//a.h
extern int temp;
//a.c
#include "a.h"
temp = 888;
//b.c
#include "a.h"
printf(temp);

4.2 不include头文件的方式

//a.h
int temp;        //不需要加extern
//a.c
#include "a.h"
temp = 888;
//b.c
//#include "a.h" //不需要包含头文件
extern int temp; //需要声明此变量为外部变量
printf(temp);    //然后直接使用即可

参考

C/C++中extern关键字详解

extern声明外部结构体

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值