C++面试干货---带你梳理常考的面试题(一)

顾得泉:个人主页

个人专栏:《Linux操作系统》 《C++从入门到精通》  《LeedCode刷题》

键盘敲烂,年薪百万!


1.C和C++的区别

       1.语法和特性:C是一种过程式编程语言,而C++是一种面向对象编程语言。C++在C的基础上增加了许多新的语法和特性,如类、对象、继承、多态等,使得代码更加模块化和可重用。

       2.扩展性:C++可以使用C的代码,因为C++是C的超集,但C不能使用C++的代码。C++还提供了许多新的库和功能,使得开发更加方便和高效。

       3.内存管理:C++引入了自动内存管理的概念,通过构造函数和析构函数来管理对象的生命周期。而C需要手动管理内存,使用malloc和free等函数进行内存分配和释放。

       4.异常处理:C++支持异常处理机制,可以捕获和处理程序运行过程中的异常情况。而C没有内置的异常处理机制,需要通过返回错误码或者使用全局变量来处理异常情况。

       5.标准库:C++标准库提供了丰富的功能和数据结构,如容器、算法、字符串处理等。而C的标准库相对较小,主要包含了一些基本的输入输出函数和数学函数。


2.指针和引用的区别

       1.定义方式:指针是一个变量,存储的是另一个变量的内存地址,通过使用"*“来声明和操作指针。引用是一个别名,它直接绑定到另一个变量,通过使用”&"来声明和操作引用。

       2.空值:指针可以为空,即指向空地址或者未初始化的指针。而引用必须在定义时初始化,并且不能为空。

       3.内存操作:指针可以通过解引用操作符"*"来访问所指向的内存地址中的值。而引用则直接访问所绑定变量的值,无需解引用。

       4.重新赋值:指针可以被重新赋值,可以指向不同的内存地址。而引用一旦绑定到一个变量,就不能再绑定到其他变量。

       5.空间占用:指针需要占用额外的内存空间来存储地址信息。而引用不需要额外的内存空间,它只是原变量的别名。

       5.函数参数传递:指针可以作为函数参数传递,通过传递地址来实现对实参的修改。而引用也可以作为函数参数传递,通过引用传递来实现对实参的修改。


3.malloc和new的区别

共同点

       都是从堆上申请空间,并且需要用户手动释放

不同点

       1.malloc是函数,new是操作符

       2.malloc申请的空间不会初始化,new可以初始化

       3.malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可

       4.malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

       5.malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

       6.申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理


4.delete 和 delete[] 的区别

       1.delete用于释放通过new运算分配的单个对象的内存,而delete[]用于释放通过new[]运算符分配的数组对象的内存。

       2.delete只能释放通过new运算符分配的单个对象的内存,而不能释放通过new[]运算符分配的数组对象的内存。同样,delete[]只能释放通过new[]运算符分配的数组对象的内存,而不能释放通过new运算符分配的单个对象的内存。

       3.delete会调用被删除对象的析构函数,以确保对象被正确地清理和销毁。而delete[]会调用数组中每个元素的析构函数,然后再释放整个数组的内存。

       4.如果使用delete来释放通过new[]分配的数组对象的内存,会导致未定义行为。同样,如果使用delete[]来释放通过new分配的单个对象的内存,也会导致未定义行为。


5.八大排序的时间复杂度

冒泡排序:

        最好情况时间复杂度:O(n),当输入数据已经有序时。

        最坏情况时间复杂度:O(n^2),当输入数据逆序时。

        平均情况时间复杂度:O(n^2)。

选择排序:

        最好情况时间复杂度:O(n^2)。

        最坏情况时间复杂度:O(n^2)。

        平均情况时间复杂度:O(n^2)。

插入排序:

        最好情况时间复杂度:O(n),当输入数据已经有序时。

        最坏情况时间复杂度:O(n^2),当输入数据逆序时。

        平均情况时间复杂度:O(n^2)。

希尔排序:

        最好情况时间复杂度:O(n log n)。

        最坏情况时间复杂度:取决于步长序列的选择,最坏情况下为O(n^2)。

        平均情况时间复杂度:取决于步长序列的选择,一般为O(n log n)。

归并排序:

        最好情况时间复杂度:O(n log n)。

        最坏情况时间复杂度:O(n log n)。

        平均情况时间复杂度:O(n log n)。

快速排序:

        最好情况时间复杂度:O(n log n),当每次划分都能均匀地将数组分成两部分时。

        最坏情况时间复杂度:O(n^2),当输入数据已经有序时。

        平均情况时间复杂度:O(n log n)。

堆排序:

        最好情况时间复杂度:O(n log n)。

        最坏情况时间复杂度:O(n log n)。

        平均情况时间复杂度:O(n log n)。

计数排序:

        最好情况时间复杂度:O(n + k),其中k是输入数据的范围。

        最坏情况时间复杂度:O(n + k)。

        平均情况时间复杂度:O(n + k)。


