c++经典面试题.docx

上传人:b****7 文档编号:10719241 上传时间:2023-02-22 格式:DOCX 页数:20 大小:130.54KB
下载 相关 举报
c++经典面试题.docx_第1页
第1页 / 共20页
c++经典面试题.docx_第2页
第2页 / 共20页
c++经典面试题.docx_第3页
第3页 / 共20页
c++经典面试题.docx_第4页
第4页 / 共20页
c++经典面试题.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

c++经典面试题.docx

《c++经典面试题.docx》由会员分享,可在线阅读,更多相关《c++经典面试题.docx(20页珍藏版)》请在冰豆网上搜索。

c++经典面试题.docx

c++经典面试题

1.C和C++中struct有什么区别?

C语言中:

Struct是用户自定义数据类型(UDT)

C++语言中:

Struct是抽象数据类型(ADT),支持成员函数的定义。

在C++中,struct的成员的默认访问说明符为public,class为private。

c中的struct是没有权限设置的. 

C++中struct增加了访问权限,且可以和类一样有成员函数。

C++中的struct等同于class,只是class默认成员权限是private,而struct默认成员权限是public。

1>C++中的struct类似于class,有变量,有构造函数、虚函数等,有继承,多态等类的特征;

2>2>C中的struct只有变量,不能有函数,但是可以有函数指针

2.C++中的struct和class有什么区别?

在C++中,两者区别不大,但是有2个主要的区别

1>。

继承权限:

struct默认是public继承;class默认是private继承

2〉。

访问权限:

struct默认是public访问;class默认是private访问

3。

如何判断一段程序是由C编译程序还是由C++编译程序编译的?

【标准答案】 

#ifdef__cplusplus

cout〈<“c++”;

#else

cout<<”c";

#endif

(这个以前还真没注意过,涨姿势了。

4.C和C++有什么不同?

 

【参考答案】

从机制上:

 

c是面向过程的(但c也可以编写面向对象的程序);

c++是面向对象的,提供了类。

但是,c++编写面向对象的程序比c容易。

 

从适用的方向:

c适合要求代码体积小的,效率高的场合,如嵌入式;c++适合更上层的,复杂的;linux核心大部分是c写的,因为它是系统软件,效率要求极高。

从名称上也可以看出,c++比c多了+,说明c++是c的超集;那为什么不叫c+而叫c++呢,是因为c++比c来说扩充的东西太多了,所以就在c后面放上两个+;于是就成了c++。

 

C语言是结构化编程语言,C++是面向对象编程语言。

C++侧重于对象而不是过程,侧重于类的设计而不是逻辑的设计。

关于这个问题,个人觉得《EffectiveC++》上面第一条说的很好,

ViewC++asafederationoflanguages。

把C++当做一个语言联邦。

C++由四部分组成

1>c语言部分;

2>面向对象部分,包括封装、继承、多态这些C语言所没有的特性;

3>泛型编程部分,大多数类、函数要考虑到把它设计成模板,方便复用;

4〉STL库,里面封装了大量的优秀模板,是3>中内容的集成,学会使用它们可以让代码更高效。

当然,最好去深入了解STL源码,那样会对C++有更深的理解。

5.“引用”与指针的区别是什么?

【参考答案】

指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。

程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。

在另一本C++著作《MoreEffectiveC++》里,第一条就是论述point和reference的区别

总结一下,

1>指针是一个存储地址的变量,而引用是一个变量的别名。

所以在一个函数中,传引用要比传指针速度更快。

2〉指针可以指向一个空值,而引用必须初始化。

指针可以如下形式出现

[cpp]viewplaincopy

1.int *p;  

是合法但不合理的(相当于是一个野指针)。

可以声明一个指向空值的指针

[cpp]viewplaincopy

1.int *p=null  

而引用不行

[cpp]viewplaincopy

1.int &r;  

是错误的

引用必须初始化为一个变量的别名,如

[cpp]viewplaincopy

1.int a=5;  

2.int &r=a;  

3>也是因为2〉的特性,指针在使用前要判断是否为空,而引用必定不为空(否则会报错),所以不用判断。

4〉指针可以更改指向的内存地址,而引用是和变量绑定的,不可更改。

5〉在运算符重载过程中,通常返回一个引用往往比返回一个指针更好,使用指针易引起语义上的歧义.

6.

classA

{

virtualvoidfunc1(); 

voidfunc2();

};

classB:

classA 

{

voidfunc1()

cout〈<"fun1inclassB”〈

} 

       virtualvoidfunc2()

       {

           cout〈〈"fun2inclassB"<

       }

A,A中的func1和B中的func2都是虚函数

B,A中的func1和B中的func2都不是虚函数.

C,A中的func2是虚函数.,B中的func1不是虚函数.

D,A中的func2不是虚函数,B中的func1是虚函数. 

【标准答案】A

水题。

7。

intid[sizeof(unsignedlong)];这个对吗?

为什么?

【标准答案】

正确

这个sizeof是编译时运算符,编译时就确定了可以看成和机器有关的常量。

8。

某文件中定义的静态全局变量(或称静态外部变量)其作用域是()?

A.只限某个函数B。

本文件

  C.跨文件D。

不限制作用域

  

【参考答案】B。

静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。

由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

在《C和指针》上看过,static关键字会改变具有外部链接性的变量和函数

9.C++函数中值的传递方式有哪几种?

【标准答案】

C++函数的三种传递方式为:

值传递、指针传递和引用传递。

(指针传递就是通常说的地址传递)

10。

对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?

【标准答案】c用宏定义,c++用inline

define实现的函数功能容易出bug,所以在c++中最好不要使用

11。

引用与指针有什么区别?

【参考答案】 

1)引用必须被初始化,指针不必。

