C/C++校招面试常考问题

8 篇文章 2 订阅

1、虚函数实现机制?

一个virtual函数的类具有一个虚函数表,且该类的每一个对象都有一个虚指针,指向该类的虚函数表。运行的时候,通过对象自己的虚指针来索引正确的虚函数来执行。若基类中虚函数的返回类型为基类型的指针或者引用,则派生类中override这个虚函数的时候需要将返回类型改为派生类类型的引用或者指针。

2、有了malloc/free为什么还要new/delete?

malloc/free是C/C++中的标准库函数,new/delete是C++中的运算符;它们都可以用来申请和释放动态内存;对于非内部数据类型,光用malloc/new是无法满足需求的;对象在构建的时候会自动调用构造函数,在消亡之前会自动调用析构函数;由于malloc和new是库函数,不在编译器的控制权限之内,所以不能将构造函数和析构函数的工作给它完成。所以C++需要一个完成动态构造和分配内存的new和一个能完成清理和释放内存的delete。那么为什么不将malloc和new删除掉呢,因为C++程序需要经常调用C函数,而且C程序只能调用malloc和free

3、overload 、override、 hide三者的区别?(重载、覆盖、隐藏)

(1)overload

重载函数的参数的个数、顺序、类型不同,virtual可有课可无,返回类型不能最为重载条件

(2)override

派生类覆盖基类的方法

基类和派生类的函数必须名字相同,参数相同,且必须要有virtual关键字

(3)hide

派生类中与基类中的函数名字相同但是参数不同,这种情况下,无论是不是有virtual,派生类的函数都会隐藏基类的方法;

如果派生类的函数与基类的函数名字相同参数相同,但是没有virtual,此时也是属于hide

4、指针与数组的区别?

数组可以在静态存储区被创建也可以在堆上,也可以在栈上创建;指针可以随时指向任意类型的内存块

使用sizeof运算符可以计算出一个数组的长度,但是sizeof只能求出指针类型的大小

5、构造函数为什么不能是虚函数?

(1)虚函数都被存放在一个虚函数表里,虚函数表其实是存放在对象的内存空间里,如果构造函数是虚的,就需要通过vtable调用,对象还没有构造出来,内存空间还没有,怎么找vtable,又如何调用呢?

(2)虚函数是通过父类的指针或者引用调用虚函数的时候可以调用子类的对应的虚函数;而构造函数是在创建父类对象的时候自动调用的,不可能通过父类的指针或者引用去调用,因此构造函数不能是虚函数

6、smart pointer实现原理?

一种通用的实现技术就是使用引用级数(reference count),智能指针将一个计数器与一个对象相关联,引用计数跟踪该类有多少个对象共享同一个指针。

7、含参数的宏与函数的优缺点?

宏:

优点:在预处理阶段完成,不占用编译时间,同时减去了函数调用的开销,运行效率较高

缺点:不进行类型检查,多次宏替换导致代码体积膨胀,而且由于宏基本上是字符串替换,故可能会因为一些参数的作用导致得出错误结果

函数:

优点:没有带参数的宏可能带来的副作用,进行类型检查,正确性较高

缺点:函数调用需要参数、返回地址的进出栈,效率没有宏高

8、宏与枚举的区别?

宏定义常量不分配内存,而枚举是定义变量的一种方式

宏和枚举的主要区别在于作用的时期和存储的形式不同,宏是在预处理阶段进行替换工作,程序运行过程中宏已经不存在;枚举是在程序运行之后起作用的,枚举常量存储在静态存储区,宏占用代码段空间,枚举除了占用空间还消耗CPU资源

9、什么时候需要常量引用?

既需要利用引用提高程序的效率,又保证在数据不被更改,就要使用常引用

10、如何判断一段程序是由C编译的还是C++编译的?