6.const用法

       1.声明常量:可以使用const关键字声明一个常量,一旦被声明为常量,其值就不能再被修改。

例如:

const int MAX_VALUE = 100; 

       在这个例子中,MAX_VALUE被声明为一个常量,其值为100,不能再被修改。

       2.修饰函数参数:const可以用来修饰函数的参数,表示该参数在函数内部不会被修改。这样做可以增加代码的可读性,并且可以防止意外修改参数的值。

       例如:

void print(const int num);

        在这个例子中,print函数的参数num被声明为const,表示在函数内部不会修改num的值。

       3.修饰成员函数:const可以用来修饰类的成员函数,表示该成员函数不会修改类的成员变量。这样做可以使得对象在调用该成员函数时不会被修改。

       例如:

 class MyClass 
{ int num; 
public: int getNum() const; 
};

       在这个例子中,getNum函数被声明为const,表示该函数不会修改类的成员变量num。

       4.修饰指针:const可以用来修饰指针,表示指针所指向的值不能被修改。

有两种情况:

        const修饰指针本身:表示指针本身的值不能被修改。例如:const int* p;

        const修饰指针所指向的值:表示指针所指向的值不能被修改。例如:int* const p;


7.什么是野指针

       野指针是指指向无效内存地址的指针。一个指针被赋值为一个未初始化的变量、已经释放的内存地址或者超出作用域的局部变量的地址时,就会产生野指针。野指针的存在可能导致程序崩溃、数据损坏或者安全漏洞。

野指针通常出现在以下情况下:

       1.指针未初始化:在定义指针变量后,没有为其分配有效的内存空间。

       2.指针指向已释放的内存:在释放了某个内存块后,仍然保留了指向该内存块的指针。

       3.指针超出作用域:在函数或代码块结束后,指针仍然存在并被使用。

为了避免野指针的问题,我们可以采取以下几种措施:

       1.初始化指针:在定义指针变量时,将其初始化为nullptr或者有效的内存地址。

       2.及时释放内存:在使用完动态分配的内存后,及时使用delete或者free函数释放内存,并将指针置为nullptr。

       3.避免指针超出作用域:确保指针的生命周期与其所指向的对象的生命周期相匹配。


8.sizeof 和 strlen 的区别

       sizeof是一个运算符,用于计算数据类型或变量所占用的字节数。它可以用于任何数据类型,包括基本数据类型(如int、float等)和自定义数据类型(如结构体、数组等)。sizeof返回的是一个无符号整数值,表示所占用的字节数。

       strlen是一个函数,用于计算字符串的长度,即字符串中字符的个数(不包括字符串末尾的空字符’\0’)。它只能用于字符串类型(即以’\0’结尾的字符数组),不能用于其他数据类型。

区别:

       参数类型:sizeof可以接受任何数据类型或变量作为参数,而strlen只能接受字符串类型的参数。

       返回值类型:sizeof返回的是一个无符号整数值,表示所占用的字节数;strlen返回的是一个整数值,表示字符串中字符的个数。

       计算方式:sizeof在编译时进行计算,而strlen在运行时遍历字符串来计算长度。

       适用范围:sizeof适用于计算任何数据类型或变量的大小;strlen适用于计算以’\0’结尾的字符串的长度。


9.什么叫做结构体对齐

       结构体对齐是指在内存中如何排列结构体的成员变量,以便于提高访问效率和节省内存空间。在结构体中,成员变量的排列顺序和对齐方式是由编译器决定的。

       结构体对齐的原则是,结构体的起始地址必须是其最宽基本类型成员大小的整数倍。这样可以保证结构体的每个成员变量都能够被正确地访问到,而不会出现对齐错误导致的访问异常或性能下降。

对于结构体的对齐方式,一般有两种常见的方式:

       1.默认对齐方式:按照成员变量的定义顺序依次排列,每个成员变量按照其自身大小进行对齐。

       2.指定对齐方式:可以使用编译器提供的特定语法来指定结构体的对齐方式,例如使用#pragma pack(n)来指定对齐字节数。

       需要注意的是,结构体对齐可能会导致内存空间的浪费。因为为了满足对齐要求,编译器可能会在结构体成员之间插入一些填充字节,以保证对齐。为了减少内存浪费,可以通过调整结构体成员的顺序或者使用特定的对齐方式来优化结构体对齐


10.strcpy和memcpy的区别

功能不同:

       strcpy函数用于将一个字符串(以’\0’结尾)从源地址复制到目标地址,包括字符串的结束符。

       memcpy函数用于将一段内存块从源地址复制到目标地址,不关心内存块的内容是否是字符串。

参数不同:

       strcpy函数接受两个参数,分别是目标地址和源地址的指针。

       memcpy函数接受三个参数,分别是目标地址、源地址和要复制的字节数。

安全性不同:

       strcpy函数在复制字符串时不会检查目标地址的空间是否足够,容易导致缓冲区溢出的安全问题。

       memcpy函数需要指定要复制的字节数,可以确保不会发生缓冲区溢出。

