c面试题
Posted chzh999
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c面试题相关的知识,希望对你有一定的参考价值。
一、简答题。(共4题,共20分,每题5分) 1、void main(void) { char *str = (char *) malloc(100); strcpy(str, "hello"); free(str); if(str != NULL) { strcpy(str, “world”); printf(str); } } 请问运行main函数会有什么样的结果? 最佳答案是:篡改动态内存区的内容,后果难以预料,非常危险。因为free(str);之后,str成为野指针, if(str != NULL)语句不起作用。 2、void GetMemory(char **p, int num) { char *p[]; *p = (char *)malloc(num); } void main(void) { char *str = NULL; GetMemory(&str, 100); strcpy(str, "hello"); printf(str); } 请问运行main函数会有什么样的结果? 最佳答案:能够输出hello,内存泄漏 3、char *GetMemory(void) { char p[] = "hello world"; return p; } void main(void) { char *str = NULL; str = GetMemory(); printf(str); } 请问运行main函数会有什么样的结果? 最佳答案是:可能是乱码。因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。 4、void GetMemory(char *p) { p = (char *)malloc(100); } void main(void) { char *str = NULL; GetMemory(str); strcpy(str, "hello world"); printf(str); }请问运行Test函数会有什么样的结果? 最佳答案是:程序崩溃。因为GetMemory并不能传递动态内存, Test函数中的 str一直都是 NULL。 strcpy(str, "hello world");将使程序崩溃。而且GetMemory函数体内申请的堆内存为释放,造成内存泄漏。 二、问答题。(共10题,每题4分,共40分) 1、解释C++三大核心概念。 参考答案是: 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 继承:子类自动继承父类所有的成员(除了构造函数,析构函数,赋值运算符重载),子类可以重写父类的方法,子类也可以扩展成员,使用继承可以达到代码重用或复用的目的。 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。(多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。) 2、拷贝构造函数在哪几种情况下调用? 参考答案是:解答要点:用一个对象初始化另一个对象时 当用对象作为函数参数传递时 当函数以值的形式返回对象时 3、虚函数,纯虚函数的概念。 参考答案是:函数声明时被virtual关键字修饰,可用于实现多态;没有函数体的虚函数为纯虚函数,纯虚函数被派生类继承后一般需要实现,否则派生类也是抽象类。 4、什么叫抽象类?抽象类有何作用?抽象类的派生类是否一定要实现纯虚函数? 参考答案是:有纯虚函数的类为抽象类,抽象类不能被实例化,但是可以声明抽象类的指针或者引用;抽象类的主要作用是通过它为一个类族(其派生类)建立一个公共的接口,使它们能够更有效地发挥多态特性;抽象类声明了一组派生类共同操作接口的通用语义,而接口的完整实现,即纯虚函数的函数体,要由派生类自己给出。但抽象类的派生类并非一定要给出纯虚函数的实现,如果派生类没有给出纯虚函数的实现,这个派生类仍然是一个抽象类 5、什么是动态绑定,动态绑定有什么好处? 参考答案是: 虚函数在被调用时,具体调用哪个版本的函数(父类还是子类),在编译时无法确定,只有在运行时才能确定称为动态绑定。动态绑定(C++中,通过基类的引用或指针调用虚函数时,发生动态绑定。引用(或指针)既可以指向基类对象也可以指向派生类对象,这一事实是动态绑定的关键。用引用(或指针)调用的虚函数在运行时确定,被调用的函数是引用(或指针)所指对象的实际类型所定义的。) 6、简单描述多重继承中怎样产生的菱形继承问题,又是如何解决的呢? 参考答案是:在多重继承中,多个基类又拥有共同的基类,导致派生类中有多份“爷爷”类中的成员,从而导致成员变量冗余以及成员函数调用的歧义;使用虚继承解决菱形继承问题,直接继承祖先的两个类,在继承时使用虚继承,通过多重继承而来的那个子类(孙子类)在构造对象时,直接调用祖先类的构造函数,孙子辈的派生类,直接继承祖先类的成员,再继承两个父类各自扩展的成员。 7、什么是Big Three?为什么程序中要实现Big Three? 参考答案是:Big Three包括拷贝构造函数、析构函数以及赋值运算符重载函数;当类中有指向堆空间的指针成员时,不实现拷贝以及赋值重载,有可能会造成二次删除或者内存泄漏问题,不实现析构函数会出现内存泄漏,其中二次删除有可能导致程序崩溃。 8、static_cast和dynamic_cast的区别是什么? 参考答案是:都可用于做向下类型转换,static_cast相当于强转,没有是否能转型成功的检查;而使用dynamic_cast进行转型时,编译器会判断待转型的数据所指向对象的真实身份,以此判断是否可以转换成功,如果转型不成功,dynamic_cast表达式则会返回NULL. 9、函数传参的三种方式,每种方式都有什么特点? 参考答案是:三种方式:值、指针、引用;以“值”方式进行参数传递时,为单向传递,只能由实参传递给形参,传指针时,可以通过指针修改指针所指向的变量,传引用时可以节省空间,相当于给实参取别名,形参与实参公用一块内存空间。 10、标准模板库分为哪两大类,各包含哪些类,它们有什么区别? 参考答案是:标准模板库中包含顺序容器与关联容器两大类,顺序容器中常用的容器有vector、deque以及list,关联容器中常用的容器包含set、multiset、map以及multimap;顺序容器中的元素是按照存入时的先后顺序进行排列,而关联容器则没有。 三、编程题(共10分) . 已知strcpy函数的原型是 char *strcpy(char *strDest, const char *strSrc); 其中strDest是目的字符串,strSrc是源字符串。 (1)不调用C++/C的字符串库函数,请编写函数 strcpy (2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值? 最佳答案是: char * strcpy(char * strDest,const char * strSrc) { char * strDestCopy=strDest; //[3] if((strDest==NULL)||(strSrc==NULL)) //[1] throw "Invalid argument(s)"; //[2] while((*strDest++=*strSrc++)!=‘