十八万字吐血整理的C/C++、嵌入式常见面试题!!!!

欢迎订阅,希望能点个赞!!!!

正在持续更新!!!!!欢迎探讨!!!

完整专栏地址:https://blog.nowcoder.net/zhuanlan/gmPWX0


相关知识点都能零星在网上找到,这个文章系列将目前遇到的所有常见面试问题进行一个汇总。

文中很多资料避免不了从网上或是其他复习资料里收集整理,十分感谢前辈的辛勤付出,如果存在侵权请一定联系我进行删除

也有相当一部分是本人在经历提前批以及秋招的过程中遇到和验证过的。


系列文章PDF下载地址:《最全C_C++及嵌入式软开面试题宝典.pdf》


131、重载运算符?

1、我们只能重载已有的运算符,而无权发明新的运算符;对于一个重载的运算符,其优先级和结合律与内置类型一致才可以;不能改变运算符操作数个数;

2、这几种 . :: ?: sizeof typeid ** 不能重载;

3、两种重载方式,成员运算符和非成员运算符,成员运算符比非成员运算符少一个参数;

4、下标运算符、箭头运算符必须是成员运算符;

5、引入运算符重载,是为了实现类的多态性;

6、当重载的运算符是成员函数时,this绑定到左侧运算符对象。成员运算符函数的参数数量比运算符对象的数量少一个;至少含有一个类类型的参数;

7、从参数的个数推断到底定义的是哪种运算符,当运算符既是一元运算符又是二元运算符(+,-,*,&);

8、下标运算符必须是成员函数,下标运算符通常以所访问元素的引用作为返回值,同时最好定义下标运算符的常量版本和非常量版本;

9、箭头运算符必须是类的成员,解引用通常也是类的成员;重载的箭头运算符必须返回类的指针;

132、函数重载函数匹配原则

将函数匹配分为三个阶段,确定候选函数,确定可行函数,确定最佳匹配函数。

1.确定候选函数:需要和被调用的函数同名,并且其声明在调用点可见。

2.确定可行函数:本次调用传入的实参能够被候选函数使用。它要满足两个条件,一是形参数量和实参数量相同,二是每个实参的类型和对应形参类型相同或者能够转换成形参的类型。

3.寻找最佳匹配:最佳匹配最基本的思想是认为,实参类型越接近,它们就越匹配。

133、定义和声明的区别

1.如果是指变量的声明和定义从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存。而定义就是分配了内存。

2.如果是指函数的声明和定义声明:一般在头文件里,对编译器说:这里我有一个函数叫function()让编译器知道这个函数的存在。定义:一般在源文件里,具体就是函数的实现过程 写明函数体。

134、全局变量和static变量的区别

1、全局变量(外部变量)的说明之前再冠以static就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。

2.这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个原文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。static全局变量与普通的全局变量的区别是static全局变量只初始化一次,防止在其他文件单元被引用。

135、static函数与普通函数有什么区别?

在函数的返回类型前加上关键字static,函数就被定义成为静态函数。普通函数的定义和声明默认情况下是extern的,但静态函数被限定在源码文件中,只在声明他的文件当中可见,不能被其他文件所用。

普通函数:

static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。

类成员函数:

区别1:静态成员函数实际上是一个全局函数,不依赖一个类的对象,属于类,不创建对象也可调用。

普通成员函数依赖一个类的对象,也就是它有一个隐藏的调用参数(this)指针,必须指向一个类的对象。

区别2:静态函数只能访问类中的静态成员变量;

区别3:如果类的成员函数想作为回调函数来使用,如创建线程等,一般只能将它定义为静态成员函数才行。

定义静态函数有以下好处:

<1> 其他文件中可以定义相同名字的函数,不会发生冲突。

<2> 静态函数不能被其他文件所用。

136、静态成员与普通成员的区别

1.生命周期

静态成员变量从类被加载开始到类被卸载,一直存在;

普通成员变量只有在类创建对象后才开始存在,对象结束,它的生命期结束;

2.共享方式

静态成员变量是全类共享;普通成员变量是每个对象单独享用的;

3.定义位置

普通成员变量存储在栈或堆中,而静态成员变量存储在静态全局区;

4.初始化位置

普通成员变量在类中初始化;静态成员变量在类外初始化;

5.默认实参

可以使用静态成员变量作为默认实参,

137、说一下理解 ifdef endif

1.一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。

2.条件编译命令最常见的形式为:

#ifdef 标识符

程序段1

#else

程序段2

#endif

它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。其中#else部分也可以没有,即:
#ifdef

程序段1

#denif

3.在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件上时,就会出现大量“重定义”错误。在头文件中使用#define、#ifndef、#ifdef、#endif能避免头文件重定义。

138、隐式转换,如何消除隐式转换?

1.C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的。所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为。很多时候用户可能都不知道进行了哪些转换

2.C++面向对象的多态特性,就是通过父类的类型实现对子类的封装。通过隐式转换,你可以直接将一个子类的对象使用父类的类型进行返回。在比如,数值和布尔类型的转换,整数和浮点数的转换等。某些方面来说,隐式转换给C++程序开发者带来了不小的便捷。C++是一门强类型语言,类型的检查是非常严格的。

3.基本数据类型,基本数据类型的转换以取值范围的作为转换基础(保证精度不丢失)。隐式转换发生在从小->大的转换中。比如从char转换为int。从int->long。自定义对象 子类对象可以隐式的转换为父类对象。

4.C++中提供了explicit关键字,在构造函数声明的时候加上explicit关键字,能够禁止隐式转换。

5.如果构造函数只接受一个参数,则它实际上定义了转换为此类类型的隐式转换机制。可以通过将构造函数声明为explicit加以制止隐式类型转换,关键字explicit只对一个实参的构造函数有效,需要多个实参的构造函数不能用于执行隐式转换,所以无需将这些构造函数指定为explicit。

139、虚函数的内存结构,那菱形继承的虚函数内存结构呢

菱形继承的定义是:两个子类继承同一父类,而又有子类同时继承这两个子类。例如a,b两个类同时继承c,但是又有一个d类同时继承a,b类。

lsy注:由于这部分内容太多,一定移步博客:(讲解深入浅出,推荐!因为移过来的时候除了问题,点下面链接后搜一下“对象在内存中的布局”就行!)

https://blog.csdn.net/qq_41687938

140、多继承的优缺点,作为一个开发者怎么看待多继承

1.C++允许为一个派生类指定多个基类,这样的继承结构被称做多重继承。

2.多重继承的优点很明显,就是对象可以调用多个基类中的接口;

3.如果派生类所继承的多个基类有相同的基类,而派生类对象需要调用这个祖先类的接口方法,就会容易出现二义性

4.加上全局符确定调用哪一份拷贝。比如pa.Author::eat()调用属于Author的拷贝。

5.使用虚拟继承,使得多重继承类Programmer_Author只拥有Person类的一份拷贝。