C/C++语言相关常见面试题总结

目录

const关键字的作用

volatile 关键字

#define和const有什么区别

decltype和auto的区别

extern 关键字的作用

如何避免野指针

C/C++中的类型转换以及使用场景

什么是RTTI?其原理是什么?

RTTI 的原理:

C++中引用和指针的区别

C++11用过哪些新特性

简述多态实现原理

虚函数表和虚函数表指针的创建时机

为什么基类的构造函数不能定义为虚函数?


const关键字的作用

思考题

  1. C语言中的const局部变量可以用指针间接修改, 说明可以取地址, 那此时局部变量放在什么区域?
  2. C语言中全局的const变量完全不可修改, 也不可以取地址、此时放在什么区域?
  3. C++中的const局部变量不可修改,可以取地址、此时又放在什么区域、底层是怎么实现的?
  4. 用const的好处是什么?

1.

放在那里? 应该是放在虚拟地址空间的栈存储区域,所以可以修改,可以取出地址。

const修饰的局部变量通常是存储在栈区域的,但编译器可能会根据实际情况进行优化,将其直接嵌入到目标代码中,而不需要分配栈上的存储空间。

2. 

应该是放置在虚拟地址空间的静态数据区域的.rodata只读数据区域,所以不可修改,并且禁止取地址、强行取地址会报段错误。

3.

可以取地址,说明取地址的时候将这个数据放入了栈区域一份。但是在生成目标代码时,编译器(编译阶段)将该变量的值直接嵌入到使用该变量的地方。这样,在程序执行时,这个变量的值就不会被修改,因为它在目标代码中已经被固定下来了,所以就算我们通过指针强行修改了给的变量所在的内存、但是编译阶段完成的直接的替换我们又改不了,所以此时真正的const实现其实是依赖于编译器的优化/强大。

4.

好处, 修饰变量,修饰函数,不可修改,检查提醒,节约内存的作用。

volatile 关键字

  • 给编译器说清楚,我这个关键字修饰的对象和函数是易变的,易挥发的。你不要进行优化。直接去读取内存。
  • 它甚至可以跟const联合使用,用了它修饰的变量,哪怕是const, 它也会告诉编译器不要在编译阶段直接就用类似于预处理阶段对define的替换处理一样给我直接替换成常量了(.rodata区域/代码段),而去给我实际读取内存。

#define和const有什么区别

  • 在C++中,两者的区别就在于数据替换时期不同,一个在预处理时期由预处理器完成,另一个是编译器由编译器完成数据值的直接替换。
  • 两者作用时期不同、处理工具不同,自然预处理器是很简单的,他不比编译器的复杂。预处理器简单的做替换,展开。编译器在编译阶段会做词法分析,语法分析,类型检查等等工作。
  • 所以相对来说,C++中推荐用const,应该就是有类型检查,更为安全一点。define太暴力了、出错了没法搞。

decltype和auto的区别

  • 首先两者都是类型推导的方式。只不过,一个是根据初始化的表达式来推导,另一个是主动给出表达式来推导。并且decltype可以准确的推导出类型,auto推导自动去除const、&、*这些附加属性

decltypeauto 是 C++11 引入的两个关键字,用于从表达式推导变量的类型,但它们之间有一些区别。

  1. decltype

    • decltype 是一个类型推导关键字,用于获取表达式的类型。
    • decltype 的结果类型与给定表达式的类型完全相同,包括 const 和引用等修饰符。
    • decltype 的语法形式为 decltype(expression),其中 expression 是需要推导类型的表达式。
    • 通常用于从变量、函数调用、表达式等处推导类型。
  2. auto

    • auto 也是一个类型推导关键字,用于自动推导变量的类型。
    • auto 的结果类型与表达式的类型相同,但会忽略掉顶层 const 和引用等修饰符。
    • auto 的语法形式为 auto,直接声明变量时使用。
    • 通常用于定义变量时,让编译器自动推导变量的类型,可以简化代码并提高可读性。

简而言之,decltype 用于获取表达式的确切类型,包括 const 和引用等修饰符;而 auto 用于自动推导变量的类型,会忽略掉顶层 const 和引用等修饰符。

extern 关键字的作用

void Test() {
    extern void Print(); // 声明一下外部的Print函数调用

    Print(); // 找不到

}

void Print() {
    printf("hahaha\n");
}

int main() {
    Test();
    
    return 0;
}

也可以引用外部文件的函数,用extern 关键字显示说明一下这个函数,或者变量在外部文件或者区域已经定义好了,此处编译器你不用帮我报错,或者警告,它是定义好了的。

