数据结构论坛

首页 » 分类 » 分类 » c面试常见问题汇总建议收藏
TUhjnbcbe - 2023/6/1 21:42:00
白癜风诚信医疗 http://baidianfeng.39.net/a_bdfys/180504/6213655.html

面试中常见的C++面试题总结,快来看看,是否对你有帮助!

1.指针和引用的区别?

(1)指针有自己的一块空间,而引用只是一个别名;

(2)使用sizeof看一个指针的大小为4字节(32位,如果要是64位的话指针为8字节),而引用则是被引用对象的大小;

(3)指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象的引用;

(4)作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象;

(5)指针在使用中可以指向其他对象,但是引用只能是一个对象的引用,不能被改变;

(6)指针可以是多级,而引用没有分级;

(7)如果返回动态分配内存的对象或者内存,必须使用指针,引用可能引起内存泄漏。

2.堆栈的区别?

(1)堆栈空间分配区别:

栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;

堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

(2)堆栈的缓存方式区别

栈:是内存中存储值类型的,大小为2M(window,linux下默认为8M,可以更改),超出则会报错,内存溢出;

堆:内存中,存储的是引用数据类型,引用数据类型无法确定大小,堆实际上是一个在内存中使用到内存中零散空间的链表结构的存储空间,堆的大小由引用类型的大小直接决定,引用类型的大小的变化直接影响到堆的变化。

(3)堆栈数据结构上的区别

堆(数据结构):堆可以被看成是一棵树,如:堆排序;

栈(数据结构):一种先进后出的数据结构。

3.new和delete是如何实现的,与malloc和free有什么异同?

new操作针对数据类型的处理,分为两种情况:

(1)简单数据类型(包括基本数据类型和不需要构造函数的类型)

简单类型直接调用operatornew分配内存;

可以通过new_handler来处理new失败的情况;

new分配失败的时候不像malloc那样返回NULL,它直接抛出异常(bad_alloc)。要判断是否分配成功应该用异常捕获的机制;

(2)复杂数据类型(需要由构造函数初始化对象)

new复杂数据类型的时候先调用operatornew,然后在分配的内存上调用构造函数。

delete也分为两种情况:

(1)简单数据类型(包括基本数据类型和不需要析构函数的类型)

delete简单数据类型默认只是调用free函数。

(2)复杂数据类型(需要由析构函数销毁对象)

delete复杂数据类型先调用析构函数再调用operatordelete。

与malloc和free的区别:

(1)属性上:new/delete是c++关键字,需要编译器支持。malloc/free是库函数,需要c的头文件支持。

(2)参数:使用new操作符申请内存分配时无须制定内存块的大小,编译器会根据类型信息自行计算。而mallco则需要显式地指出所需内存的尺寸。

(3)返回类型:new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,故new是符合类型安全性的操作符。而malloc内存成功分配返回的是void*,需要通过类型转换将其转换为我们需要的类型。

(4)分配失败时:new内存分配失败时抛出bad_alloc异常;malloc分配内存失败时返回NULL。

(5)自定义类型:new会先调用operatornew函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operatordelete函数释放内存(通常底层使用free实现)。malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。

(6)重载:C++允许重载new/delete操作符。而malloc为库函数不允许重载。

(7)内存区域:new操作符从自由存储区(freestore)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。其中自由存储区为:C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。

4.struct和class的区别?

(1)首先说一下C中的结构体和C++中的结构体的异同:

(2)C++中struct与class的区别:

内部成员变量及成员函数的默认访问属性:struct默认防控属性是public的,而class默认的访问属性是private的

继承关系中默认访问属性的区别:在继承关系,struct默认是public的,而class是private

class这个关键字还可用于定义模板参数,就等同于typename;而strcut不用与定义模板参数

5.define和const的区别?

(1)起作用的阶段:#define是在编译的预处理阶段起作用,而const是在编译、运行的时候起作用。

(2)作用的方式:const常量有数据类型,而宏常量没有数据类型,只是简单的字符串替换。编译器可以对前者进行类型安全检查。而对后者没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。

(3)存储的方式:#define只是进行展开,有多少地方使用,就替换多少次,它定义的宏常量在内存中有若干个备份;const定义的只读变量在程序运行过程中只有一份备份,const比较节省空间,避免不必要的内存分配,提高效率。

6.在c++中const和static的用法?

(1)static:

修饰全局变量:存储在静态存储区;未经初始化的全局静态变量自动初始化为0;作用域为整个文件之内。

修饰局部变量:存储在静态存储;未经初始化的局部静态变量会被初始化为0;作用域为局部作用域,但离开作用域不被销毁。

修饰静态函数:静态函数只能在声明的文件中可见,不能被其他文件引用

修饰类的静态成员:在类中,静态成员可以实现多个对象之间的数据共享,静态成员是类的所有对象中共享的成员,而不属于某一个对象;类中的静态成员必须进行显示的初始化

修饰类的静态函数:静态函数同类的静态成员变量一个用法,都是属于一个类的方法。而且静态函数中只可以使用类的静态变量。

(2)const:

修成类成员:在C++中,const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数;const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。

修饰类函数:该函数中所有变量均不可改变。

7.C++的顶层const和底层const?

底层const是代表对象本身是一个常量(不可改变);

顶层const是代表指针的值是一个常量,而指针的值(即对象的地址)的内容可以改变(指向的不可改变);

8.拷贝初始化和直接初始化,初始化和赋值的区别?

ClassTestct1(ab);这条语句属于直接初始化,它不需要调用复制构造函数,直接调用构造函数ClassTest(constchar*pc),所以当复制构造函数变为私有时,它还是能直接执行的。

ClassTestct2=ab;这条语句为复制初始化,它首先调用构造函数ClassTest(constchar*pc)函数创建一个临时对象,然后调用复制构造函数,把这个临时对象作为参数,构造对象ct2;所以当复制构造函数变为私有时,该语句不能编译通过。

ClassTestct3=ct1;这条语句为复制初始化,因为ct1本来已经存在,所以不需要调用相关的构造函数,而直接调用复制构造函数,把它值复制给对象ct3;所以当复制构造函数变为私有时,该语句不能编译通过。

ClassTestct4(ct1);这条语句为直接初始化,因为ct1本来已经存在,直接调用复制构造函数,生成对象ct3的副本对象ct4。所以当复制构造函数变为私有时,该语句不能编译通过。

要点就是拷贝初始化和直接初始化调用的构造函数是不一样的,但是当类进行复制时,类会自动生成一个临时的对象,然后再进行拷贝初始化。

9.externC的用法?

externC的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上externC后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。比如说你用C开发了一个DLL库,为了能够让C++语言也能够调用你的DLL输出(Export)的函数,你需要用externC来强制编译器不要修改你的函数名。

10.模板函数和模板类的特例化?

引入的原因:编写单一的模板,它能适应大众化,使每种类型都具有相同的功能,但对于某种特定类型,如果要实现其特有的功能,单一模板就无法做到,这时就需要模板特例化。

定义:是对单一模板提供的一个特殊实例,它将一个或多个模板参数绑定到特定的类型或值上。

1、函数模板特例化:必须为原函数模板的每个模板参数都提供实参,且使用关键字template后跟一个空尖括号对,表明将原模板的所有模板参数提供实参。

templatetypenameT//函数模板

int

1
查看完整版本: c面试常见问题汇总建议收藏