2)引用初始化以后不能被改变,指针可以改变所指的对象。

3)不存在指向空值的引用,但是存在指向空值的指针。

可以参考下在5题中补充的内容

12。

C++中virtual与inline的含义分别是什么?

【参考答案】

在基类成员函数的声明前加上virtual关键字,意味着将该成员函数声明为虚函数。

inline与函数的定义体放在一起,使该函数称为内联。

inline是一种用于实现的关键字,而不是用于声明的关键字。

虚函数的特点;如果希望派生类能够重新定义基类的方法,则在基类中将该方法定义为虚方法,这样可以启用动态联编。

内联函数的特点;使用内联函数的目的是为了提高函数的运行效率。

内联函数体的代码不能过长,因为内联函数省去调用函数的时间是以代码膨胀为代价的。

内联函数不能包含循环语句,因为执行循环语句要比调用函数的开销大。

哈!

我想我确实要注意一下表达能力.。

13。

VC中,编译工具条内的Debug与Release选项是什么含义?

【参考答案】

Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。

Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

Debug带有大量的调试代码,运行时需要相应的运行库,

发布模式程序紧凑不含有调试代码和信息,直接可以运行(如果不需要运行库)

14。

函数assert的用法?

【参考答案】断言assert是仅在debug版本起作用的宏,用于检查“不应该“发生的情况。

程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段

学VC++的时候见过assert宏定义,但是自己从来没用过.。

15.const 与#define的比较,const有什么优点?

【参考答案】

(1)const常量有数据类型,而宏常量没有数据类型。

编译器可以对前者进行类型安全检查。

而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。

 

#define不能生成类的专属常量,因为它只是进行简单的替换。

(2) 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

《EffectiveC++》中建议以const、enum、inline代替#define.

使用enum的原因

有些情况下,编译器不允许静态常量出现在类的初始设定中,只得以enum的形式

另一方面,enum和#define更相似,它们都没有具体的类型,比如,有constinta;却没有#defineNinta,enum和#define都不能够被去地址,而const可以.

16.请你谈谈引用和指针的区别。

【参考答案】

