《c++笔试题汇总更新400道.docx》由会员分享,可在线阅读,更多相关《c++笔试题汇总更新400道.docx(145页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、C+笔试面试!000题1 .什么是“引用”?申明和使用“引用”要注意哪些问题?答:引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作 效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后, 相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作 为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用 名是目标变量名的个别名,它本身不是种数据类型,因此引用本身不占存储 单元,系统也不给引用分配存储单元。不能建立数组的引用。2 .指针和引用的区别?答:引用是在C+中引入的。它们之间的区别有:(1)非空区别:指针可以为空,而引
2、用不能为空(2)可修改区别:如果指针不是常指针,那么就可以修改指向,而引用不能 (3)初始化区别:指针定义时可以不初始化,而引用在定义的时必须初始化3、为什么构造函数不能声明为虚函数?答:因为虚函数采用的是虚调用的方法,虚调用是指允许在只知道部分信息的情 况下的工作机制,特别允许我们调用个只知道接口而不知道其对象的准确类型 的函数。但是如果我们要调用构造函数创建对象时,必须要知道对象的准确类型, 因此构造函数不能为虚函数。4 . char strl= abc ; char str2| = abc” ; strl=str2 为 FALSE,因为 strl 和str2是位于堆栈上的,它们占用不同的
3、内存空间。Const char str3 = abc” ; const char str4 = abc” ; str3=str4为FALSE,同样它们是位于堆栈上的内存空 间,是不同的。Const char *str5= abc” , const char *str6= abc ;char *str7= abc,char *str8= abc ,str5=str6 str7=str8 为 TRUE,因为“ abc是位 于文字常量区的,系统会将几个“abc进行优化,使它们位于同块内存区,因 此指针的指向也就相同了。5 .以下函数能求出数组的长度吗?void fun(char str) int l
4、en = sizeof(str)/sizeof(str0);答:不能,数组作为参数传递给函数时,数组名被退化为指针,因此函数中的 sizeof(str)实际是在求一个指针的sizeof,答案为4,因此不能计算出数组的长度。6 .类的静态成员和非静态成员有何区别?答:类的静态成员每个类只有一个,静态成员为所有类的实例对象共享,静态成 员有静态成员变量和静态成员函数,静态成员变量使用前必须初始化,静态成员 变量可以被静态成员函数和非静态成员函数访问,而静态成员函数只能访问静态 成员变量,因为静态成员函数属于类,其没有this指针。非静态成员每个对象都 有一个。7 .static的有什么作用(包括在
5、类中)?答:(1)函数体内的静态变量,其值在函数的调用过程中保持不变。跟局部变量 的区别。(2)在函数体外定义的静态变量,限制了它的使用范围只在于该子模块,该 子模块内的函数都能访问它,但是子模块外不能访问,实际就类似于是个本地 的全局变量。与一般全局变量的区别。(3)类的静态成员函数。本质上来说,static就是声明了对象的生成期,限制了对象的作用域。或(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的 内存只能被分配一次,因此其值在下次函数调用时仍维持上次的值。(2)在模块内的static全局变量可以被模块内的所有函数访问,但不能被模块 外其他函数访问。(3)
6、在模块内的static函数只可被这模块内的其他函数调用,这个函数的使 用范围被限制在声明它的模块。(4)在类中的static成员变量属于整个类所有,对类的所有对象只有一份拷贝。(5)在类中的static成员函数属于整个类所有,这个函数不接受this指针,因 而只能访问类的static成员变量。8.写程序,将一个字符串倒序?答:直接在main函数中实现的void main()char * source = hello;char *des;int len = strlen(source);des = (char *)malloc(len+l); 申请空间必须是len+1,加1是为了放结束符if (
7、!des) exit(l); )char *s = &sourcelen-l;char *d = des;while (len!=0) *d+ = *s; *d 二、; 必须要coutsourceendl;coutdesendl;9 .在C+程序中调用C编译后的函数,为什么要加extern C的声明?答:因为C+支持函数重载,而C不支持函数重载。函数被C+编译后在库中的 名字与C语言的不同。假设某个函数的原型为:void foo(int x, int y):该函数被C 编译器编译后在库中的名字为_foo,而C+编译器则产生像foo_int_int之类的名 字。C+提供了 C连接交换指定符号ex
8、tern C来解决名字匹配问题。10 .C+中哪些函数不能被声明为虚函数?答:普通函数(非成员函数),构造函数,内联成员函数、静态成员函数、友元函 数。(1)虚函数用于基类和派生类,普通函数所以不能(2)构造函数不能是因为虚函数采用的是虚调用的方法,允许在只知道部分信息 的情况的工作机制,特别允许调用只知道接口而不知道对象的准确类型的方法, 但是调用构造函数即使要创建一个对象,那势必要知道对象的准确类型。(3)内联成员函数的实质是在调用的地方直接将代码扩展开(4)继承时,静态成员函数是不能被继承的,它只属于个类,因为也不存在动 态联编等(5)友元函数不是类的成员函数,因此也不能被继承10.1
9、nclude D include filename.h”的区别?答:O是从标准库路径搜索,是从用户当前工作目录开始,找不到,在到标 准库开始12.编写strlen函数,编写strcpy函数答:int Strlen(const char *str)int len = 0;assert(str != NULL);while (*str+ 占。) len+; return len;非空判断是必须进行的操作,可以使用断言的方式assert(str) != NULL会继续char *StrCpy(char *strDes, const char *strSrc)assert(strDes != NULL
10、) & (strSrc != NULL);char *address = strDes;while (*strDes+ = *strSrc+) !=。);return address;首先必须判断两个指针是否为空,由于复制后的指针需要返回,因此需要一个指针来记录地址的初始值,最 后将复制的结果返回是为了进行链式操作。13Heap和Stack的区别?答:Heap是堆,Stack是栈。栈的空间由操作系统自动分配和回收,而堆上的空间由程序员申请和释 放。栈的空间大小较小,而堆的空间较大。栈的地址空间往低地址方向生长,而堆向高地址方向生长。栈的存取效率更高。程序在编译期间对变量和函数的内存分配都在栈上
11、,且程序运行过程中对函数调用中参数的内存分配也是在栈上。14.输出的结果是多少,并分析过程?unsigned short A = 10;printf( “un”,A);char ch = 128;printf( %dn , ch);答:A=4294967285,首先将A转化为int类型,即对应的二进制数值为:00000000 00000000 00000000 00001010, A=11111111 11111111 11111111 11110101,其实这 种情况最高位是1,认为是负数,但是在输出中指定以无符号数输出,于是结果为 4294967285=4294967295 (四字节表示的
12、最大数)-10.ch = 128对应的二进制为:10000000,在输出中以整数形式输出,由于最高位是1, 于是就是负数,10000000是该负数的补码,根据求补码的反步骤计算,先1,得到 01111111,在取反得10000000=128,由于本身是负数,即为128.15、sizeof和strlen之间的区别?答:(1) sizeof操作符的结果类型是size_t,它在头文件中的typedef为unsigned int 类型,该类型保证能容纳实现所建立的金大对象的字节大小。(2) sizeof是运算符,strlen是函数(3) sizeof可以用类型做参数,strlen只能用char 做参数
13、,且必须是 以、结尾的。(4)数组做sizeof的参数不退化,传递给strlen就退化为指针。(5)大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量 的长度。(6)strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度, 而不是类型占用内存的大小。(7) sizeof后如果是类型必须加括号,如果是变量名可以不加括号。(8)当使用了一个结构类型或变量时,sizeof返回实际的大小。(9)数组作为参数传递给函数时传的是指针而不是数组,传递的是数组 的首地址。(10)计算结构变量的大小就必须讨论数组对齐问题。(11) sizeof操作符不能用于函数类型,不完全类型或位字
14、段。16 .内联函数和宏的差别?答:内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用, 在编译的时候内联函数可以直接被镶嵌到目标代码中,而宏只是-个简单的替换。 内联函数要做参数类型检査,这是与宏相比的优势。Inline是指嵌入代码,就是在调用函数的地方不是跳转,而是把代码直接写到 那里去。对于短小的代码来说,inline可以带来一定效率的提升,而且和C时代的 宏函数相比,inline更安全可靠。可是这是以增加空间消耗为代价的。Inline 一般只适用于:个函数被不断地重复调用;函数只有简单的儿行,且 函数内不能含有for while switch语句。17 .请找出下面代码中
15、的所以错误说明:以下代码是把个字符串倒序,如“ abed”倒序后变为“deba”#include string, h”main () char*src=w hello, worldw ;char* dest=NULL;int len=strlen(sre);dest=(char*)malloc(len);char* d=dest;char* s=srclen;while(len - !=0)d+=s -;printf( %sw , dest);return 0;,答:方法1:int main() char* sre = hello, worldM ;int len = strlen(src);
16、char* dest = (char*)malloc (len+1);要为、分配个空间char* d = dest;char* s = &src lenT;指向最后-个字符while( len - != 0 )*d+=*s -;*d = ;尾部要加、printf( K%snM , dest);free(dest);使用完,应当释放空间,以免造成内存汇泄露return 0;18 .用两个栈实现个队列的功能?要求给出算法和思路!设2个栈为A,B,开始均为空.入队:将新元素push入栈A;出队:(1)判断栈B是否为空;(2)如果不为空,则将栈A中所有元素依次pop出并push到栈B;(3)将栈B的栈
17、顶元素pop出;这样实现的队列入队和出队的平摊复杂度都还是 0(1),比上面的几种方法要好19 .下面的程序中x是多少?enum stringxl, x2, x3=10, x4, x5, x;x= 0X801005, 0x801 Of4;20多态的作用?主要是两个:1.隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码 重用;2.接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例 的某属性时的正确调用。21. New delete 与 malloc free 的联系与区别?都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节 数并且不能初始化对象
18、,new会自动调用对象的构造函数。delete会调用对象的 destructor,而 free 不会调用对象的 destructor.22. #def ine DOUBLE (x) x+x , i = 5*D0UBLE(5); i 是多少?答案:i为30。23. 局部变量能否和全局变量重名答:能,局部会屏蔽全局。要用全局变量,需要使用:局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部 变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多 个同名的局部变量,比如在两个循环体内都定义个同名的局部变量,而那个局部变 量的作用域就在那个循环体内。2、如何引用个已经
19、定义过的全局变量答: extern可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来 引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间 会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间 不会报错,而在连接期间报错24全局变量可不可以定义在可被多个.C文件包含的头文件中为什么答:可以,在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中 对此变量赋初值,此时连接不会出错25 .设有以下说明和定义:typedef union long i; int k5;
20、 char c; DATE; struct data int cat; DATE cow; double dog; too;DATE max;则语句 printf(d”,sizeof(struct date)+sizeof(max);的执行结果是: 52答:DATE是一个union,变量公用空间.里面最大的变量类型是int5,占用20个字节,所以它 的大小是20 data是个struct,每个变量分开占用空间.依次为int4 + DATE20 + doubles = 32.所以结果是20 + 32 = 52.当然.在某些!6位编辑器下,int可能是2字节,那么结果 是 int2 + DATE
21、10 + doubles = 226 .unsigned short hash(unsigned short key) return (key)%256 请问 hash(16),hash(256)的值分别是:A.1.16;B.8.32;C.4.16;D.1.3227请问下面程序有什么错误?int a602501000,i,j,k;for(k=0;k=l 000;k+)for(j=0;j250;j+)for(i=0;i60;i+)ajk=O;把循环语句内外换一下28下面程序的打印结果是什么?请分析#define Max_CB 500void LmiQueryCSmd(Struct MSgCB *
22、 pmsg) unsigned char ucCmdNum;for(ucCmdNum=0;ucCmdNum= - EPSINON) & (x =”或“v=”此类形式 如下是错误的写法,不得分。if(x=0.0) if(x !=0.0)请写出char*p与“零值”比较的if语句。(3分)标准答案:if (p = NULL) if(p != NULL)如下写法均属不良风格,不得分。if (p = 0) if (p != 0) if (p) if (!)30编写类String的构造函数、析构函数和赋值函数已知类String的原型为:class String public:String(const c
23、har *str = NULL); / 普通构造函数 String(const String &other);/Z 拷贝构造函数 String(void);析构函数String & operate =(const String &other); /Z 赋值函数 private:char *m_data;用于保存字符串);请编写String的上述4个函数。标准答案:、String:String(void) 3 分 delete m_data;山于m_data是内部数据类型,也可以写成delete m_data;/ String 的普通构造函数String:String(const char *s
24、tr) 6 分if(str=NULL)m_data = new charl; /若能加NULL判断则更好*m_data = 、0;)elseint length = strlen(str);String:String(void)3 分delete m_data;由于m_data是内部数据类型,也可以写成delete m_data;/ String的普通构造函数String: :String(const char *str) 6 分if(str=NULL)m_data = new charfl; /若能加NULL判断则更好*m_data= 、0;elseint length = strlen(s
25、tr);strcpy(m_data, other.m_data); 赋值函数String & String: :operate =(const String &other) 13 分 (1)检查自赋值 4 分 if(this = &other)return來this,文章来源草根IT/释放原有的内存资源 3分delete m_data;/ (3)分配新的内存资源,并复制内容3分int length = strlen(other.m_data);m_data = new charlength+l;/ 若能加 NULL 判断则更好strcpy(m_data, other. m_data)/ (4)
26、返回本对象的引用3分return *this;31引用”与指针的区别是什么?指针通过某个指针变量指向个对象后,对它所指向的变量间接操作。程序中使用指针,程序 的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。此外, 就是上面提到的对函数传ref和pointer的区别32结构与联合有和区别?1 .结构和联合都是山多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了 个被选中的成员(所有成员共用块地址空间),而结构的所有成员都存在(不同成员的存 放地址不同)。2 .对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结 构的不同成员赋值是互不
27、影响的33.下面关于“联合”的题目的输出?a) # i nclude union int i;char x2; a;void main() a.x0 = 10; a.xl= 1; printf(%d,a.i); 答案:266 (低位低地址,高位高地址,内存占用情况是OxOlOA)b) main() union /定义一个联合/int i;struct /在联合中定义个结构*/char first;char second;half; number;number.i=0x4241;/ 联合成员赋值*/printf(,%c%cn, number.half.first, mumber.half.sec
28、ond);number.half.first=a,; /*联合中结构成员赋值/number.half.second=,b,;getch(); 答案:AB (0x41 对应TV,是低位;0x42 对应B,是高位)6261 (number.i 和 number.half 共用块地址空间)34关联、聚合(Aggregation)以及组合(Composition)的区别?涉及到UML中的些概念:关联是表示两个类的一般性联系,比如“学生”和“老师” 就是种关联关系:聚合表示has-a的关系,是种相对松散的关系,聚合类不需要对被聚合 类负责,如下图所示,用空的菱形表示聚合关系:从实现的角度讲,聚合可以表示
29、为:class A . class B A* a; .而组合表示contains-a的关系,关联性强于聚合:组合类 与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关 系:实现的形式是:class A. class B A a;.35面向对象的三个基本特征,并简单叙述之?1.封装:将客观事物抽象成类,毎个类对自身的数据和方法实行protection (private, protected, public) 2.继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需 额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性 和
30、方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=接口继承以及纯虚 函数)构成了功能复用的两种方式。3.多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就 可以根据当前赋值给它的子对象的特性以不同的方式运作。筒単的说,就是一句话:允许将子 类类型的指针赋值给父类类型的指针36.重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数 类型不同,或许两者都不同)。重写:是指子类重新定义复类虚函数的方法。从实现原理 上来说:帀载:编译器根据函数不同的参
31、数表,对同名函数的名称做修饰,然后这些同名函数 就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func (p: integer): integer;和 function func (p: string): integer; 那么编译器做过修饰后的函数名称 可能是这样的:injfunc、stjfunc.对于这两个函数的调用,在编译器间就已经确定了,是静态 的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关! 重写: 和多态真正相关。当子类車新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针, 动态的调用属于子类的该函数,这样的
32、函数调用在编译期间是无法确定的(调用的子类的虚函 数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)37多态的作用是什么?主要是两个:1.隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;2.接 口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某属性时的正确调用38若没有定义拷贝构造函数,则编译器自动生成一个缺省的拷贝构造函数,它可能会产生什 么问题?浅拷贝问题,主要原因为类中如果有指针成员变量时,当调用拷贝构造函数时只拷贝地址从 而使两个对象的指针变量指向了一个地址空间。39简述成员函数、全局函数和友元函数的差别。成员函数只能由该类所实例化的对象来进
33、行调用。静态成员除外全局函数可以在任意位置进行调用。友元函数可以让本类和友元类对象调用。40.简述结构化的程序设计、面向对象的程序设计的基本思想。结构化程序设计为从程序代码的开始处按照顺序方式执行至代码的结束位置。是一种顺序的方 式,函数与变量没有明显的联系,面向对象主要把处理事情的事物和方法结合为一体成为 个类,一个类具备处理一件事情的数据变量和处理方法,把数据和方法有机的结合为了一体, 使每一件事情都具备一定的独立性,形成一个模块。增加了内聚性,降低了耦合性。同时也增 加了代码的可读性以及代码的帀用性。41结构struc(和类class有什么异同?在c语言中struct只能对数据进行聚合,
34、而C+的class把数据以及对数据的处理方法也同时聚 合为一体,增加了内聚性。此外class拥有可再生性和可抽象性,实现的代码的复用。集中体 现在派生的功能和多态的功能。同时class也比struct具备更好的封装性,体现在三种访问权 限上。在C+中的struct和class的结构基本一致,只是struct的默认权限为Public而class为private=42C+是不是类型安全的?答案:不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全 的。43简述数组与指针的区别?数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意
35、类型的内存块。(1)修改内容上的差别char a = hello” ; a0 = X;char *p = world;注意p指向常量字符串p0= X;编译器不能发现该错误,运行时错误(2)用运算符sizeof可以计算出数组的容量(字节数)。sizeof (p), p为指针得到的是 个指针变量的字节数,而不是p所指的内存容量。C+/C语言没有办法知道指针所指的内存容量,除非 在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指 针。char a = hello world; char *p = a; cout sizeof(a) endl; / 12字节 cout
36、sizeof(p)endl; 4 字节 计算数组和指针的内存容 量 void Func(char a100) cout sizeof(a) endl; / 4 字节不是 !00 字节44如何判断一段程序是由C编译程序还是由C+编译程序编译的?答案:#ifdef _cplusplus coutvc+”; #else coutucH; #endif45.main主函数执行完毕后,是否可能会再执行一段代码,给出说明?答案:可以,可以用onexit注册个函数,它会在main之后执行intfnl (void), fn2 (void), fn3 (void), fn4 (void); void main(
37、 void ) String str(zhanglinn); _onexit( fnl ); _onexit( fn2 ); _onexit( fn3 ); _onexit( fn4 );printf( This is executed firstAn); int fnl() printf( nextAn );retum 0; int fn2()printf( executed H ); return 0; int fn3() printf( is *); return 0; int fn4() printf( uThis n); return 0; 46文件中有一组整数,要求排序后输出到另一
38、个文件中# i nclude # i nclude using namespace std;void Order(vector& data) /bubble sort int count = data.size()int tag = false /Z设置是否需要继续冒泡的标志位for (int i = 0 i count i+)for (int j = 0 j dataj+l) tag = trueint temp = datajdataj = datajj+1 data|j+l = temp if( !tag) break ) void main( void ) vectordata;ifs
39、tream in(nc:data.txt); if ( !in) coutfile error!*;exit(l); ) int temp; while (!in.eof() intemp;data.push_back(temp); in.close。; 关闭输入文件流 Order(data);ofstream out(c:result.txt); if ( !out)coutHfile error!;exit(l); )for (i = 0 i next = NULL)return head; Node *pl = head; Node *p2 = pl-next ;Node *p3 = p
40、2-next ;pl-next = NULL;while ( p3 != NULL) p2-next = pl ; p 1 = p2 ;p2 = p3p3 = p3-next; p2-next = pl ;head = p2 ; return head; (2)已知两个链表headl和head2各自有序,请把它们合并成一个链表依然有序。(保留 所有结点,即便大小相同)Node * Merge(Node *headl , Node *head2) if ( head 1 = NULL) return head2 ;if ( head2 = NULL) return head 1 ;Node *h
41、ead = NULL ;Node *pl = NULL; Node *p2 = NULL;if ( headl-data data ) head = headl pl = headl-next; p2 = head2 elsehead = head2 ;p2 = head2-next; p 1 = head I ;Node *pcurrent = head ;while (pl != NULL & p2 != NULL) if ( p 1 -data data ) pcurrent-next = pl ;pcurrent = pl ;pl = pl-next; else pcurrent-ne
42、xt = p2 ;pcurrent = p2 ;p2 = p2-next if ( pl != NULL) pcurrent-next = pl ;if(p2 != NULL)pcurrent-next = p2 ;return head ; (3)已知两个链表headl和head2各自有序,请把它们合并成一个链表依然有序,这次要求 用递归方法进行。(Autodesk)答案:Node * MergeRecursive(Node *headl , Node *head2) if ( headl = NULL) return head2;if ( head2 = NULL) return head
43、l ;Node *head = NULL ;if ( head 1 -data data ) head = head 1 ;head-next = MergeRecursive(head 1 -next,head2); else head = head2 ;head-next = MergeRecursive(head 1 ,head2-next); return head; 48写个函数找出个整数数组中,第二大的数(microsoft) 答案:const int MINNUMBER = -32767int find_sec_max( int data, int count) int maxnumber = data0 ; int sec_max = MINNUMBER ;for (int i = 1 i maxnumber) sec max = maxnumber;mber-dau- Ulse Iif ( data sec_max )sec_max = data; return sec_max; 49如何判断个单链表是有环的?(注意不能用标志位,最多只能用两个额外指 针)struct node char val;