c++经典面试100题

1.某文件中定义的静态全局变量(或称静态外部变量)其作用域是?
答:本文件,静态全局变量限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。


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

#ifdef__cplusplus
	cout<<"c++";
	#else
	cout<<"c";
	#endif

这个没搞懂


3.C++函数中值的传递方式有哪几种?
答:C++函数的三种传递方式为:值传递、指针传递和引用传递。
区别:
a.指针有自己的内存空间,引用只是起一个别名;
b.sizeof计算指针大小为4,而引用则是引用对象的大小;
c.可以有const指针,但是没有const引用;
d.指针可以被初始化为NULL,而引用必须被初始化,且必须是一个已有对象的引用;
e.指针可以有多级指针(**p),而引用只有一级。


4.

class A
{
     
	virtual void func1();
	void func2();	
}
class B :class A
{
     
	void func1(){
     cout<<"fun1 in class B"<<endl;}
	virtual void func2(){
     cout<<"fun2 class B"<<endl;}
}

A. A中的func1和B中的func2都是虚函数
B.A中的func1和B中的func2都不是虚函数
C.A中的func2是虚函数,B中的func1不是虚函数
D.A中的func2不是虚函数,B中的func1是虚函数。
答:A


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

  1. 从机制上,C是面向过程的;C++是面向对象的,提供了类。
  2. 从适用的方向:C适合要求代码体积小的,效率高的场合,如嵌入式;C++适合更山梗的,复杂的;Linux核心大部分都是C写的,因为它是系统软件,效率要求极高。
  3. 从名称上也可以看出C++比C多了+,说明C++是C的超集。
  4. C语言是结构化编程语言,C++是面向对象编程语言。

6.C和C++中struct有什么区别

区别 Protection行为 能否定义函数
C 否,但可以有函数指针
C++ 有,默认是private 可以

7.C++中的struct和class有什么区别?
答:从语法上讲,class和struct做类型定义时只有两点区别:

  1. 默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;
  2. 成员的默认访问权限。class的成员默认时private权限,struct默认时public权限。
    除了这两点,class和struct基本就是一个东西。语法上没有任何其它区别。

8.这个写法对吗?为什么?

int id[sizeof(unsigned long)];

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


9.“new” 在C++中是___?
关键字和运算符,malloc是库函数,不在编译器控制范围之内;new是运算符,在编译器控制范围只内。调用malloc时,从堆中申请内存;调用new时,从堆中申请内存并为内存调用构造函数。
备注:
C++程序在执行时,将内存大方向划分为4个区域

  • 代码区:存放函数体的二进制代码,由操作系统进行管理的
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:由编译器自动分配释放, 存放函数的参数值,局部变量等
  • 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

10.多态的作用?

多态是在不同继承关系的类对象,去调同一函数,产生了不同的行为。

就是说,有一对继承关系的两个类,这两个类里面都有一个函数且名字、参数、返回值均相同,然后我们通过调用函数来实现不同类对象完成不同的事件。

但是构成多态还有两个条件:

  • 调用函数的对象必须是指针或者引用。
  • 被调用的函数必须是虚函数,且完成了虚函数的重写。

1.隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用
2.接口重用,为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性的正确调用。


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


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

  1. 封装,将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,protected,public)
  2. 继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=》接口继承以及纯虚函数)构成了功能复用的两种方式。
  3. 多态:是将父对象设置成为和一个或更多的与他的子对象相等的技术。赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话,允许将子类类型的指针赋值给父类类型的指针。

13.main函数执行之前,还会执行什么代码?
全局对象的构造函数会在main函数之前执行。


14 内存的分配方式有几种?

  1. 静态储存区域分配。内存在程序编译的时候就已经分配好,这快内存在程序的整个运行期间都存在。例如全局变量,静态局部。
  2. 在栈上创建,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高但是分配的内存容量有限——普通的局部变量。
  3. 从堆上分配,也称为动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

15.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?
从作用域看:

全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。

局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。

从分配内存空间看:

全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间

全局变量和局部变量的区别是作用域不同,全局变量从定义位置开始到程序结束,而局部变量只限定义的函数内可使用,全局变量在数据段,而局部变量在栈,局部 变量在函数结束时内存空间就被系统收回,所以要返回的数组或字符串不要用局部变量定义

16.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++应用什么实现?
C用宏定义,C++用inline.(内联函数)。

17.有了malloc/free为什么还要new/delete?
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。他们都可用来申请动态内存和释放内存。对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。对象在消亡之前还是要自动执行析构函数。由于malloc/free。因此C++语言需要一个能够完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。