如何避免野指针

上述再补充一个及时跟新迭代器,迭代器失效本质上也就是插入,删除操作之后,之前的迭代器指向的节点发生了改变,所以我们需要及时跟新迭代器,避免操作失效的迭代器,其实本质上也是一个失效的指针.

迭代器失效的本质确实类似于野指针或非法操作内存的情况,因为迭代器失效意味着迭代器指向的位置在容器中不再有效,可能会指向已经释放的内存地址或者容器中的其他位置.

C/C++中的类型转换以及使用场景

  • C语言这个类型转换看似很爽,啥都能转,充分给足程序猿面子,但是转换不明确,限制太少了、而且没有错误检查,很容易出错。(太霸道了)
  • static_cast:说白了就是最基础的类型转换,也是最常用的类型转换。基本类型,子类指向父类的安全转换(上行转换)、void*和其他类型指针的转换。(最像C转换使用场合的转换)
  • const_cast:专门去除 const 或者 volatile 属性的。
  • dynamic_cast:用于父子类型之间的安全转换。编译器默认上行转换安全,下行转换进行类型检查。dynamic_cast 运算符在 C++ 中用于执行安全的向下转型(downcasting),并且在运行时进行类型检查。它主要用于在继承层次结构中的类之间进行转换,以及在执行转换之前进行类型检查。
  • 类型检查: 当使用 dynamic_cast 进行向下转型时,编译器会在运行时检查指针或引用指向的对象的实际类型是否与要转换到的类型相匹配。这种匹配性检查通过查看对象的虚拟表来实现。如果指向的对象实际上是要转换到的类型或其派生类的对象,则转换成功;否则,转换失败。
  • 失败处理

    • 如果 dynamic_cast 无法将基类指针或引用转换为派生类指针或引用,它将返回一个空指针(对于指针)或抛出一个 std::bad_cast 异常(对于引用)。
    • 如果进行指针类型转换时,指针为 null,则 dynamic_cast 也会返回 null。
  • 适用性

    • dynamic_cast 只能用于具有虚函数的类,因为它需要虚拟表来检查对象的实际类型。
    • dynamic_cast 只能用于多态类型(即基类或包含虚函数的类)之间的转换。
    • dynamic_cast 不适用于非多态类型之间的转换。

接着上面这个dynamic_cast 是运行时检测。

什么是RTTI?其原理是什么?

RTTI(Run-Time Type Information)是 C++ 提供的一种机制,用于在运行时获取对象的类型信息。RTTI 允许程序在运行时查询对象的类型,以便进行类型安全的操作,例如动态类型转换和异常处理。

RTTI功能体现在两个运算符上:typeid运算符和dynamic_cast运算符

  • typeid运算符,用于返回表达式的类型,可以通过基类的指针获取派生类的数据类型.

RTTI 的原理:

  1. 虚函数表(vtable): 在启用 RTTI 的情况下,C++ 编译器会为每个类生成一个虚函数表(vtable)。虚函数表是一个存储了指向虚拟函数的指针的数组,每个类都有自己的虚函数表。当一个类含有至少一个虚函数时,这个类就会拥有一个虚函数表。

  2. 类型信息对象(type_info): 对于每个类,编译器还会生成一个类型信息对象,其类型为 type_info。这个对象包含有关该类的类型信息,例如类名、类型大小等。在包含 RTTI 的编译器中,这个类型信息对象也包含指向虚函数表的指针。

  3. dynamic_cast 运算符的工作: 当使用 dynamic_cast 运算符进行向下转型时,编译器会查找源对象的类型信息对象,并在其中查找目标类型的信息。如果目标类型是源对象的基类或者与其兼容,则 dynamic_cast 可以成功转换;否则,转换失败。这种类型信息的查询是通过访问类型信息对象的虚函数表来实现的。

  4. typeid 运算符: C++ 还提供了 typeid 运算符,用于获取对象的类型信息。当使用 typeid 运算符时,编译器会生成代码来获取对象的类型信息对象,从而可以得到对象的类型信息。

总之,RTTI 的原理是通过在运行时为每个类生成虚函数表和类型信息对象,并通过这些信息来实现对对象的类型进行查询和检查。这使得在运行时能够进行类型安全的操作,如动态类型转换和异常处理。

C++中引用和指针的区别

  • 一般来说引用的必须初始化绑定一个对象,并且不可更改绑定,且不可绑空,使得引用相对指针更加安全一些。但是引用也会存在安全问题(也会悬空,尤其是在lambda表达式中捕获引用)

