【C++ 面试 - 基础题】每日 3 题(十)

news2024/9/23 9:22:21

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/fYaBd

📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

28. extern 的作用 

extern 可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外 extern 也可用来进行链接指定。

extern 有两个作用,第一,当它与 "C" 一起连用时,因为 C 和 C++ 生成符号的方式不同,C 和 C++ 语言之间的 API 接口是无法直接调用的,C 语言的函数声明必须扩在 extern "C"{} 中。

如:extern "C" void fun(int a, int b); 则告诉编译器在编译 fun 这个函数名时按着 C 的规则去翻译而不是 C++ 的,C++ 的规则在翻译这个函数名时会把 fun 这个名字变得面目全非。

因为,C++ 语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而 C 语言则不会,因此会造成链接时找不到对应函数的情况,此时 C 函数就需要用 extern "C" 进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。

extern "C" 将 C++ 的 name mangling 机制关闭了,这样函数名就不会被 C++ 取的稀奇古怪,原来是什么样就是什么样。

需要注意的是, extern "C" 关键字只对函数的名称和调用约定起作用,对于函数的参数类型和返回值类型没有影响。

所以,在使用 extern "C" 声明函数时,需要保证函数的参数类型和返回值类型与 C 语言的定义相同,否则会导致编译错误或运行时错误.

总结:

  1. extern "C" 只是 C++ 的关键字,不是 C 的。

  2. 被 extern "C" 修饰的目标一般是对一个全局 C 或者 C++ 函数的声明。

  3. extern "C " 这个关键字声明的真实目的,就是实现 C++ 与 C 及其它语言的混合编程。

第二,当 extern 不与 "C" 在一起修饰变量或函数时,extern 用于指示变量或函数的定义在另一个源文件中,并在当前源文件中声明。说明该符号具有外部链接 (external linkage) 属性。

也就是告诉编译器:这个符号在别处定义了,你先编译,到时候链接器会去别的地方找这个符号定义的地址。

29. extern 的符号的声明与定义

首先明白 C/C++ 中变量的声明和定义是两个不同的概念声明是指告诉编译器某个符号的存在,在程序变量表中记录类型和名字,而定义则是指为该符号分配内存空间或实现其代码逻辑。

凡是没有带 extern 的声明同时也都是定义。

而对函数而言,带有 {} 是定义,否则是声明。如果想声明一个变量而非定义它,就在变量名前添加关键字 extern ,且不要显式的初始化变量。

// 声明
extern int global_var;
int sum(int a, int b);

// 定义
int global_var = 42;
int sum(int a, int b){
    return a+b;
}

声明变量或函数的存在,但不进行定义,让编译器在链接时在其他源文件中查找定义这使得不同的源文件可以共享相同的变量或函数。

当链接器在一个全局变量声明前看到 extern 关键字,它会尝试在其他文件中寻找这个变量的定义。这里强调全局且非常量的原因是,全局非常量的变量默认是外部链接的。

  

30. 编译和链接的过程中,extern 的作用

编译链接过程中,extern 的作用如下:

  1. 在编译期 extern 用于告诉编译器某个变量或函数的定义在其他源文件中,编译器会为它生成一个符号表项,并在当前源文件中建立一个对该符号的引用。这个引用是一个未定义的符号,编译器在后续的链接过程中会在其他源文件中查找这个符号的定义。

  2. 在链接期,链接器将多个目标文件合并成一个可执行文件,并且在当前源文件中声明的符号,会在其它源文件中找到对应的定义,并将它们链接起来。

下面是一个使用 extern 声明全局变量的示例:

   

在上面的示例中, file1.cpp 文件中的 main 函数使用了全局变量 global_var ,但是 global_var 的定义是在 file2.cpp 中的,因此在 file1.cpp 中需要使用 extern 声明该变量。

在编译时,编译器会为 global_var 生成一个符号表项,并在 file1.cpp 中建立一个对该符号的引用。 的定义,并将其链接起来。在链接时,链接器会在其他源文件中查找 global_var。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2038785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何把命令行创建python虚拟环境与pycharm项目管理更好地结合起来

1. 问题的提出 我在linux或windows下的某个目录如“X”下使用命令行的方式创建了一个python虚拟环境(参考文章),对应的目录为myvenv, 现在我想使用pycharm创建python项目myproject,并且利用虚拟环境myvenv,怎么办&…

搭建jenkins+k8s过程中遇到的问题

1、k8s地址配置导致的一些个问题 Still waiting to schedule task ‘Jenkins’ doesn’t have label ‘k8s-jenkins-slave’ 出现以上异常一般就是k8s地址配置不对或者地址不通导致的 配置完k8s地址以及命名空间等内容之后,在获取k8s下的token 1.查看sa # kubectl get sa…

我的第一个CUDA程序

MatAdd算法 实现两个矩阵对应元素相加 MatAdd算法的GPU实现 CPU端为输入矩阵A和B、输出矩阵C分配空间,并进行初始化CPU端分配设备端内存,并将A和B传输到GPU上定义数据和线程的映射关系,并确定线程的开启数量和组织方式 每个线程负责输出矩阵…

EasyX自学笔记3(割草游戏1)

割草游戏,有玩家(上下左右控制移动)周围围绕子弹,敌人(随机刷新)向玩家靠近,子弹打死敌人,玩家与敌人触碰游戏结束。 分析需求 1.有玩家、敌人、子弹三种对象 2.玩家上下左右控制…

Spring MVC数据绑定和响应学习笔记