18.如果在申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存申请失败。你是怎么处理内存耗尽的?

  1. 判断指针是否为NULL,如果是则马上用return语句终止本函数。
  2. 判断指针是否为NULL,如果是则马上用exit(1)终止整个程序的运行

19.用C++写一个程序,如何判断一个操作系统是16位还是32位的?
定义一个指针p,打印出sizeof§,如果节后是4,则表示该操作系统是32位,打印结果是2,表示是16位。


20.用C++写一个程序,如何判断一个操作系统是16位还是32位的?布恩那个用sizeof()函数

unsigned int a=~0;
if(a>65536)
{
     	
	cout<<"32 bit"<<endl;
}
else
{
     
	cout<<"16 bit"<<endl;
	
}

21.为什么需要使用堆,使用堆空间的原因?
直到运行时才知道一个对象需要多少内存空间;不知道对象的生存期到底有多长。


22.错误的转义字符是(A)
A.’\091’
B.’\’
C.’’
D.’’
A:不是八进制数。


23.若数组名作实参而指针变量作形参,函数调用实参传给形参的是(D)
A.数组的长度
B.数组第一个元素的值
C.数组所有元素的值
D.数组第一个元素的值
PS:一般还要把数组元素个数传传进去


24.有了malloc/free为什么还要new/delete ?
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可以孕育申请动态内存和释放内存。对于非内部数据类型的对象而言,光用malloc./free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前 要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于Malloc/free.。因此C++语言需要一个能动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。z注意new/delete不是库函数。


25请讲一讲析构函数和虚函数的用法和作用?
析构函数是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类对象的生命周期结束的时候,由系统自动调用。有释放内存空间的作用。虚函数是C++多台的一种表现,使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。


26.如果ClassA中定义并实现虚函数 int fun(void),ClassB中也实现了该函数,那么上述变量a->func()将调用哪个类里面的函数?如果int func(void )不是虚函数,情况又如何?为什么?
第一问调用的是B的。第二问调用A的。虚函数只能借助于指针或者引用来达到多态的效果。


27.引用和指针有什么区别?

  1. 引用必须被初始化,指针不必。
  2. 引用初始化以后不能被改变,指针可以改变所指对象。
  3. 不存在指向空值的引用,但是存在指向空值的指针。

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

  1. 程序的可读性变差。程序员会忘记那些数字或者字符串是什么意思,用户则更加不知道它们从何处来、表示什么。
  2. 在程序的很多地方输入同样的数字或者字符串,难保不发生书写错误。
  3. 如果要修改数字或字符串,则会在很多地方改动,既麻烦又容易出错。

29.在C++中有没有纯虚构造函数?
构造函数不能是虚的。只能有虚的析构函数。


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

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

31.重载(overload)、重写(override)、重定义(redefinition)的区别?

名称 名字空间 区别
重载 同一名字空间 是指允许存在多个同名函数,而这些函数的参数表不同。
重定义/隐藏 不同名字空间 用于继承,派生类与基类的函数同名,屏蔽基类的函数
重写/覆盖 不同名字空间 用于继承,子类重新定义父类虚函数的方法

32.C++是不是类型安全的?
不是,类型的指针可以进行强制的类型转换。


33.C++是不是所有的动作都是main()引起的?如果不是,请举例。
不是,比如全局变量的初始化,就不是由main函数引起的。
举例:

class A{
     };
A a;//a的构造函数先执行
int main(){
     }

35.C++中virtual与inline的含义分别是什么?
在基类成员函数的声明之前加上virtual关键字,意味着将该成员函数声明为虚函数 inline与函数的定义体放在一起,使得该函数称为内联。inline是一种用于实现的关键字,而不是用于声明的关键字。
虚函数的特点:如果希望派生类能够重新定义基类的方法,则在基类中将该方法定义为虚方法,这样可以启动动态联编。
内联函数的特点:使用内联函数的目的是为了提高函数的运行效率。内联函数体的代码不能过长,因为内联函数省去调用函数的时间是以代码膨胀为代价的。内联函数不能包含循环语句,因为执行循环语句要比调用函数的开销大。


36.const关键字,有哪些作用?

  1. 想要阻止一个变量被改变,可以使用const关键字。在定义该const变量时候,通常需要对他进行初始化,因为以后就没有机会在改变他了。
  2. 对指正来说,可以使用指针本身为const,也可以指定指针所指的数据为const,或二者同时为const;
  3. 在一个函数声明中,const可以修饰形参,表明其为const类型,表明它是一个输入参数,在函数内部不能改变其值;
  4. 对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
  5. 对于类的成员函数,有时候必须指定其返回值为const类型,使得其返回值不为“左值”。

你可能感兴趣的:(C++)