(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。

 

(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。

 

(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象).

不断地出现,可见这个问题是经常容易被问到的.

17。

有了malloc/free为什么还要new/delete ?

【参考答案】

malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。

它们都可用于申请动态内存和释放内存.

 对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。

对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数.

由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

 

因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete.注意new/delete不是库函数。

以前只是习惯在用C时用malloc/free,用C++时用new/delete,没注意到这些差异性。

18。

如果在申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存申请失败。

你是怎么处理内存耗尽的?

【参考答案】

(1)判断指针是否为NULL,如果是则马上用return语句终止本函数.

(2)判断指针是否为NULL,如果是则马上用exit

(1)终止整个程序的运行 

(3)为new和malloc设置异常处理函数。

例如VisualC++可以用_set_new_hander函数为new设置用户自己定义的异常处理函数,也可以让malloc享用与new相同的异常处理函数.

我一般是直接return了

19.C++是不是类型安全的?

【参考答案】不是。

两个不同类型的指针之间可以强制转换(用reinterpretcast)。

20。

const符号常量;

(1)constchar*p

(2)charconst*p(

3)char*constp

说明上面三种描述的区别;

【参考答案】

(1)p是一个指向constchar的指针,p是可以改变指向的,但是p指向的值是不能改变的;    

(2)p指向的恰好是一个指向const的char的普通指针;

(3)p是一个指针,这个指针是指向char的const指针。

    

(1)和

(2)的定义是一样的.

1、2和3的区别在于,1和2的const出现在*号左边,3出现在*号右边.好像也是在《C和指针》上看到的这句话.

21。

用C++写个程序,如何判断一个操作系统是16位还是32位的?

【标准答案】定义一个指针p,打印出sizeof(p),如果节果是4,则表示该操作系统是32位,打印结果是2,表示是16位。

22.用C++写个程序,如何判断一个操作系统是16位还是32位的?

不能用sizeof()函数。

【参考答案】 

 

[cpp]viewplaincopy

1.int a = ~0;  

2.if( a>65536 )  

3.{         

4.cout〈〈”32 bit"〈〈endl;     

5.}  

6.else  

7.{  

8.cout<〈”16 bit"<

9.}  

这个参考答案估计参考了不少年了。

.现在大部分机器都32、64位的了,所以,应该把65536改为4294967296,来判断机器是32位||64位

23。

[cpp]viewplaincopy

1.void * ( * (*fp1)(int))[10];

      

2.float (*(* fp2)(int,int,int))(int);

       

3.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型。

24。

多态类中的虚函数表是Compile—Time,还是Run-Time时建立的?

【标准答案】虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员—-虚拟函数表指针是在运行期—-也就是构造函数被调用时进行初始化的,这是实现多态的关键。

25。

错误的转义字符是()

A。

’\091'B。

’\\’

C.'\0’D.’\’‘

【标准答案】A

A错误的关键在于,其中出现了9,这样它就不是8进制的转换了。

26.若数组名作实参而指针变量作形参,函数调用实参传给形参的是()

A。

数组的长度B.数组第一个元素的值

C。

数组所有元素的值D。

数组第一个元素的地址

【标准答案】D

27.变量的指针含意是指变量的()

A.值 B。

地址C。

存储 

D。

名字

【标准答案】B

28.内存的分配方式有几种?

【参考答案】

一、从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。

例如全局变量.

二、在栈上创建。

在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。

栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限.

三、从堆上分配,亦称动态内存分配。

程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。

动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

29。

floata,b,c,问等式(a+b)+c==(b+a)+c和(a+b)+c==(a+c)+b能否成立?

【参考答案】

两者都不行。

在比较float或double时,不能简单地比较.由于计算误差,相等的概率很低。

应判断两数之差是否落在区间(-e,e)内。

这个e应比浮点数的精度大一个数量级。

 

我想到的是另一个运算符%.不能对float或double使用%运算符,原因和参考答案中的说法类似

30.全局变量和局部变量有什么区别?

是怎么实现的?

操作系统和编译器是怎么知道的?

 

【参考答案】

1>/2>

生命周期不同:

全局变量随主程序创建而创建,随主程序销毁而销毁;内存中分配在全局数据区。

局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在;分配在栈区。

 

使用方式不同:

通过声明后全局变量程序的各个部分都可以用到;

局部变量只能在局部使用; 

3>

操作系统和编译器通过内存分配的位置来知道的,

全局变量分配在全局数据段并且在程序开始运行的时候被加载。

局部变量则分配在堆栈里面。

另,全局变量会被初始化为0,而局部变量以随机值进行初始化

31。

Heap与stack的差别

【参考答案】

Heap是堆,stack是栈。

Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。

Stack空间有限,Heap是很大的自由存储区

C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。

程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行

32。

InC++,whatdoes"explicit"mean?

whatdoes”protected"mean?

 

【标准答案】

c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,在某些情况下,我们要求类的使用者必须显示调用类的构造函数时就需要使用explicit,反之默认类型转换可能会造成无法预期的问题。

protected控制的是一个函数对一个类的成员(包括成员变量及成员方法)的访问权限。

protected成员只有该类的成员函数及其派生类的成员函数可以访问。

我擦!

它俩为啥放在一起问.

33。

重复多次fclose一个打开过一次的FILE*fp指针会有什么结果,并请解释。

 

【参考答案】考察点:

导致文件描述符结构中指针指向的内存被重复释放,进而导致一些不可预期的异常。

 

34.为什么数组名作为参数,会改变数组的内容,而其它类型如int却不会改变变量的值?

【参考答案】当数组名作为参数时,传递的实际上是地址.而其他类型如int作为参数时,由于函数参数值实质上是实参的一份拷贝,被调函数内部对形参的改变并不影响实参的值。

传值与传地址的区别

35.你觉得如果不使用常量,直接在程序中填写数字或字符串,将会有什么麻烦?

 

【参考答案】

(1) 程序的可读性(可理解性)变差。

程序员自己会忘记那些数字或字符串是什么意思,用户则更加不知它们从何处来、表示什么. 

(2) 在程序的很多地方输入同样的数字或字符串,难保不发生书写错误。

 

(3) 如果要修改数字或字符串,则会在很多地方改动,既麻烦又容易出错。

36。

为什么需要使用堆,使用堆空间的原因?

【参考答案】直到运行时才知道一个对象需要多少内存空间;不知道对象的生存期到底有多长。

因为需要动态分配内存啊。

37。

 const关键字?

有哪些作用

【参考答案】const关键字至少有下列n个作用:

(1)欲阻止一个变量被改变,可以使用const关键字.在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;

(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;

(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;

(这样既可以利用传地址、传引用的高效特性,又保证了传值的安全性)

(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;

还记得如果要修改成员变量,应该把成员变量声明为什么吗?

mutable!

(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值"。

更多更详细的内容,推荐看《EffectiveC++》

38。

、是不是一个父类写了一个virtual函数,如果子类覆盖它的函数不加virtual,也能实现多态?

【参考答案】virtual修饰符会被隐形继承的。

virtual可加可不加。

子类的空间里有父类的所有变量(static除外)。

同一个函数只存在一个实体(inline除外)。

子类覆盖它的函数不加virtual,也能实现多态。

在子类的空间里,有父类的私有变量。

私有变量不能直接访问.不过最好是加上,加上表明它是一个虚函数,这样提高了代码的阅读性.

39。

面向对象的三个基本特征,并简单叙述之?

【参考答案】                                   

1。

封装:

将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,protected,public)         

2。

继承:

广义的继承有三种实现形式:

实现继承(指使用基类的属性和方法而无需额外编码的能力)、

可视继承(子窗体使用父窗体的外观和实现代码)、

接口继承(仅使用属性和方法,实现滞后到子类实现)。

前两种(类继承)和后一种(对象组合=〉接口继承以及纯虚函数)构成了功能复用的两种方式。

                3。

多态:

是将父对象设置成为和一个或更多的与他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。

简单的说,就是一句话:

允许将子类类型的指针赋值给父类类型的指针.

40。

重载(overload)、重写(override,有的书也叫做“覆盖”)、重定义(redefinition)的区别?

【标准答案】

41.多态的作用?

【参考答案】

主要是两个:

1.隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;

2。

接口重用:

为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用.

42.当一个类A中没有声明任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。

【标准答案】sizeof(A)=1;

编译器不允许一个类的大小为0,会为它分配1字节的内存.试想,若,不这样做,那2个类A的实例在内存中将会无法区分。

43.如果ClassA中定义并实现虚函数intfunc(void),ClassB中也实现该函数,

那么

[cpp]viewplaincopy

1.A a;  

2.a->func()  

将调用哪个类里面的函数?

如果intfun

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1