返回值不同:

       strcpy函数返回目标地址的指针,即复制后的字符串的起始地址。

       memcpy函数没有返回值。

适用场景不同:

       strcpy函数适用于字符串的复制操作,常用于处理以’\0’结尾的字符串。

       memcpy函数适用于任意内存块的复制操作,可以复制任意类型的数据。


 结语:关于本次常见面试题的梳理到这里就结束了,希望本篇文章的分享会对大家的面试带来些许帮助,如果大家有什么问题,欢迎大家在评论区留言,最后祝愿每位伙伴都能找到心意的工作。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 STM32U5 片内温度传感器正确测算温度

目录预览 1、引言 2、问题 3、小结 01 引言 STM32 在内部都集成了一个温度传感器,STM32U5 也不例外。这个位于晶圆上的温度传感器虽然不太适合用来测量外部环境的温度,但是用于监控晶圆上的温度还是挺好的,以防止芯片过温运行。 02 问题…

Doris实战——银联商务实时数仓构建

目录 前言 一、应用场景 二、OLAP选型 三、实时数仓构建 四、实时数仓体系的建设与实践 4.1 数仓分层的合理规划 4.2 分桶分区策略的合理设置 4.3 多源数据迁移方案 4.4 全量与增量数据的同步 4.5 离线数据加工任务迁移 五、金融级数仓稳定性最佳实践 5.1 多租户资…

【MySQL】数据库中常用的函数

目录 聚合函数COUNT()函数的多种用法COUNT(*)COUNT(主键)COUNT(1)COUNT(常量)COUNT(非主键)COUNT(distinct(字段)) COUNT()函数小结 字符函数length(str)函数:获取参数值的字节个数concat(str1,str2,...)函数:字符串拼接upper(str)、lower(str)函数:大小…

【YOLO v5 v7 v8 小目标改进】新CNN架构 InceptionNeXt:怎么让大卷积核既好用又快

新CNN架构 InceptionNeXt:怎么让大卷积核既好用又快 提出背景问题: 如何提高大核心卷积的效率,同时保持或提升模型性能? 改进思路MetaNeXtInception深度卷积InceptionNeXt 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔改 提出背景 论文&am…

【MySQL】mvcc以及三个重要日志

🍎个人博客:个人主页 🏆个人专栏:【】数据库 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 MVCC关键概念: MVCC机制的优点: 三个重要的日志: 重做日志: 回滚日志&am…

从金蝶云星空到四化智造MES(API)通过接口配置打通数据

从金蝶云星空到四化智造MES(API)通过接口配置打通数据 数据源平台:金蝶云星空 金蝶K/3Cloud(金蝶云星空)是移动互联网时代的新型ERP,是基于WEB2.0与云技术的新时代企业管理服务平台。金蝶K/3Cloud围绕着“生态、人人、…

c语言的数据结构:队列

1.队列存在的实现方式及其存在意义 1.1为什么队列使用单链表实现更好 动态内存分配:链表在C语言中通常使用动态内存分配,这意味着可以在运行时根据需要动态地添加或删除节点。这对于实现一个动态大小的队列非常有用,因为队列的大小可以在运…

外链工具,热门的外链工具

在网络推广和搜索引擎优化中,外链工具是提升网站排名和曝光度的关键。本文将介绍一些外链工具,以及它们的作用和用途。 外链工具有哪些? 147SEO工具: 147SEO工具是一款提升网站收录的外链工具,用户可以通过147SEO工具…

antvX6 - Vue自定义节点,并实现多种画布操作,拖拽、缩放、连线、双击、检索等等

一、 首先 antv x6 分为两个版本 低版本和高版本 我这里是使用的2.0版本 并且搭配了相关插件 例如:画布的图形变换、地图等 个人推荐 2.0版本,高版本配置多,可使用相关插件多,但是文档描述小,仍在更新, 低…

JavaWeb之 Web概述

目录 前言1.1 Web和 JavaWeb的概念1.2 JavaWeb技术栈1.2.1 B/S架构1.2.2 静态资源1.2.3 动态资源1.2.4 数据库1.2.5 HTTP协议1.2.6 Web服务器 1.3 JavaWeb 学习内容 前言 博主将用 CSDN 记录 Java 后端开发学习之路上的经验,并将自己整理的编程经验和知识分享出来&a…

yolo目标检测实战

该博客主要介绍了: 1. 如何制作yolo目标检测数据集 2.如何在自己的数据集上训练yolo 3.训练好后的模型如何进行推理 1.数据标注 关于数据如何标注,请查看这篇博文 2.数据集目录结构 重点关注红框内部的结构 images: 图片目录 images/train: 训练集…

Zookeeper学习1:概述、安装、应用场景、集群配置

文章目录 概述安装LinuxWindows 配置参数集群参考配置文件配置步骤流程启动 概述 Zookeeper: 为分布式框架组件提供协调服务的中间件 【类似:文件系统通知机制】 负责存储上下层应用关系的数据以及接收观察者注册监听,一旦观察查关心的数据发…