c++经典笔试题和面试题答案(二)
8. 重载(overload)、重写(override,有的书也叫做“覆盖”)、重定义(redefinition)的区别? 重载: 同一个空间名字, 允许存在多个同名函数,但是函数的参数表不同; 覆盖: 不同空间名字,子类重新定义父类虚函数的方法; 重定义:也叫隐藏,子类与父类的函数同名,用于隐藏父类函数; 函数重载时,我们靠什么来区别重载的函数? 只能靠参数而不能靠函数的返回值来区分重载函数; 重载运算符时应该注意什么? ·不能改变c++中内部数据类型(如int ,char 等); ·不能重载“.”,“.”对类中任何成员有效,成为一种标准用法; ·不能用c++中没有用到的符号; ·对已存在的符号进行重载,不能改变其优先级; 9. In C++, what does "explicit" mean? what does "protected" mean? 【标准答案】c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,在某些情况下,我们要求类的使用者必须显示调用类的构造函数时就需要使用explicit,反之默认类型转换可能会造成无法预期的问题。protected控制的是一个函数对一个类的成员(包括成员变量及成员方法)的访问权限。protected成员只有该类的成员函数及其派生类的成员函数可以访问。 10. 重复多次fclose一个打开过一次的FILE *fp指针会有什么结果,并请解释。(等价于free(p),同一个指针不能释放内存两次) 【参考答案】考察点:导致文件描述符结构中指针指向的内存被重复释放,进而导致一些不可预期的异常 11. c++中的内联函数(inline):内联函数省去的函数调用时间是以代码膨胀为代价的;(内联函数不能太长,也不能有循环语句) 对于一个频繁使用的短小的函数, c中用宏定义,c++中用内联函数; 12. c++中的虚函数与纯虚函数(virtual ): 虚函数若果继承类想要重新定义基类的方法,用virtual定义方法,使用动态联编; 13. 多态类中的虚函数表是Compile-Time,还是Run-Time时建立的? 虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组. 而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键。 构造函数不能是虚函数,只能析构函数为虚函数;如果析构函数不是虚函数,则派生类的析构函数用不上,会导致内存泄露; 14. VC中,编译工具条内的Debug与Release选项是什么含义? Debug是调试版本,包含调试信息,不做任何优化,以便程序员调试程序(需要相应的运行库); Release是发布版本,经过优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好的使用,如果不需要运行库,可以直接运行; 15. const与#define 比较: const常量有数据类型,而宏常量没有数据类型; 编辑器可以对const常量进行类型安全检查,对宏只是字符替换,不能进行类型安全检查,容易产生不可预测的错误; 16. 你觉得如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦? 【参考答案】(1)程序的可读性(可理解性)变差。程序员自己会忘记那些数字或字符串是什么意思,用户则更加不知它们从何处来、表示什么。 (2)在程序的很多地方输入同样的数字或字符串,难保不发生书写错误。 (3)如果要修改数字或字符串,则会在很多地方改动,既麻烦又容易出错。 17. 有了malloc/free,为啥还要new/delete; Malloc()和free()是c/c++的标准库函数,无法自动执行构造和析构函数 new()/delete()是运算符,在编辑器的控制内,new可以自动完成内存分配与初始化;delete()可以自动完成清理和释放内存工作; 18. 为什么需要使用堆,使用堆空间的原因? 【参考答案】直到运行时才知道一个对象需要多少内存空间;不知道对象的生存期到底有多长。 19. C++是不是类型安全的? 不是,不同的指针类型之间可以强制类型转化(reinterPt cast); 20. const 符号常量; (1)const char *p -> p是一个非常量指针,指向一个常量字符; (2)char const *p -> 同1 (3)char * const p -> p是一个常量指针,指向一个字符; 21. const float EPSINON = 0.00001; if ((x >= - EPSINON) && (x <= EPSINON) 不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。 22. float a,b,c,问等式(a+b)+c==(b+a)+c和(a+b)+c==(a+c)+b能否成立? 【参考答案】两者都不行。 在比较float或double时,不能简单地比较。由于计算误差,相等的概率很低。应判断两数之差是否落在区间(-e,e)内。这个e应比浮点数的精度大一个数量级 22. C++里面是不是所有的动作都是main()引起的?如果不是,请举例。 答; 静态变量和全局变量的分配早在main之前完成, 全局对象是在Main开始之前就分配了的 全局对象的构造函数就在Main开始之前就执行了! 23. _LINE_ , _FILE_,是系统预定义宏: 答:cout<<_FILE_< 24. sprintf()strcpy(),memcpy()函数的区别: 答:sprintf:操作对象可以是任意类型的数据,但是目的对象是字符串;可以实现其他类型数据到字符串的转化;若原操作数是字符 串,并且指定%s格式符,也可以实现字符串的拷贝; strcpy:操作对象是字符串,完成从源字符串到目的字符串的拷贝功能; memcpy():完成内存拷贝,操作对象可以是任意数据类型;将一个内存块的内容拷贝到另一内存块,内存块由其首地址和长度确定。 25.c与c++中static用法的区别: c中:见我的博文extern,static,const修饰变量的用法 c++中用static 修饰类中的函数,则该函数不能被对象调用,只能由类直接调用; 用static修饰类的数据成员,则该变量属于类,不属于某个对象; 编程题: 1. 用C++写个程序,如何判断一个操作系统是16位还是32位的? 答:定义一个指针p,打印sizeof(p);如果是4,则是32位,若是2,则是16位;(指针p所用内存额字节数通常为一个机器字长) 2. 用C++写个程序,如何判断一个操作系统是16位还是32位的?不能用sizeof()函数。 Int a = ~0; if( a>65536 ) { cout<<"32 bit"< } else { cout<<"16 bit"< } 3. 当一个类A 中没有声命任何成员变量与成员函数,这时sizeof(A)的值是多少, 如果不是零,请解释一下编译器为什么没有让它为零。 答: sizeof(A)=1; 这是被编译器安插进去的一个字节,这样就使得这个空类的两个实例得以在内存中配置独一无二的地址。如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了。 4. char str1[] = "abc"; char str2[] = "abc"; 在栈区,str1,str2,str3,str4是数组有不同内存地址,赋值都为abc; const char str3[] = "abc"; 同上;同时此数组的数据区不能改变; const char str4[] = "abc"; const char* str5 = "abc"; 两个不同的指针指向常量区相同的地址 const char* str6 = "abc"; char* str5 = "abc"; char* str6 = "abc"; cout << (str1 == str2) << endl; //true or false cout << (str3 == str4) << endl; cout << (str5 == str6) << endl;