以下是一些需要注意的情况:

  1. 捕获局部变量的引用:如果 lambda 表达式捕获了一个局部变量的引用,并且该引用在 lambda 表达式执行时已经超出了其作用域,则会导致引用悬空。这种情况下,应该确保 lambda 表达式执行时捕获的引用仍然有效。

  2. 捕获指向堆内存的引用:如果 lambda 表达式捕获了指向堆内存的引用,而在 lambda 表达式执行时,堆内存已经被释放,那么捕获的引用将变为悬空。在使用指针或引用捕获对象时,应该确保对象的生命周期能够覆盖整个 lambda 表达式的执行过程。

为了避免引用悬空的问题,可以采取以下措施:

  1. 使用值捕获:如果捕获的对象在 lambda 表达式执行期间不会发生变化,并且对象的生命周期足够长,可以考虑使用值捕获而不是引用捕获。

  2. 小心捕获生命周期:确保捕获的引用或指针所引用的对象在 lambda 表达式执行期间保持有效。这可能需要在 lambda 表达式外部控制对象的生命周期,或者使用智能指针等机制来管理对象的生命周期。

  3. 避免悬空引用:在捕获引用时,要确保引用的对象在 lambda 表达式执行期间保持有效。如果无法保证引用的有效性,则应该避免捕获该引用。

C++11用过哪些新特性

简述多态实现原理

注意时间点差异:

  • 静态的多态是通过重载和模板技术实现的,是在编译时确定。
  • 动态的多态是用虚函数机制实现,是运行时确定。

虚函数表和虚函数表指针的创建时机

注意:

  • 虚函数表是属于整个类的,其中无非包含的虚函数的入口地址嘛,这些函数也是属于类的。
  • 虚函数表的创建时机和虚函数表指针初始化的时机是不一样的。一个是编译器创建、放在全局只读数据段,另外一个是在构造函数中初始化的这个vptr。类对象内部前面4个字节都存放的是这个vptr,故而都可以通过它找到虚函数表。

为什么基类的构造函数不能定义为虚函数?

因为虚表指针的初始化在构造函数中完成,由于此时虚表指针还没有完成初始化,所以基类的构造函数不能定义为虚函数。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

亮剑AIGC,紫光云能否胜人一筹?

【全球云观察 | 科技热点关注】 扎实创新每一步, 先人一步快人一步。 2023年全球科技行业最火的莫过于生成式AI,即Artificial Intelligence Generated Content。在迈向生成式AI的道路上,虽然说不上千军万马,但是国内…

Redis - hash 哈希表

