100条经典C++笔试题⽬及答案分享
c语言和c++区别100条经典C++笔试题⽬分享
看到好⽤的经典C++题⽬,对机试和笔试,甚⾄⾯试都有帮助,特意分享,⾃⼰也复习⼀遍,互勉。
题⽬来源:
1、中兴、华为、慧通、英华达、微软亚洲技术中⼼等中外企业⾯试题⽬;
2、C++⾯试宝典(林锐《⾼质量编程第三版》)、C++ primer、Thinking in C++。
⼀、C++与C差异(1-17)
1.C和C++中struct有什么区别?
【答案】
Protection⾏为能否定义函数
c⽆否,但可以有函数⼦针
c++有,默认private可以
2.C++中的struct和class有什么区别?
【答案】从语法上讲,class和struct做类型定义时只有两点区别:
(1)默认继承权限。如果不明确指定,来⾃class的继承按照private继承处理,来⾃struct的继承按照public继承处理;
(2)成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。 除了这两点,class和struct基本就是⼀个东西。语法上没有任何其它区别。
(敲⿊板:继承和访问权限不同,struct为public,class为private)
3.如何判断⼀段程序是由C 编译程序还是由C++编译程序编译的?
【答案】
运⽤编译标志宏,窗体直接运⾏以下代码:
#include<iostream>
int main()
{
#ifdef __cplusplus
printf("C++\n");
#else
printf("c\n");
#endif
system("pause");
return0;
}
4.C和C++有什么不同?
【答案】
机制:c是⾯向过程的(但c也可以编写⾯向对象的程序);
c++是⾯向对象的,提供了类。但是,c++编写⾯向对象的程序⽐c容易。
适⽤⽅向:c适合要求代码体积⼩的,效率⾼的场合,如嵌⼊式;
c++适合更上层的,复杂的; llinux核⼼⼤部分是c写的,因为它是系统软件,效率要求极⾼。
名称:c++⽐c多了+,说明c++是c的超集;那为什么不叫c+⽽叫c++呢,是因为c++⽐c来说扩充的东西太多了,所以就在c后⾯放上两个+;于是就成了c++。
总之,C语⾔是结构化编程语⾔,C++是⾯向对象编程语⾔。C++侧重于对象⽽不是过程,侧重于类的设计⽽不是逻辑的设计。
5.“引⽤”与指针的区别是什么?
【答案】指针是存储变量内容的地址,指针操作是通过某个指针变量指向⼀个对象后,对它所指向的变量间接操作,也就是地址间的操作,程序中使⽤指针,程序的可读性差;⽽引⽤本⾝就是⽬标变量的别名,对引⽤的操作就是对⽬标变量的操作。
6.class A {
virtual void func1();
void func2();
} ;
class B: class A
{
void func1(){
cout < < “func1 in class B” < < endl;}
virtual void func2(){cout < < “fun2 in class B” < < endl;}
}
A. A中的func1和B中的func2都是虚函数.
B. A中的func1和B中的func2都不是虚函数.
C. A中的func2是虚函数,B中的func1不是虚函数.
D. A中的func2不是虚函数,B中的func1是虚函数.
【答案】A
7.int id[sizeof(unsigned long)];这个对吗?为什么?
【答案】正确,这个sizeof是编译时运算符,编译时就确定了,可以看成和机器有关的常量。
8.某⽂件中定义的静态全局变量(或称静态外部变量)其作⽤域是 ()?
A.只限某个函数
B.本⽂件
C.跨⽂件
D.不限制作⽤域
【答案】B。静态全局变量则限制了其作⽤域, 即只在定义该变量的源⽂件内有效, 在同⼀源程序的其它源⽂件中不能使⽤它。由于静态全局变量的作⽤域局限于⼀个源⽂件内,只能为该源⽂件内的函数公⽤, 因此可以避免在其它源⽂件中引起错误。
9.C++函数中值的传递⽅式有哪⼏种?
【答案】C++函数的三种传递⽅式为:值传递、指针传递和引⽤传递。
10.对于⼀个频繁使⽤的短⼩函数,在C语⾔中应⽤什么实现,在C++中应⽤什么实现?
【答案】c⽤宏定义,c++⽤inline
11.引⽤与指针有什么区别?
【答案】
1. 引⽤创建时必须同时被初始化,指针可以在任何时候初始化。
2. 引⽤初始化后不能改变引⽤关系,指针能随时改变所指的对象。
3. 不存在指向空值的引⽤,但是存在指向空值的指针。
12.C++中virtual与inline的含义分别是什么?
【答案】
在基类成员函数的声明前加上virtual关键字,意味着将该成员函数声明为虚函数。inline与函数的定义体放在⼀起,使该函数称为内联。inline是⼀种⽤于实现的关键字,⽽不是⽤于声明的关键字。
虚函数的特点:如果希望派⽣类能够重新定义基类的⽅法,则在基类中将该⽅法定义为虚⽅法,这样可以启⽤动态联编。
内联函数的特点:使⽤内联函数的⽬的是为了提⾼函数的运⾏效率。内联函数体的代码不能过长,因为内联函数省去调⽤函数的时间是以代码膨胀为代价的。内联函数不能包含循环语句,因为执⾏循环语句要⽐调⽤函数的开销⼤。
13.VC中,编译⼯具条内的Debug与Release选项是什么含义?
【答案】Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进⾏了各种优化,使得程序在代码⼤⼩和运⾏速度上都是最优的,以便⽤户很好地使⽤。Debug带有⼤量的调试代码,运⾏时需要相应的运⾏库,发布模式程序紧凑不含有调试代码和信息,直接可以运⾏(如果不需要运⾏库)
14.函数assert的⽤法?
【答案】断⾔assert是仅在debug版本起作⽤的宏,⽤于检查“不应该“发⽣的情况。程序员可以把assert看成⼀个在任何系统状态下都可以安全使⽤的⽆害测试⼿段。
【答案】
(1) const 常量有数据类型,⽽宏常量没有数据类型。编译器可以对前者进⾏类型安全检查。⽽对后者只进⾏字符替换,没有类型安全检查,并且在字符替换可能会产⽣意料不到的错误(边际效应) 。 (2) 有些集成化的调试⼯具可以对 const 常量进⾏调试,但是不能对宏常量进⾏调试。
16.有了 malloc/free 为什么还要 new/delete?
【答案】
malloc 与 free 是 C++/C 语⾔的标准库函数,new/delete 是 C++的运算符。它们都可⽤于申请动态内存和释放内存。 对于⾮内部数据类型的对象⽽⾔,光⽤ maloc/free ⽆法满⾜动态对象的要求。对象在创建的同时要⾃动执⾏构造函数,对象在消亡之前要⾃动执⾏析构函数。由于malloc/free 是库函数⽽
不是运算符,不在编译器控制权限之内,不能够把执⾏构造函数和析构函数的任务强加malloc/free。 因此 C++语⾔需要⼀个能完成动态内存分配和初始化⼯作的运算符 new,以及⼀个能完成清理与释放内存⼯作的运算符 delete。注意
new/delete 不是库函数。
17.如果在申请动态内存时不到⾜够⼤的内存块,malloc 和 new 将返回 NULL 指针,宣告内存申请失败。你是怎么处理内存耗尽的?【答案】
(1)判断指针是否为 NULL,如果是则马上⽤ return 语句终⽌本函数。
(2)判断指针是否为 NULL,如果是则马上⽤ exit(1)终⽌整个程序的运⾏
(3)为 new 和 malloc 设置异常处理函数。例如 Visual C++可以⽤_set_new_hander 函数为 new 设置⽤户⾃⼰定义的异常处理函数,也可以让 malloc 享⽤与 new 相同的异常处理函数。
⼆、数据类型、关键字(18-37)
18.C++是不是类型安全的?
【答案】不是。两个不同类型的指针之间可以强制转换(⽤reinterpret cast)。
(1)const char *p
(2)char const *p
(3)char * const p
说明上⾯三种描述的区别;
【答案】(1)p是⼀个指向const char的指针,p是可以改变指向的,但是p指向的值是不能改变的;(2)p指向的恰好是⼀个指向const的char 的普通指针;(3)p是⼀个指针,这个指针是指向char的const指针。(1)和(2)的定义是⼀样的。
20.⽤C++写个程序,如何判断⼀个操作系统是16位还是32位的?
【答案】定义⼀个指针p,打印出sizeof( p ),如果节后是4,则表⽰该操作系统是32位,打印结果是2,表⽰是16位。
21.⽤C++写个程序,如何判断⼀个操作系统是16位还是32位的?不能⽤sizeof()函数。
【答案】
int a =~0;
if( a>65536){
cout<<"32 bit"<<endl;
}
else{
cout<<"16 bit"<<endl;
}
22.以下分别表⽰什么意思:
void * ( * ( * fp1)(int))[10];
float ( * ( * fp2)(int,int,int))(int);
int (* ( * fp3)())[10] ();
【答案】
(1)void * ( * (fp1)(int))[10]
fp1是⼀个指针,指向⼀个函数,这个函数的参数为int型,函数的返回值是⼀个指针,这个指针指向⼀个数组,这个数组有10个元素,每个元素是⼀个void型指针。
(2)float (( fp2)(int,int,int))(int)
fp2是⼀个指针,指向⼀个函数,这个函数的参数为3个int型,函数的返回值是⼀个指针,这个指针指向⼀个函数,这个函数的参数为int 型,函数的返回值是float型。
(3)int (* ( * fp3)())[10] ()
fp3是⼀个指针,指向⼀个函数,这个函数的参数为空,函数的返回值是⼀个指针,这个指针指向⼀个数组,这个数组有10个元素,每个元素是⼀个指针,指向⼀个函数,这个函数的参数为空,函数的返回值是int型。
23.多态类中的虚函数表是Compile-Time,还是Run-Time时建⽴的?
【答案】虚拟函数表是在编译期就建⽴了,各个虚拟函数这时被组织成了⼀个虚拟函数的⼊⼝地址的数组.⽽对象的隐藏成员–虚拟函数表指针是在运⾏期–也就是构造函数被调⽤时进⾏初始化的,这是实现多态的关键。
24.错误的转义字符是 ()
A.’\091’
B.’ \ \ ’
C.’\0’
D.’ \ ’
【答案】A
25.若数组名作实参⽽指针变量作形参,函数调⽤实参传给形参的是()
A.数组的长度
B.数组第⼀个元素的值
C.数组所有元素的值
D.数组第⼀个元素的地址
【答案】D
26.变量的指针含意是指变量的 ()
A.值
B.地址
C.存储
D.名字
【答案】B
27.内存的分配⽅式有⼏种?
【答案】
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运⾏期间都存在。例如全局变量。
(2)在栈上创建。在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运⾏的时候⽤malloc或new申请任意多少的内存,程序员⾃⼰负责在何时⽤free或delete释放内存。动态内存的⽣存期由我们决定,使⽤⾮常灵活,但问题也最多。
28.float a,b,c ,问等式 (a+b)+c==(b+a)+c 和(a+b)+c==(a+c)+b能否成⽴?
【答案】两者都不⾏。在⽐较float或double时,不能简单地⽐较。由于计算误差,相等的概率很低。应判断两数之差是否落在区间(-e,e)内。这个e应⽐浮点数的精度⼤⼀个数量级。
29.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?
【答案】⽣命周期不同:全局变量随主程序创建和创建,随主程序销毁⽽销毁;局部变量在局部函数内部,甚⾄局部循环体等内部存在,退出就不存在; 内存中分配在全局数据区。 使⽤⽅式不同:通过
声明后全局变量程序的各个部分都可以⽤到;局部变量只能在局部使⽤,分配在栈区。 操作系统和编译器通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运⾏的时候被加载。局部变量则分配在堆栈⾥⾯ 。
30.Heap与stack的差别
【答案】Heap是堆,stack是栈。Stack的空间由操作系统⾃动分配/释放,Heap上的空间⼿动分配/释放。Stack空间有限,Heap是很⼤的⾃由存储区C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。程序在编译期对变量和函数分配内存都在栈上进⾏,且程序运⾏过程中函数调⽤时参数的传递也在栈上进⾏
31.In C++, what does “explicit” mean? what does “protected” mean?
【答案】c++中的explicit关键字⽤来修饰类的构造函数,表明该构造函数是显式的,在某些情况下,我们要求类的使⽤者必须显⽰调⽤类的构造函数时就需要使⽤explicit,反之默认类型转换可能会造成⽆法预期的问题。protected控制的是⼀个函数对⼀个类的成员(包括成员变量及成员⽅法)的访问权限。protected成员只有该类的成员函数及其派⽣类的成员函数可以访问。
32.重复多次fclose⼀个打开过⼀次的FILE *fp指针会有什么结果,并请解释。
【答案】导致⽂件描述符结构中指针指向的内存被重复释放,进⽽导致⼀些不可预期的异常。
33.为什么数组名作为参数,会改变数组的内容,⽽其它类型如int却不会改变变量的值?
【答案】当数组名作为参数时,传递的实际上是地址。⽽其他类型如int作为参数时,由于函数参数值实质上是实参的⼀份拷贝,被调函数内部对形参的改变并不影响实参的值。
34.你觉得如果不使⽤常量,直接在程序中填写数字或字符串,将会有什么⿇烦?
【答案】
(1)程序的可读性(可理解性)变差。程序员⾃⼰会忘记那些数字或字符串是什么意思,⽤户则更加不知它们从何处来、表⽰什么。(2)在程序的很多地⽅输⼊同样的数字或字符串,难保不发⽣书写错误。
(3)如果要修改数字或字符串,则会在很多地⽅改动,既⿇烦⼜容易出错。
35.为什么需要使⽤堆,使⽤堆空间的原因?
【答案】直到运⾏时才知道⼀个对象需要多少内存空间;不知道对象的⽣存期到底有多长。
【答案】
const关键字⾄少有下列n个作⽤:
(1)欲阻⽌⼀个变量被改变,可以使⽤const关键字。在定义该const变量时,通常需要对它进⾏初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本⾝为const,也可以指定指针所指的数据为const,或⼆者同时指定为const;
(3)在⼀个函数声明中,const可以修饰形参,表明它是⼀个输⼊参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是⼀个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
37.是不是⼀个⽗类写了⼀个virtual 函数,如果⼦类覆盖它的函数不加virtual ,也能实现多态?
【答案】virtual修饰符会被隐形继承的。virtual可加可不加。⼦类的空间⾥有⽗类的所有变量(static除
外)。同⼀个函数只存在⼀个实体(inline除外)。⼦类覆盖它的函数不加virtual ,也能实现多态。在⼦类的空间⾥,有⽗类的私有变量。私有变量不能直接访问。
三、C++⾯向对象的特性(38-61)
38.⾯向对象的三个基本特征,并简单叙述之?
【答案】
(1)封装:将客观事物抽象成类,每个类对⾃⾝的数据和⽅法实⾏protection(private,protected,public)
(2)继承:⼴义的继承有三种实现形式:实现继承(指使⽤基类的属性和⽅法⽽⽆需额外编码的能⼒)、可视继承(⼦窗体使⽤⽗窗体的外观和实现代码)、接⼝继承(仅使⽤属性和⽅法,实现滞后到⼦类实现)。前两种(类继承)和后⼀种(对象组合=>接⼝继承以及纯虚函数)构成了功能复⽤的两种⽅式。
(3)多态:是将⽗对象设置成为和⼀个或更多的与他的⼦对象相等的技术,赋值之后,⽗对象就可以根据当前赋值给它的⼦对象的特性以不同的⽅式运作。简单的说,就是⼀句话:允许将⼦类类型的指针赋值给⽗类类型的指针。
39.重载(overload)、重写(override,有的书也叫做“覆盖”)、重定义(redefinition)的区别?
【答案】
名称名字空间区别
重载同⼀名字⼦空间是指允许存在多个同名函数,⽽这些函数的参数表不同。
重定义/隐藏不同名字⼦空间⽤于继承,派⽣类与基类的函数同名,屏蔽基类的函数
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论