#ifdef __cplusplus//C++编译器定义了-cplusplus
cout << "by c++";
#else
cout << "by c";
#endif
11、C++和C里面的struct区别?
在C++里面class和struct的区别就是:class成员的默认权限是private,struct的是public;还有就是class可以定义模板但是struct不行
12、堆栈溢出一般是什么内存导致的?
(1)没有对数组进行边界检查,导致数组越界

(2)没有回收垃圾资源,导致内存泄露,最后内存耗尽

(3)循环的递归调用或者太深层次的递归调用

(4)使用占用内存过大的类型的局部变量

13、构造函数可以是内联的

14、const和static的作用?

static关键字:

(1)函数体内的static变量的作用范围是整个函数体,该变量的内存只被分配一次,因此其值在下次调用的时候还能维持上次的值

(2)类中的static变量属于整个类对象所有,对于类的所有对象都只有一份复制

(3)类中的static成员函数属于整个类所有,这个函数不接受this指针,也只能访问static成员

const关键字:

(1)想要避免一个变量被改变,可以加const修饰,在定义的时候还需要对const变量初始化,否则以后没法改变

(2)类的成员函数,若被const修饰,那么这个函数就是一个常量函数,保证不修改类的成员变量

15、注意sizeof不是函数是运算符,在计算变量大小的时候可以省略括号,但是在计算类型的大小的时候不能省略

16、例如int arr[3],a和&a虽然值相等,但是两者的含义不相同,a是数组首地址,即a[0]的地址,&a是整个数组对象的地址,&a+1,表示sizeof(int)*3,即a[3],已经越界了

17、类中的const成员变量,在构造函数里初始化只能在初始化列表初始化,不能在函数体初始化;const static 成员只能在类外初始化,记得要在变量前加上类名作用域;static成员变量也是在类外初始化,但是不能在变量前加上static关键字,同时也是需要加上作用域的

18、定义类的成员变量的时候mutable关键字的作用?

在const方法中修改成员变量的时候,防止出错;

19、C++中explicit关键字的作用?

禁止将构造函数作为转换函数,即禁止构造函数进行自动隐式类型转换

20、C++的多态性?

C++里的多态性分为静多态和动多态

静多态:编译阶段确定执行什么,主要通过函数重载和运算符重载实现

动多态:运行时确定执行什么,主要通过虚函数实现

21、在对一个类进行sizeof运算的时候,一个类里面的static变量不占内存,所有的虚函数都只占用4个字节(32位),因为所有的函数都存放在vtable中,只有一个vpointer指向vtable

22、引用和指针的区别?

(1)引用声明的时候必须要进行初始化,即绑定对象变量(不能绑定一个常量上,如int &r=1);但指针变量可以在任何时候初始化

(2)一旦一个引用指向一个对象之后,它就不能改变为指向另外一个对象;但是指针可以在任何时候指向任何对象

(3)不能有NULL引用

(4)引用实际上是变量的别名,指针是指向某内存,它的内容就是内存的地址

23、面试中经常让写的一个函数strcpy

这个函数看起来很easy,但是刚接触编程的时候还是写不出来,菜。。。;

我们在手撕这个函数的代码的时候要注意很多地方,我先贴出代码,然后再解释

char * mystrcpy(char *str1, char *str2)
{
if (str1 == nullptr || str2 == nullptr)//1
return " exception";
char* Address_str = str2;
while ((*str1++ = *str2++!) = '\0');//2
return Address_str;
}

(1)我们首先需要判断一下两个字符串是不是为null,体现代码的健壮性

(2)需要判断一下字符串结束的条件

24、在C/C++中<<和>>除了可以表示输入输出运算符还可以表示位运算分别是左移和右移

例如:

int i = 1 << 4;
cout << i;

此时i=16;实际上是先将i转换为二进制,然后在向左移4位得到的结果就是16

25、数组和链表的区别

(1)数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少或不插入和删除元素,就应该用数组。

(2)链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表数据结构了。

26、面向对象的三个基本特征是:封装、继承、多态



--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

暂时先更新到这里,如果还有需要补充,我会回来补充的












  • 2
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值