前言 ⼏乎所有的主流编程语⾔都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组、映射。在 Redis 中,哈希类型是指 value 本⾝⼜是⼀个键值对结构,形如 key "key",value { { fiel…

java设计模式(2)---六大原则

设计模式之六大原则 这篇博客非常有意义,希望自己能够理解的基础上,在实际开发中融入这些思想,运用里面的精髓。 先列出六大原则:单一职责原则、里氏替换原则、接口隔离原则、依赖倒置原则、迪米特原则、开闭原则。 一、单一职…

Linux环境基础开发工具yum,vim使用

目录 1.Linux 软件包管理器 yum1.1什么是软件包1.2关于 rzsz1.3注意事项1.4查看软件包1.5如何安装软件1.6如何卸载软件 2.Linux开发工具2.1Linux编辑器-vim使用2.1.1vim的基本概念2.1.2vim的基本操作2.1.3vim正常模式命令集2.1.4vim末行模式命令集2.1.5vim操作总结 2.2简单vim配…

成功案例|全基因组测序+GWAS联合分析揭示不同种族帕金森病的遗传同质性和异质性

发表期刊:npj Parkinson’s Disease 影响因子:8.7 测序方式:WGS 研究对象:人 1 研究背景 帕金森病(PD)是一种常见的与年龄相关的神经退行性疾病,其特征是运动迟缓、姿势不稳定、僵硬和静息…

面试八股——redis——缓存——缓存穿透、击穿、雪崩

HR:你在项目中的那些场景用到了redis? 1. 缓存穿透问题 (项目中使用的方法) 2. 缓存击穿 解决办法1:加互斥锁。大量并发时,先让一个人去查,其他人等着。这样剩下人就可在缓存直接获取值。&#…

软件应用,麻将馆棋牌室计时计费管理系统软件,在计时的时候可以使用灯控器智能控灯

软件应用,麻将馆棋牌室计时计费管理系统软件,在计时的时候可以使用灯控器智能控灯 一、前言 以下软件操作教程以佳易王棋牌计时计费软件V18.0为例说明,其他版本可以参考 件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 …

Perfetto Trace抓取

1. Perfetto简介 Perfetto 是一个用于 Android 系统的性能跟踪工具,可以帮助开发者分析系统性能和调试问题。 Perfetto 是 Android 10 中引入的全新平台级跟踪工具。这是适用于 Android、Linux 和 Chrome 的更加通用和复杂的开源跟踪项目。 在低于Android R的版本上…

高性价比不入耳运动耳机哪个牌子好?精心筛选五大高赞好物推荐

在现在的时代运动耳机已成为我们不可或缺的伴侣,而在众多的运动耳机品牌中,选择一款高性价比、佩戴舒适且不入耳的款式,往往能让我们在运动过程中享受更加纯粹的音乐体验,接下来,就让我们一起探索那些备受好评的不入耳…

RobotFrameWorkRIDE失败重试

一、方法一:修改源码 【方式】https://blog.csdn.net/qq_15158911/article/details/119077562 二、方式二:使用插件 【需要环境】robotframework>4.1Python>3.8RobotFrameWorkRIDE2.X 【操作】 1、安装robotframework-retryfailed pip insta…

CleanMyMac X 4.15.1 for Mac 最新中文破解版 系统优化垃圾清理工具

CleanMyMac X for Mac 是一款功能更加强大的系统优化清理工具,相比于 CleanMyMac 4.15.1来说,功能增加了不少,此版本为4.15.1官方最新中英文正式破解版本,永久使用,解决了打开软件崩溃问题,最新版4.15.1版本…

Java后端项目性能优化实战-群发通知

背景 公司群发通知模块性能存在问题,我进行全面的系统调优,系统处理能力大幅提升。 原发送流程 优化后的发送流程 优化的点 说明:以下问题基本都是压测过程遇到的,有些问题普通的功能测试暴露不了。优化目标:保证高…

Transformer的前世今生 day07(Masked Self-Attention

Masked Self-Attention 掩码自注意力 由于NLP中的生成模型,是一个一个的生成单词, 所以为了让自注意力也实现这个过程,就设计了掩码自注意力 掩码:在自注意力机制中,每个输入位置都会与其他位置进行注意力计算&#x…

Maven从零到放弃:文档学习

学习背景: Maven一直在使用,自己也构建过相应的项目。也对常用的配置和命令有一些了解,也处理过一些相关的问题。例如:项目缺少依赖;版本冲突或其他构建失败的问题。但是一直没有进行系统性的学习。 链接:…

【暴刷力扣】11. 盛最多水的容器

11. 盛最多水的容器 题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xf…

Python进阶——数据分析案例

一、数据内容分析 二、需求分析 三、实现步骤 1. 设计一个类,可以完成数据的封装 2. 设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能 3. 读取文件,生产数据对象 4. 进行数据需求的逻辑计算 5. 通过PyEcharts进行…

陪诊APP:温暖每一程的健康守护者

在快节奏的现代生活中,我们时常面临健康问题的困扰。无论是日常的体检,还是突发的疾病,就医过程中的种种不便往往让我们感到力不从心。而这时,一款贴心、专业的陪诊APP应运而生,为您的健康之旅提供全方位的陪伴与支持。…

【2024.3.25练习】约瑟夫环

题目描述 题目分析 这种很有规律性的数学题适合寻找递推关系。设为人数为时的答案,在排出第一人(即序号为)时,该题目可变成求,但是由于是从第人开始算,即得到递推关系式: 我的代码 #include &…

【文档智能 LLM】LayoutLLM:一种多模态文档布局模型和大模型结合的框架

前言 传统的文档理解任务,通常的做法是先经过预训练,然后微调相应的下游任务及数据集,如文档图像分类和信息提取等,通过结合图像、文本和布局结构的预训练知识来增强文档理解。LayoutLLM是一种结合了大模型和视觉文档理解技术的单…

真的睡错了!MLILY梦百合“别睡硬床”发布会传递正确睡眠观

3月21日,MLILY梦百合召开了“别睡硬床”线上发布会,梦百合家居董事长倪张根在世界睡眠日这个特殊时间点发表演讲,传递正确睡眠观念,希望引起国人关注,正视睡眠误区,告别传统硬床。同时希望邀请到更多医生、专家、行业学者,和MLILY梦百合一起共同呼吁“别睡硬床”, 让更多人了解…