学习视频:12001 数据绑定_哔哩哔哩_bilibili 目录 1.数据绑定 简单数据绑定 默认类型数据绑定 简单数据类型绑定的概念 参数别名的设置 PathVariable注解的两个常用属性 POJO绑定 自定义类型转换器 xml方式 注解方式 数组绑定 集合绑定 复杂POJO绑定 属性为对象类…

力扣面试经典算法150题:最长公共前缀

最长公共前缀 今天的题目是力扣面试经典150题中的数组的简单题: 最长公共前缀 题目链接:https://leetcode.cn/problems/longest-common-prefix/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 编写一个函数来查找字符串数组中的最长公…

修改OpenSSH服务版本号

前言 这几年信息安全要求很高,奈何口号响亮掩盖不了我们技术基础依然很低的事实,加上风口烧钱和政绩工程等因素,于是就诞生了一些乱象,其中一个就是安全扫描胡乱标记,这里面的典型就是OpenSSH的漏洞扫描报告。 比如&…

人工智能小车——智能车臂控制平台

随着机器人技术的不断发展 ,各行业对机器人应用人才的需求也随之增加,培养符合行业发展需求的机器人技术专业人才成为了高校的重要任务。 基本介绍 智能车臂控制平台(ZI-AutoRB)是一套用以机器人控制技术学习和研究的软硬件系统。…

米联客-FPGA程序设计Verilog语法入门篇连载-10 Verilog语法_一般设计规范

软件版本:无 操作系统:WIN10 64bit 硬件平台:适用所有系列FPGA 板卡获取平台:https://milianke.tmall.com/ 登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑! 1概述 本小节讲解Verilog语法的一般…

照片回收利器:最新数据恢复软件推荐

照片回收利器:最新数据恢复软件推荐 在今天的数字化时代,我们将大量珍贵的照片和个人数据存储在电脑、手机和其他设备中。然而,由于各种原因,这些数据可能会意外删除或丢失,这对我们来说是一个巨大的损失。因此&#…

【Redis】List类型

目录 List列表 命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP RPOP LINDEX LINSERT LLEN lrem ltrim lset 阻塞版本命令 BLPOP BRPOP 内部编码 使用场景 消息队列 分频道的消息队列 作为栈或者队列 List列表 列表类型是⽤来存储多个有序的字符串&…

5 大场景上手通义灵码企业知识库 RAG

大家好,我是通义灵码,你的智能编程助手!最近我又升级啦,智能问答功能全面升级至 Qwen2,新版本在各个方面的性能和准确性都得到了显著提升。此外,行间代码补全效果也全面优化,多种编程语言生成性…

python-小理和他的猫(赛氪OJ)

[题目描述] 今天小理又要为他的猫小咪准备好吃的猫粮了,你愿意帮助一下他们么? 小理现在拥有的金钱数为 N ,有 M 种小咪喜欢的猫粮从左到右排列,已知每种猫粮的价格 ai​ ,他的购买规则如下: 1.必须按照从左…

数据结构与算法--图的存储与遍历

文章目录 回顾提要图的定义和表示图的表示完全图和子图顶点的度路径与回路连通图 邻接矩阵权和网 邻接表示例 深度优先遍历 (DFS)广度优先遍历 (BFS)广度优先遍历过程总结邻接矩阵存储结构邻接表存储结构 回顾 线索化二叉树:在某种次序遍历过程中创建线索&#xff…

简单数学运算(c语言)

1.描述 //牛牛最近学会了一些简单的数学运算,例如 //∑i1 ∑i 1 //请你帮他模拟一下这个运算。 (即 1 2 3.... n - 1 n) //输入描述: //输入仅一个正整数 n //输出描述: //请你计算 //∑i1n 2.就是递归函数 方法一&#xf…

40.【C语言】指针(重难点)(E)

目录 13.指针的使用和传址调用 14.数组名的理解 *数组名就是数组首元素的地址 *两个例外 *使用指针访问数组 *一维数组的传参本质 往期推荐 承接上篇39.【C语言】指针(重难点)(D) 13. 指针的使用和传址调用 见29.【C语言】函数系…

Linux系统编程(9)

一、wait函数 1.wait函数 #include <sys/wait.h> pid_t wait(int *status);wait函数有两个作用&#xff1a; 1.获取子进程 的退出状态 当父进程要获取子进程的退出状态时&#xff0c;子进程里需要使用exit函数&#xff08;exit&#xff08;退出状态值&#xff09;退出…

10:【stm32】USART与串口通信一:USART(上)

USART&#xff08;上&#xff09; 1、串口通信1.1、简介1.2、数据帧1.2.1、简介1.2.2、校验规则1.2.3、停止位的长度 1.3、异步通信的波特率1.3.1、同步通信1.3.2、异步通信1.3.3、硬件流控 2、USART2.1、简介2.2、工作的原理2.3、相关寄存器 3、标准库编程3.1、编程接口USART_…

day16-测试自动化之selenium的PO模式

一、PO模式介绍 PO&#xff08;Page Object&#xff09;模式是一种在自动化测试中常用的设计模式&#xff0c;将页面的每个元素封装成一个对象&#xff0c;通过操作对象来进行页面的交互。 一般分为六个版本&#xff0c;现在大部分企业都用的V4版本&#xff0c;三层结构…

redis面试(十六)公平锁释放和排队加锁

锁释放 RedissonFairLock.unlockInnerAsync()方法 这和加锁的逻辑没有太大区别 也就是说在客户端A他释放锁的时候&#xff0c;也会走while true的脚本逻辑&#xff0c;看一下有序集合中的元素的timeout时间如果小于了当前时间&#xff0c;就认为他的那个排队就过期了&#xf…