c++面试题之易错题本

发布时间:2016-12-8 15:55:54 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"c++面试题之易错题本",主要涉及到c++面试题之易错题本方面的内容,对于c++面试题之易错题本感兴趣的同学可以参考一下。

1,inline只适合函数体内代码简单的函数使用,不能包含复杂的结构控制语句例如while switch,并且内联函数本身不能是递归函数; 2,在C++中,对于有virtual的类,其sizeof会比正常情况多处4个字节。既在类的最开始四个字节,放的是VTABLE表的地址(void *类型)。而在VTABLE中,所有虚函数是以指针数组的形式存放。 对于派生的类,即使没有重载基类的虚函数,也会在其VTABLE占用一格。造成空间上的浪费。非虚基类没有VTABLE,VTABLE是在构造的时候编译器生成的。 3,线程和进程:进程是操作系统资源分配的最小单位,线程是CPU运行的最小单位。 4,static有什么用途:1.限制变量的作用域2.设置变量的存储域;C/C++中Static的作用的第一条也是最重要的一条:隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。如果加了static,就会对其它源文件隐藏。static的第二个作用是保持变量内容的持久。 5,引用与指针有什么区别?      引用就是某个目标变量的“别名”,对引用的操作就是对目标变量的操作     1) 引用必须被初始化,指针不必。2) 引用初始化以后不能被改变,指针可以改变所指的对象。3) 不存在指向空值的引用,但是存在指向空值的指针。 6,全局变量储存在静态数据区,局部变量在堆栈 7,什么是平衡二叉树:左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1; 8,堆栈溢出一般是由什么原因导致的:没有回收垃圾资源; 9,构造函数为什么不能声明为虚函数? 1. 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的。问题出来 了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数。 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重写的函数得到对应的调用。构造函数本身就是要初始化实例,那使用虚函数也没有实际意义 呀。所以构造函数没有必要是虚函数。虚函数的作用在于通过父类的指针或者引用来调用它的时候能够变成调用子类的那个成员函数。而构造函数是在创建 对象时自动调用的,不可能通过父类的指针或者引用去调用,因此也就规定构造函数不能是虚函数。 3. 构造函数不需要是虚函数,也不允许是虚函数,因为创建一个对象时我们总是要明确指定对象的类型,尽管我们可能通过实验室的基类的指针或引用去 访问它但析构却不一定,我们往往通过基类的指针来销毁对象。这时候如果析构函数不是虚函数,就不能正确识别对象类型从而不能正确调用析构函数。 4. 从实现上看,vbtl在构造函数调用后才建立,因而构造函数不可能成为虚函数从实际含义上看,在调用构造函数时还不能确定对象的真实类型(因为子 类会调父类的构造函数);而且构造函数的作用是提供初始化,在对象生命期只执行一次,不是对象的动态行为,也没有必要成为虚函数。 5. 当一个构造函数被调用时,它做的首要的事情之一是初始化它的VPTR。因此,它只能知道它是“当前”类的,而完全忽视这个对象后面是否还有继承者。 当编译器为这个构造函数产生代码时,它是为这个类的构造函数产生代码——既不是为基类,也不是为它的派生类(因为类不知道谁继承它)。所以它使用 的VPTR必须是对于这个类的VTABLE。而且,只要它是最后的构造函数调用,那么在这个对象的生命期内,VPTR将保持被初始化为指向这个VTABLE, 但 如果接着还有一个更晚派生的构造函数被调用,这个构造函数又将设置VPTR指向它的 VTABLE,等.直到最后的构造函数结束。VPTR的状态是由被最后调 用的构造函数确定的。这就是为什么构造函数调用是从基类到更加派生类顺序的另一个理由。但是,当这一系列构造函数调用正发生时,每个构造函数都已 经设置VPTR指向它自己的VTABLE。如果函数调用使用虚机制,它将只产生通过它自己的VTABLE的调用,而不是最后的VTABLE(所有构造函数被调用 后才会有最后的VTABLE)。 10,为什么基类的析构函数是虚函数?在实现多态时,当用基类指针操作派生类,在析构时防止只析构基类而不析构派生类的状况发生。11,冒泡排序算法的时间复杂度是O(n^2)12,写出float x 与“零值”比较的if语句。if(x>0.000001&&x<-0.000001)13,Internet采用哪种网络协议?该协议的主要层次结构?tcp/ip -----应用层/传输层/网络层/数据链路层/物理层;14,由C/C++编译的程序占用的内存分为以下几个部分; 1、栈区(stack): 由编译器自动分配释放,存放函数的参数值,局部变量等。其操作方式类似于数据结构中的栈。 2、堆区(heap): 一般由程序员分配释放(malloc/free、new/delete), 若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构 中的堆是两回事,分配方式倒是类似于链表。 3、全局区(static): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静 态变量在相邻的另一块区域,程序结束后由系统释放。 4、文字常量区: 常量字符串就是放在这里的, 程序结束后由系统释放。 5、程序代码区: 存放函数体的二进制代码。15,char *strcpy(char *strDest, const char *strSrc){ if ( strDest == NULL || strSrc == NULL) return NULL ; if ( strDest == strSrc) returnstrDest ; char *tempptr = strDest ; while( (*strDest++ = *strSrc++) != ‘’); return tempptr ;}16, 面向对象的三个基本特征:1)封装:将客观事物抽象成类。2)继承:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。3)多态:允许将子类类型的指针赋值给父类类型的指针,通过基类指针调用子类函数。17,请说出const与#define 相比,有何优点:1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。18,头文件的作用是什么:1)通过头文件来调用库功能。2)头文件能加强类型安全检查。 19,写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个:#define MIN(A,B) ((A) <= (B) ? (A) : (B))  20,char * const p; //常量指针,p的值不可以修改char const * p;//指向常量的指针,指向的常量值不可以改const char *p; //和char const *p,(先从*和p的位置判断,再看const的位置) 21,用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 22,char* ss = “0123456789″;sizeof(ss) 结果 4 //ss是指向字符串常量的字符指针sizeof(*ss) 结果 1 //*ss是第一个字符        char ss[] = “0123456789″;sizeof(ss) 结果 11 //ss是数组,计算到\0位置,因此是10+1,sizeof(*ss) 结果 1 //*ss是第一个字符        char ss[100] = “0123456789″;sizeof(ss) 结果是100 //ss表示在内存中的大小 100×1intss[100] = “0123456789″;sizeof(ss) 结果 400 //ss表示再内                  存中的大小 100×4        char q[]=”abc”;char p[]=”a\n”;sizeof(q),sizeof(p),strlen(q),strlen(p);   结果是 4 3 3 2 23,new、delete、malloc、free关系? delete会调用对象的析构函数;new调用构造函数;----free只会释放内存 new/delete是C++的运算符;malloc与free是C++/C语言的标准库函数,malloc/free是库函数而不是运算符,不在编译器控制权限之内 24,delete与 delete []区别 delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数,当delete操作符用于数组时,它为每个数组元素调用析构函数 25,多态,虚函数,纯虚函数? 多态:是对于不同对象接收相同消息时产生不同的动作; C++的多态性具体体现在运行和编译两个方面:1>在程序运行时的多态性通过继承和虚函数来体现. 2>在程序编译时多态性体现在函数和运算符的重载上 虚函数:在基类中冠以关键字 virtual 的成员函数。 它提供了一种接口界面。允许在派生类中对基类的虚函数重新定义. 纯虚函数的作用:在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。作为接口而存在,纯虚函数不具备函数的功能,一般不能直接被调用。 从基类继承来的纯虚函数,在派生类中仍是虚函数。如果一个类中至少有一个纯虚函数,那么这个类被称为抽象类(abstract class)。 抽象类中不仅包括纯虚函数,也可包括虚函数。抽象类必须用作派生其他类的基类,而不能用于直接创建对象实例。但仍可使用指向抽象类的指针支持运行时多态性。 26,将“引用”作为函数参数有哪些特点? 1)传递引用给函数与传递指针的效果是一样的。(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作; 27,在什么时候需要使用“常引用”? 如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。 28,将“引用”作为函数返回值类型的格式、好处和需要遵守的规则? 好处:在内存中不产生被返回值的副本;1)不能返回局部变量的引用。2)不能返回函数内部new分配的内存的引用。3)可以返回类成员的引用,但最好是const。 引用是除指针外另一个可以产生多态效果的手段。 29,结构与联合有和区别? 1). 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。2). 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。 30,多态的作用? 1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。 31,当一个类A 中没有任何成员变量与成员函数,这时sizeof(A)的值是多少?1个字节。如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了 32,OSI的七层网络结构图和TCP/IP的五层结构图?      33,关键字volatile有什么含意 并给出三个不同的例子? 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 1). 并行设备的硬件寄存器(如:状态寄存器) 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量 34,vector 和 list的区别? vector内部使用数组,访问速度快,但是删除数据比较耗性能 list内部使用链表,访问速度慢,但是删除数据比较快 35,winsock建立连接的主要实现步骤? TCP:服务器端:1.socket()建立套接字,2将套接字绑定到本地地址和端口上,绑定(bind)3.将套接字设为监听模式,准备接收客户端,监听(listen);4.等待客户端请求到来,请求到来后,连接请求,并返回一个新的对应此连接的套接字,accept()5.用返回的套接字和客户端进行通讯(send/recv);6.返回并等待另一客户请求。7.关闭套接字。      客户端:1.socket()建立套接字2.向服务器发出连接请求,(connect)2。和服务器进行通信,send()和recv(),在套接字上写读数据,直至数据交换完毕;4closesocket()关闭套接字。 UDP:服务器端:1.创建套接字(socekt)2.将套接字绑定到本地地址和端口上(bind);3.等待接收数据(recvfrom);4.closesocket()关闭套接字。       客户端:1.创建套接字(socekt)2,向服务器端发送数据(sendto)3.closesocket()关闭套接字。

上一篇:关于HttpClient的总结
下一篇:C# 事件机制

相关文章

相关评论