旅游网站建设的摘要,建立微网站,海南移动互联网开发,自己用电脑做网站服务器说明#xff1a;
面试群#xff0c;群号#xff1a; 228447240面试题来源于网络书籍#xff0c;公司题目以及博主原创或修改#xff08;题目大部分来源于各种公司#xff09;#xff1b;文中很多题目#xff0c;或许大家直接编译器写完#xff0c;1分钟就出结果了。但…说明
面试群群号 228447240面试题来源于网络书籍公司题目以及博主原创或修改题目大部分来源于各种公司文中很多题目或许大家直接编译器写完1分钟就出结果了。但在这里博主希望每一个题目大家都要经过认真思考答案不重要重要的是通过题目理解所考知识点好应对题目更多的变化博主与大家一起学习一起刷题共同进步写文不易麻烦给个三连
前面1-15已经是C/C,但是由于前面写的比较混乱把八股文和题目混在了一起所以从这一篇开始重新整理重新写前面1-15也就可以选看了希望多多支持 1.C中新增了string它与C语言中的 char *有什么区别吗它是如何实现的
答案 string 继承自 basic_string, 其实是对 char* 进行了封装封装的 string 包含了 char* 数组容量长度等等属性。 string 可以进行动态扩展在每次扩展的时候另外申请一块原空间大小两倍的空间 2^n 然后将原字符串拷贝过去并加上新增的内容。 2.有哪些情况必须用到成员列表初始化作用是什么 答案 1) 必须使用成员初始化的四种情况 ① 当初始化一个引用成员时 ② 当初始化一个常量成员时 ③ 当调用一个基类的构造函数而它拥有一组参数时 ④ 当调用一个成员类的构造函数而它拥有一组参数时 2) 成员初始化列表做了什么 ① 编译器会一一操作初始化列表以适当的顺序在构造函数之内安插初始化操作并且在任何显示用户代码之前 ② list 中的项目顺序是由类中的成员声明顺序决定的不是由初始化列表的顺序决定的 3.什么是内存泄露如何检测与避免 答案 内存泄露 一般我们常说的内存泄漏是指 堆内存的泄漏 。堆内存是指程序从堆中分配的大小任意的 ( 内存块的大小可以在程序运行期决定) 内存块使用完后必须显式释放的内存。应用程序般使用 malloc, 、 realloc 、new等函数从堆中分配到块内存使用完后程序必须负责相应的调用 free 或 delete 释放该内存块否则这块内存就不能被再次使用我们就说这块内存泄漏了. 避免内存泄露的几种方式 计数法使用new或者malloc时让该数1delete或free时该数-1程序执行完打印这个计数如果不为0则表示存在内存泄露 一定要将基类的析构函数声明为虚函数 对象数组的释放一定要用delete [] 有new就有delete有malloc就有free保证它们一定成对出现 4.说说移动构造函数 答案 1) 我们用对象 a 初始化对象 b 后对象 a 我们就不在使用了但是对象 a 的空间还在呀在析构之前既然拷贝构造函数实际上就是把a 对象的内容复制一份到 b 中那么为什么我们不能直接使用 a 的空间呢这样就避免了新的空间的分配大大降低了构造的成本。这就是移动构造函数设计的初衷 2) 拷贝构造函数中对于指针我们一定要采用深层复制而移动构造函数中对于指针我们采用浅层复制。浅层复制之所以危险是因为两个指针共同指向一片内存空间若第一个指针将其释放另一个指针的指向就不合法了。 所以我们只要避免第一个指针释放空间就可以了。避免的方法就是将第一个指针比如 a-value 置为 NULL 这样在调用析构函数的时候由于有判断是否为 NULL 的语句所以析构 a 的时候并不会回收 a- value 指向的空间 3) 移动构造函数的参数和拷贝构造函数不同拷贝构造函数的参数是一个左值引用但是移动构造函数的初值是一个右值引用。意味着移动构造函数的参数是一个右值或者将亡值的引用。也就是说只用用一个右值或者将亡值初始化另一个对象的时候才会调用移动构造函数。而那个move 语句就是将一个左值变成一个将亡值。 5.静态类型和动态类型静态绑定和动态绑定的介绍 答案 静态类型对象在声明时采用的类型在编译期既已确定 动态类型通常是指一个指针或引用目前所指对象的类型是在运行期决定的 静态绑定绑定的是静态类型所对应的函数或属性依赖于对象的静态类型发生在编译期 动态绑定绑定的是动态类型所对应的函数或属性依赖于对象的动态类型发生在运行期 6.引用是否能实现动态绑定为什么可以实现 答案 可以。 引用在创建的时候必须初始化在访问虚函数时编译器会根据其所绑定的对象类型决定要调用哪个函数。注意只能调用虚函数。 7.怎样判断两个浮点数是否相等 答案 对两个浮点数判断大小和是否相等不能直接用 来判断会出错明明相等的两个数比较反而是不相等对于两个浮点数比较只能通过相减并与预先设定的精度比较记得要取绝对值浮点数与0 的比较也应该注意。与浮点数的表示方式有关。 8.指针加减计算要注意什么 答案 指针加减本质是对其所指地址的移动移动的步长跟指针的类型是有关系的因此在涉及到指针加减运算需要十分小心加多或者减多都会导致指针指向一块未知的内存地址如果再进行操作就会很危险。 举个例子 #include iostream
using namespace std;
int main()
{int *a, *b, c;a (int*)0x500;b (int*)0x520;c b - a;printf(%d\n, c); // 8a 0x020;c b - a;printf(%d\n, c); // -24return 0;
} 首先变量 a 和 b 都是以 16 进制的形式初始化将它们转成 10 进制分别是 1280 5*16\^21280 和 1312 5*16\^22*161312) 那么它们的差值为 32 也就是说 a 和 b 所指向的地址之间间隔 32 个位但是考虑到是int 类型占 4 位所以 c 的值为 32/48 a 自增 16 进制 0x20 之后其实际地址变为 1280 2*16*4 1408 因为一个 int 占 4 位所以要乘 4 这样它们的差值就变成了1312 - 1280 -96 所以 c 的值就变成了 -96/4 -24 9.C中的指针参数传递和引用参数传递有什么区别底层原理你知道吗 答案 1) 指针参数传递本质上是值传递它所传递的是一个地址值。 值传递过程中被调函数的形式参数作为被调函数的局部变量处理会在栈中开辟内存空间以存放由主调函数传递进来的实参值从而形成了实参的一个副本替身。 值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行的不会影响主调函数的实参变量的值形参指针变了实参指针不会变。 2) 引用参数传递过程中被调函数的形式参数也作为局部变量在栈中开辟了内存空间但是这时存放的是由主调函数放进来的实参变量的地址。 被调函数对形参本体的任何操作都被处理成间接寻址即通过栈中存放的地址访问主调函数中的实参变量根据别名找到主调函数中的本体。 因此被调函数对形参的任何操作都会影响主调函数中的实参变量。 3) 引用传递和指针传递是不同的虽然他们都是在被调函数栈空间上的一个局部变量但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。 而对于指针传递的参数如果改变被调函数中的指针地址它将应用不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量地址那就得使用指向指针的指针或者指针引用。 4) 从编译的角度来讲程序在编译时分别将指针和引用添加到符号表上符号表中记录的是变量名及变量所对应地址。 指针变量在符号表上对应的地址值为指针变量的地址值而引用在符号表上对应的地址值为引用对象的地址值与实参名字不同地址相同。 符号表生成之后就不会再改因此指针可以改变其指向的对象指针变量中的值可以改而引用对象则不能修改。 10.类如何实现只能静态分配和只能动态分配 答案 1) 前者是把 new 、 delete 运算符重载为 private 属性。后者是把构造、析构函数设为 protected 属性再用子类来动态创建 2) 建立类的对象有两种方式 ① 静态建立静态建立一个类对象就是由编译器为对象在栈空间中分配内存 ② 动态建立 A *p new A(); 动态建立一个类对象就是使用 new 运算符为对象在堆空间中分配内存。 这个过程分为两步第一步执行operator new() 函数在堆中搜索一块内存并进行分配第二步调用类构造函数构造对象 3) 只有使用 new 运算符对象才会被建立在堆上因此只要限制 new 运算符就可以实现类对象只能建立在栈上可以将new 运算符设为私有。 11.如果想将某个类用作基类为什么该类必须定义而非声明 答案 派生类中包含并且可以使用它从基类继承而来的成员为了使用这些成员派生类必须知道他们是什么。 所以必须定义而非声明。 12.继承机制中对象之间如何转换指针和引用之间如何转换 答案 1) 向上类型转换 将派生类指针或引用转换为基类的指针或引用被称为向上类型转换向上类型转换会自动进行而且向上类型转换是安全的。 2) 向下类型转换 将基类指针或引用转换为派生类指针或引用被称为向下类型转换向下类型转换不会自动进行因为一个基类对应几个派生类所以向下类型转换时不知道对应哪个派生类所以在向下类型转换时必须加动态类型识别技术。RTTI 技术用 dynamic_cast 进行向下类型转换。