C++语言面试八股文
- 是C++中一种用户自定义的数据类型,可以被用来存储不同类型的数据项。结构体的定义使用struct关键字,结构体的访问采用成员访问运算符(.)。
- 共同体是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型。即我们可以定义一个带有多个成员的共同体,但是任何时候只能有一个成员带有值。 共同体可以使用union定义,定义方式类似于结构体。
区别:
- 结构体的每个成员都有自己的独立地址,它们可以同时存在;而共同体中的所有成员占用同一段内存,它们不能同时存在。
- sizeof(struct)是内存对齐后所有成员长度的和;sizeof(union)是内存对齐后最长数据成员的长度。
2.程序的执行过程
- 预处理:根据以字符#开头的命令修改原始的c程序,比如#include<stdio.h>告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入程序文本中,将#define的变量替换等等,结果得到了另一个c程序,通常以.i作为文件扩展名。
- 编译:文本文件hello.i翻译成hello.s,它包含了一个汇编语言程序。汇编语言程序中的每条语句都以一种标准的文本格式确切的描述一条低级机器语言指令。
- 汇编:将汇编程序翻译为机器语言指令,把这些指令打包成可重定位目标程序(relocateble object program)的格式,并把结果保存在hello.o中。hello.o文件是二进制文件,因为他的字节编码是机器语言指令而不是ascii码。如果用文本编辑器打开hello.o会看到一堆乱码。
- 链接:比如hello中用到了printf函数,这是标准c库的函数,存在于一个名为printf.o的单独编译好的目标文件中,这个文件必须以某种方式合并到我们编译好的的目标文件中。链接器(ld)程序负责处理这种合并,结果得到hello文件,它是可执行目标文件,可以被加载到内存中,由系统执行。
3.静态编译和动态编译
- 动态编译的可执行文件需要附带一个的 动态链接库,在执行时,需要调用其对应动态链接库中的命令。所以其优点一方面是缩小了执行文件本身的体积,另一方面是加快了编译速度,节省了 系统资源。缺点一是哪怕是很简单的程序,只用到了链接库中的一两条命令,也需要附带一个相对庞大的链接库;二是如果其他计算机上没有安装对应的 运行库,则用动态编译的可执行文件就不能运行。
- 静态编译就是 编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库。所以其优缺点与动态编译的可执行文件正好互补。
4.c++特性
- 封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 类将成员变量和成员函数封装在类的内部,根据需要设置访问权限,通过成员函数管理内部状态、
- 继承:继承所表达的是类之间相关的关系,这种关系使得对象可以继承另外一类对象的特征和能力。 继承的作用:避免公用代码的重复开发,减少代码和数据冗余。
- 多态:多态性可以简单地概括为“一个接口,多种方法”,字面意思为多种形态。程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。比如函数重载、运算符重载、虚函数等
5.静态多态和动态多态
-
静态多态:也称为编译期间的多态,在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,如果有对应的函数就调用该函数,否则出现编译错误。
静态多态有两种实现方式:- 函数重载:包括普通函数的重载和成员函数的重载
- 函数模板的使用
- 动态多态:即运行时的多态,在程序执行期间(非编译期)判断所引用对象的实际类型,根据其实际类型调用相应的方法。
Vector底层实现和List底层实现
- vector底层是数组
- List底层是双向链表
Vector迭代器失效
- 前插会导致迭代器失效
- 当vector扩容的时候迭代器失效
vector的构成
vector 是C++标准库中的容器类,其可以理解为一个动态数组,其内部实现有三个指针:
- pointer _M_start;
- pointer _M_finish;
- pointer _M_end_of_storage;
分别代表其使用内存的开始、结束,以及分配的内存结尾,其中
- _M_finish - _M_start 对应 sizeof();
- _M_end_of_storage - _M_start 对应 capacity() ;
vector 通过配置比其所容纳的元素所需更多的内存,即先预留足够空间,避免二次分配,从而提高 vector 的性能。
因此,sizeof(vec) 的大小等于 3 x 8 = 24。
extern和static
extern和static两者之间是有一种相克的关系:用了extern的不能用static,用了static的不能用extern,extern是声明让别的文件中能够使用,static修饰之后的函数或全局变量不能被其他文件使用。
typedef和define有什么区别
typedef和define都是替一个对象取一个别名,以此增强程序的可读性,区别如下:
(1)原理不同
#define是C语言中定义的语法,是预处理指令,在预处理时进行简单而机械的字符串替换,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。
typedef是关键字,在编译时处理,有类型检查功能。它在自己的作用域内给一个已经存在的类型一个别名,但不能在一个函数定义里面使用typedef。用typedef定义数组、指针、结构等类型会带来很大的方便,不仅使程序书写简单,也使意义明确,增强可读性。
(2)功能不同
typedef用来定义类型的别名,起到类型易于记忆的功能。另一个功能是定义机器无关的类型。如定义一个REAL的浮点类型,在目标机器上它可以获得最高的精度:typedef long double REAL, 在不支持long double的机器上,看起来是这样的,typedef double REAL,在不支持double的机器上,是这样的,typedef float REAL
#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。
(3)作用域不同
#define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,而typedef有自己的作用域。
(4)对指针的操作不同
常量指针和指针常量的区别
常量指针和指针常量的区别_飞翔的荷兰橙的博客-CSDN博客_指针常量和常量指针
const int *p常量指针,并且这个指针是一个指向常量的指针,指针指向的变量的值不可通过该指针修改,但是指针指向的值可以改变。
int * const p;指针常量,指针里的内容可以变,指向的地址不能变
struct和class的区别,struct与union的区别
【C++】struct和class的区别_忽晴忽雨江湖的博客-CSDN博客_struct和class的区别
内联函数inLine
inline函数的总结_WhiteJunior的博客-CSDN博客_inline函数
delete与 delete []区别 都是用来调用析构函数的:
(1)delete只会调用一次析构函数,delete[]会调用每一个成员的析构函数。
(2)delete与new配套,delete []与new []配套,用new分配的内存用delete删除用new[]分配的内存用delete[]删除
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了