当前位置: 首页 > article >正文

C++中extern的作用(面试)

1.声明和定义的区别

1.1声明

例如一个变量,声明是告诉编译器变量的类型和名称,而不分配空间给他。

再例如一个函数,声明是告诉编译器函数的返回值,函数名,形参类型,而不具体实现。

1.2定义

例如一个变量的定义,就是在声明的基础上,给变量分配空间。

例如一个函数的定义,就是在声明的基础上,在{}内,具体实现函数。

#include<iostream>
using namespace std;
int main()
{
	int a;//即是声明,同时也定义了(因为编译器已经默认分了空间给a)
	int add(int x, int y);//只是声明,并没有分配空间
	return 0;
}

2.链接属性

c++中有none(无)、external(外部)和 internal(内部)三种链接属性。其中具有外部链接属性的有非常量的全局变量和自由函数,他们在整个项目中具有全局性,不能重名(因为在链接过程中多个obj文件会合成一个,此时所有的全局变量和自由函数都会聚集在一起)。

3.extern的作用

3.1共享非const全局变量

//在1.cpp中
int a = 0;
//在2.cpp中
extern int a;//此时就能使用a了

例如在不同的工程文件中,在1.cpp中定义了一个全局变量,如果我们想要在2.cpp中也使用这个变量,就需要使用到extern关键字声明a。

这里就要提出疑问了?在预处理-编译-汇编-链接,最后的链接过程中不是多个obj文件会合成一个吗,这时不是只需要在2.cpp中声明就可以了吗?即int a。为什么还要使用extern关键字呢?

前面我们已经提到了int a时,编译器会自动为a分配空间,此时即是声明,也是定义,因此会在链接时报错,a被多次定义了,因此只能使用extern int a;此时才代表a声明了。

3.2共享自由函数

//在add.cpp中
int add(int x,int y)
{
    return x+y;
}
//在1.cpp中
extern int add(int,int)//此时就能使用add函数声明

其实,我们在这里也可以不使用extern关键字,因为在最后链接时都会合并在一起,因此只需要声明,此时不加上extern也不报错。

3.3共享const全局变量

对于 const 变量,extern 也可以用来声明它们,但需要注意的是,const 变量默认具有内部链接,这意味着它们只在定义它们的文件中可见。如果要在多个文件中共享 const 变量,需要在定义时就加上extern关键字。

3.4extern"C"

当在 C++ 代码中调用 C 语言编写的函数时,需要使用 extern "C" 来防止 C++ 编译器对函数名进行名称修饰(name mangling)。

例如我们在add.c中定义了add函数

int add(int x, int y)
{
	return x + y;
}

如果我们需要在add.cpp中也使用这个函数,首先需要进行声明 

#include<iostream>
using namespace std;

int add(int, int);
int main()
{
	cout<<add(5, 6);
	return 0;
}

如果是这样的话,就会报错,因为C++函数名称的修饰,已经找不到对应的add函数了

#include<iostream>
using namespace std;

extern"C" int add(int, int);
int main()
{
	cout<<add(5, 6);
	return 0;
}

如果是这样就可以,因为被extern“C”的修饰,此时add函数的调用已经遵循了C的原则

4.建议

为了更好地组织代码,通常会在头文件中声明 extern 变量和函数,然后在源文件中定义它们,在对应文件中只需要包头文件就能使用了。


http://www.kler.cn/news/364778.html

相关文章:

  • Openpyxl--学习记录
  • 如何将rust日志输出到android终端
  • 如何写一个视频编码器演示篇
  • 论文阅读与写作入门
  • 新鲜出炉面试题之【说说spring spring MVC spring boot的区别】
  • u盘装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法
  • 【网络安全】护网蓝队之应急响应
  • OracleT5-2 Solaris11安装
  • 使用JMeter进行Spring Boot接口的压力测试
  • Linux运维常见问题排查
  • wordcloud分词生成
  • c#————FieldInfo的基础使用
  • 鸿蒙网络编程系列33-TLS回声服务器示例
  • 音频编解码器音频文件格式
  • 数字图像处理的概念(二)
  • 基于SpringBoot+Vue+uniapp微信小程序的文玩销售小程序的详细设计和实现
  • 如何使用 Ngrok 将本地服务暴露到公网
  • 企业数字化转型战略深度解析与最佳实践路径:微服务架构与物联网的深度融合
  • python爬虫技术实现酷我付费破解下载
  • 搜维尔科技:Manus新品发布Metagloves Pro专业版,专为高精度需求的客户打造,尤其是人形机器人产业与人机工效研究使用
  • 免费开源!语音识别平台让医疗对话更高效,沟通更准确
  • 【卫星图像处理】卫星光照处理
  • docker 镜像详解
  • filebeat接入nginx和mysql获取日志
  • 【C++】类和对象(附题)
  • 【LeetCode每日一题】——862.和至少为 K 的最短子数组