1. 说明const与#define的特点及区别
const常量存在于程序的数据段,并在堆栈分配了空间。const常量是一个Run-time的概念,它在程序中确确实实地存在着并可以被调用、传递。const常量有数据类型,而宏常量没有数据类型。编译器可以对const常量进行类型安全检查。
2. C++中const有什么作用
(1)const用于定义常量:const定义的常量编译器可以对其进行数据静态类型安全检查
(2)const修饰函数形式参数:当输入参数为用户自定义类型和抽象类型数据时,应该将“值传递”改为“const&传递”,可以提高效率
(3)const修饰函数的返回值:如给“指针传递”的函数返回加const,则返回值不能被直接修改,且该返回值只能被赋值给加const修饰的同类型指针
(4)const修饰类的成员函数(函数定义体):任何不会改变数据成员的函数都应用const修饰,这样,当不小心修改了数据成员或是调用了非const成员函数时,编译器会报错。
3. static有什么作用
(1)在函数体内,一个被声明为静态的变量在这一函数被调用的过程中维持其值保持不变
(2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所有函数访问,但不能被模块外其他函数访问。他是一个本地的全局变量
(3)在模块内,一个被声明为静态的函数只可被这一模块内的其他函数调用。那就是这个函数被限制在声明它的模块的本地范围内使用
4. 为什么不把所有的函数都定义成为内联函数
(1)如果函数内的代码比较长,使用内联将导致内存消耗代价较高
(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大
(3)类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构函数可能会隐藏一些行为,如“偷偷地”执行了基类或成员对象的构造函数和析构函数
5. 内联函数与宏的区别
(1)内联函数在编译时展开,宏在预编译时展开
(2)在编译的时候,内联函数可以直接被镶嵌到目标函数中,而宏只是一个简单的文本替换
(3)内联函数可以完成诸如类型检查、语句是否正确等编译功能,宏就不能具有这样的功能
(4)宏不是函数,inline函数是函数
(5)宏在定义时要小心处理宏参数(一般情况下是把参数用括号括起来),否则容易出现二义性。而内联函数定义时不会出现二义性
5.指针和引用的区别
(1)初始化不同。引用在创建时必须初始化,即引用到一个有效的对象;而指针在定义的时候不必初始化,可以在定以后的任何地方重新赋值
(2)可修改性不同。引用一旦被初始化为指向一个对象,它就不能被改编为另外一个对象的引用;而指针在任何时候都可以改变为指向另外一个对象。给引用赋值并不是改变它和原始对象的绑定关系
(3)不存在NULL引用,引用不能使用指向空值的引用,它必须总是指向某个对象而指针则可以是NULL,不需要总是指向某些对象,可以把指针指向任何的对象,所以指针更加灵活,也容易出错
(4)测试需要的区别。由于引用不会指向空值,这意味着使用引用之前不需要进行测试它的合法性;而指针则需要经常进行测试。因此使用引用的代码效率比使用指针的要高
(5)应用区别。如果是指一旦指向一个对象后就不会改变指向,那么应该使用引用。如果存在指向NULL(不指向任何对象)或是在不同的时刻指向不同的对象这些可能性,应该使用指针
实际上,在语言层面上,引用的用法和对象一样;在二进制层面,引用一般都是通过指针来实现的,只不过编译器帮助我们完成了转换。总体来说,引用既有指针的效率,又具有变量使用的方便性和直观性。
6. 为何引用比传指针安全
(1)由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改编为另外一个对象的引用,因此引用很安全
(2)对指针来说,它可以随时指向别的对象,并且可以不被初始化,或者初始化为NULL,所以不安全。const指针依然存在空指针,并且有可能产生野指针
7. 指针常量与常量指针的区别
(1)常量指针,表述为“是常量的指针”,它首先应该是一个指针
常量指针,它是一个指向常量的指针。设置常量指针指向一个常量,为的是防止写程序过程中对指针误操作出现了修改常量这样的错误。编译系统就会提示我们出错信号。因此,常量指针就是一个指向常量的指针,指针指向的内存的内容是不可以修改的。
(2)指针常量,表述为“是指针的常量”,它首先应该是一个常量
指针常量,它首先是一个常量,再是一个指针。指针常量就是不能修改这个指针指向的地址,一开始初始化指向哪里,他就只能指向哪里了,不能指向其它地方了,就像一个数组的数组名一样,是一个固定的指针,不能对它进行移动操作
例如:char const* p = nullptr
8. 函数指针域指针函数
(1)指针函数,是指带指针的函数,即本质是一个函数,并且返回类型是某一类型的指针
(2)函数指针,是指函数的指针变量,因而它本身首先应试指针变量,只不过该指针变量指向函数。有了指向函数的指针变量之后,可以用该指针变量调用函数
9. 野指针是什么
“野指针”不是null指针,而是指向“垃圾”内存的指针。人们一般不会错用null指针,因为用if语句很容易判断。但是“野指针”是很危险的,if语句对它不起作用。“野指针”的生成原因主要有以下两个
(1)指针变量没有被初始化,任何这孩子很变量刚被创建时不会自动完成null指针,它是默认的随机的,它会乱指一气。
(2)指针p被free或是delete之后,没有置位null,让人误解认为p还是一个合法的指针
10. Malloc/free和new/delete的区别
首先malloc和free是C++/C标准库函数,new/delete是C++的运算符。他们都用于申请动态内存和释放内存。
原因:对于非内部数据类型(C/C++本身自带的变量类型)的对象,对象消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权范围内,不能执行构造函数和析构函数,只能使用new/delete运算符
11. 内存分配的方式
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好了,这块内存在程序的整个运行期间都存在,例如全局变量
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。处理器的指令集中有关于栈内存的分配运算,因此效率很高,但是分配内存的容量有限。
(3)在堆上分配,亦成为动态内存分配。程序在运行的时候低啊用malloc(标准库函数)或是new(运算符)申请任意多少的内存,程序员自己负责何时调用free和delete释放内存。动态内存的生存周期由程序员决定,使用非常灵活,但问题也很多。
12. 指针和句柄的区别
首先指针指向的是内存中的一个地址,但是要是得到了这块内存的地址那么就可以对这块内存进行任意的更改,这样带来的风险很高不安全。===》因而Windows中使用GlobalAlloc等函数声明的内存区域指定一个句柄,句柄是一种指向指针的指针 。它们的不同之处:
(1)句柄所值的可以使一个很复杂的结构,并且很有可能是与系统有关的。比如说线程的句柄,它指向的就是一个类或是结构,它和系统有很密切的关系。当一个线程由于不可预料的原因而终止时,系统就可以返回它所占用的资料,如CPU、内存等。反过来想可以知道,这个句柄中的某一些是与系统进行交互的。由于Windows系统是一个多任务系统,它随时都可能要分配内存、回收内存、充足内存
(2)指针也是可以指向一个复杂的结构,但是通常是由用户自己定义的,所以必须的工作都要用户完成,特别是在删除的时候
14. 相比全局对象,静态数据成员的优点
(1)静态数据成员没有进入程序的全局名字空间,因此不存在程序中的其他全局名字冲突的可能性
(2)使用静态数据成员可以隐藏信息。因为静态数据成员可以使private成员,而全局对象是不能的
15. C++声明一个空类会默认生成的函数
(1)默认的构造函数和析构函数
(2)复制函数,类对象的构造时候
(3)赋值函数,被同类对象间的赋值操作
(4)取值运算,当对类的对象进行取地址(&)时,此函数被调用
C/C++面试知识点清理
最新推荐文章于 2023-10-11 16:09:49 发布