📄 c-c++ 笔试、面试题目大汇总.htm
字号:
onmousewheel="return bbimg(this)" style="CURSOR: pointer"
onclick=javascript:window.open(this.src); alt=""
src="C-C++ 笔试、面试题目大汇总.files/070313232885151.gif"
onload="javascript:if(this.width>500){this.resized=true;this.style.width=500;}"
border=0></FONT></DIV>
<DIV><FONT size=2>从实现的角度讲,聚合可以表示为:</FONT></DIV>
<DIV><FONT size=2>class A {...} class B { A* a;
.....}</FONT></DIV>
<DIV><FONT
size=2>而<STRONG>组合</STRONG>表示contains-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系:</FONT></DIV>
<DIV><FONT
size=2>
<IMG onmousewheel="return bbimg(this)" style="CURSOR: pointer"
onclick=javascript:window.open(this.src); alt=""
src="C-C++ 笔试、面试题目大汇总.files/070313232885152.gif" width=229
onload="javascript:if(this.width>500){this.resized=true;this.style.width=500;}"
border=0></FONT></DIV>
<DIV><FONT size=2>实现的形式是:</FONT></DIV>
<DIV><FONT size=2>class A{...} class B{ A a; ...}</FONT></DIV>
<DIV><FONT size=2>参考文章:<A
href="http://blog.csdn.net/wfwd/archive/2006/05/30/763753.aspx">http://blog.csdn.net/wfwd/archive/2006/05/30/763753.aspx</A></FONT></DIV>
<DIV><FONT
size=2>
</FONT><A
href="http://blog.csdn.net/wfwd/archive/2006/05/30/763760.aspx">http://blog.csdn.net/wfwd/archive/2006/05/30/763760.aspx</A></DIV>
<DIV><FONT
size=2><STRONG>17.面向对象的三个基本特征,并简单叙述之?</STRONG></FONT></DIV>
<DIV><FONT size=2>1. 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,
protected,public)</FONT></DIV>
<DIV><FONT size=2>2.
继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。</FONT></DIV>
<DIV><FONT size=2>3.
多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:<STRONG>允许将子类类型的指针赋值给父类类型的指针。</STRONG></FONT></DIV>
<DIV><FONT size=2><STRONG>18.
重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?</STRONG></FONT></DIV>
<DIV><FONT size=2>常考的题目。从定义上来说:</FONT></DIV>
<DIV><FONT
size=2><STRONG>重载</STRONG>:是指允许存在多个<STRONG>同名函数</STRONG>,而这些函数的<STRONG>参数表不同</STRONG>(或许参数个数不同,或许参数类型不同,或许两者都不同)。</FONT></DIV>
<DIV><FONT size=2><STRONG>重写</STRONG>:是指子类重新定义复类虚函数的方法。</FONT></DIV>
<DIV><FONT size=2>从实现原理上来说:</FONT></DIV>
<DIV><FONT
size=2><STRONG>重载</STRONG>:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function
func(p:integer):integer;和function
func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是<STRONG>静态</STRONG>的。也就是说,<STRONG>它们的地址在编译期就绑定了(早绑定),</STRONG>因此,<STRONG>重载和多态无关</STRONG>!</FONT></DIV>
<DIV><FONT
size=2>重写:和多态真正相关<SPAN>。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,<STRONG>动态的调用</STRONG>属于子类的该函数,这样的函<STRONG>数调用在编译期间是无法确定的</STRONG>(调用的子类的虚函数的地址无法给出)。因此,<STRONG>这样的函数地址是在运行期绑定的(晚绑定)。</STRONG></SPAN></FONT></DIV>
<DIV><SPAN><FONT size=2><STRONG>19.
多态的作用?</STRONG></FONT></SPAN></DIV>
<DIV><SPAN><FONT size=2>主要是两个:1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;2.
接口重用:为了类在继承和派生的时候<STRONG>,保证使用家族中任一类的实例的某一属性时的正确调用</STRONG>。</FONT></SPAN></DIV>
<DIV><SPAN><SPAN><SPAN><FONT size=2><STRONG>20.
Ado与Ado.net的相同与不同?</STRONG></FONT></SPAN></SPAN></SPAN></DIV>
<DIV><SPAN><SPAN><SPAN><FONT size=2>除了“能够让应用程序处理存储于DBMS
中的数据“这一基本相似点外,两者没有太多共同之处。但是Ado使用OLE DB 接口并基于微软的COM 技术,而ADO.NET
拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM 体系,ADO.NET
接口也就完全不同于ADO和OLE DB 接口,这也就是说ADO.NET 和ADO是两种数据访问方式。ADO.net 提供对XML
的支持。</FONT></SPAN></SPAN></SPAN></DIV><SPAN><SPAN><SPAN><SPAN>
<DIV><FONT size=2><STRONG>21. New delete 与malloc free
的联系与区别?<BR></STRONG>答案:都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new
会自动调用对象的构造函数。delete 会调用对象的destructor,而free
不会调用对象的destructor.</FONT></DIV>
<DIV><FONT size=2><STRONG>22. #define DOUBLE(x) x+x
,</STRONG></FONT><FONT size=2><STRONG>i = 5*DOUBLE(5); i
是多少?<BR></STRONG>答案:i 为30。</FONT></DIV>
<DIV><FONT size=2><STRONG>23. 有哪几种情况只能用intialization list
而不能用assignment?</STRONG> </FONT></DIV>
<DIV><FONT size=2>答案:当类中含有const、reference
成员变量;基类的构造函数都需要初始化表。</FONT></DIV>
<DIV><FONT
size=2><STRONG>24. C++是不是类型安全的?</STRONG><BR>答案:不是。两个不同类型的指针之间可以强制转换(用reinterpret
cast)。C#是类型安全的。</FONT></DIV>
<DIV><FONT size=2><STRONG>25. main
函数执行以前,还会执行什么代码?<BR></STRONG>答案:全局对象的构造函数会在main 函数之前执行。</FONT></DIV>
<DIV><FONT
size=2><STRONG>26. 描述内存分配方式以及它们的区别?</STRONG><BR>1)<STRONG>
从静态存储区域分配</STRONG>。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如<STRONG>全局变量,static
变量</STRONG>。<BR>2)
<STRONG>在栈上创建</STRONG>。在执行函数时,<STRONG>函数内局部变量的存储单元都可以在栈上创建</STRONG>,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。<BR>3)
<STRONG>从堆上分配</STRONG>,<STRONG>亦称动态内存分配</STRONG>。程序在运行的时候用malloc
或new 申请任意多少的内存,程序员自己负责在何时用free 或delete
释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。</FONT></DIV>
<DIV><FONT size=2><STRONG>27.struct 和 class
的区别</STRONG></FONT></DIV>
<DIV><FONT size=2>答案:struct 的成员默认是公有的,而类的成员默认是私有的。struct 和 class
在其他方面是功能相当的。 </FONT></DIV>
<DIV><FONT
size=2>从感情上讲,大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!)时,你也许应该使用
struct 关键字,否则,你应该使用 class 关键字。 </FONT></DIV>
<DIV><FONT size=2><STRONG>28.当一个类A
中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。(Autodesk)<BR></STRONG>答案:肯定不是零。举个反例,如果是零的话,声明一个class
A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了。</FONT></DIV>
<DIV><FONT size=2><STRONG>29. 在8086
汇编下,逻辑地址和物理地址是怎样转换的?(Intel)</STRONG><BR>答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。</FONT></DIV>
<DIV><FONT size=2><STRONG>30. 比较C++中的4种类型转换方式?</STRONG>
</FONT></DIV>
<DIV><FONT size=2>请参考:<A
href="http://blog.csdn.net/wfwd/archive/2006/05/30/763785.aspx">http://blog.csdn.net/wfwd/archive/2006/05/30/763785.aspx</A></FONT><FONT
size=2>,重点是static_cast,
dynamic_cast和reinterpret_cast的区别和应用。</FONT></DIV>
<DIV><FONT size=2><STRONG>31.分别写出BOOL,int,float,指针类型的变量a
与“零”的比较语句。</STRONG><BR>答案:<BR>BOOL : if ( !a ) or
if(a)<BR>int : if ( a == 0)<BR>float
: const EXPRESSION EXP =
0.000001<BR>
if ( a < EXP && a >-EXP)<BR>pointer : if ( a != NULL)
or if(a == NULL) </FONT></DIV>
<DIV><FONT size=2></FONT> </DIV>
<DIV><FONT size=2><STRONG>32.请说出const与#define
相比,有何优点?<BR></STRONG>答案:</FONT><FONT size=2>1) <STRONG>const
常量有数据类型,而宏常量没有数据类型</STRONG>。编译器可以对前者进行类型<STRONG>安全检查</STRONG>。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。<BR>
2) <STRONG>有些集成化的调试工具可以对const
常量进行调试</STRONG>,但是不能对宏常量进行调试。</FONT></DIV>
<DIV><FONT
size=2><STRONG>33.简述数组与指针的区别?</STRONG><BR>数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。<BR>(1)修改内容上的差别<BR>char
a[] = “hello”;<BR>a[0] = ‘X’;<BR>char *p = “world”; // 注意p
指向常量字符串<BR>p[0] = ‘X’; // 编译器不能发现该错误,运行时错误<BR>(2) 用运算符sizeof
可以计算出数组的容量(字节数)。<STRONG>sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p
所指的内存容量</STRONG>。C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。</FONT><FONT
size=2><STRONG>注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。<BR></STRONG>char
a[] = "hello world";<BR>char *p = a;<BR>cout<< sizeof(a)
<< endl; // 12 字节<BR>cout<< sizeof(p) << endl; //
4 字节<BR>计算数组和指针的内存容量<BR>void Func(char a[100])<BR>{<BR>cout<<
sizeof(a) << endl; // 4 字节而不是100 字节<BR>}</FONT></DIV>
<DIV><FONT
size=2><STRONG>34.类成员函数的重载、覆盖和隐藏区别?<BR></STRONG>答案:<BR>a.成员函数被重载的特征:<BR>(1)相同的范围(在同一个类中);<BR>(2)函数名字相同;<BR>(3)参数不同;<BR>(4)virtual
关键字可有可无。<BR>b.覆盖是指派生类函数覆盖基类函数,特征是:<BR>(1)不同的范围(分别位于派生类与基类);<BR>(2)函数名字相同;<BR>(3)参数相同;<BR>(4)基类函数必须有virtual
关键字。<BR>c.“<STRONG>隐藏</STRONG>”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:<BR>(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。<BR>(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual
关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)</FONT></DIV>
<DIV><FONT size=2><STRONG>35. There are two int variables: a and b,
don’t use “if”, “? :”, “switch”or other judgement statements, find
out the biggest one of the two numbers.</STRONG><BR>答案:( ( a + b ) +
abs( a - b ) ) / 2</FONT></DIV>
<DIV><FONT size=2><STRONG>36.
如何打印出当前源文件的文件名以及源文件的当前行号?<BR></STRONG>答案:<BR>cout << __FILE__
;<BR>cout<<__LINE__
;<BR>__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。</FONT></DIV>
<DIV><FONT size=2><STRONG>37. main
主函数执行完毕后,是否可能会再执行一段代码,给出说明?<BR></STRONG>答案:可以,可以用_onexit
注册一个函数,它会在main 之后执行int fn1(void), fn2(void), fn3(void), fn4
(void);<BR>void main( void )<BR>{<BR>String
str("zhanglin");<BR>_onexit( fn1 );<BR>_onexit( fn2 );<BR>_onexit(
fn3 );<BR>_onexit( fn4 );<BR>printf( "This is executed first.\n"
);<BR>}<BR>int fn1()<BR>{<BR>printf( "next.\n" );<BR>return
0;<BR>}<BR>int fn2()<BR>{<BR>printf( "executed " );<BR>return
0;<BR>}<BR>int fn3()<BR>{<BR>printf( "is " );<BR>return
0;<BR>}<BR>int fn4()<BR>{<BR>printf( "This " );<BR>return
0;<BR>}<BR>The _onexit function is passed the address of a function
(func) to be called when the program terminates normally. Successive
calls to _onexit create a register of functions that are executed in
LIFO (last-in-first-out) order. The functions passed to _onexit
cannot take parameters.<BR></FONT></DIV>
<DIV><FONT size=2><STRONG>38. 如何判断一段程序是由C
编译程序还是由C++编译程序编译的?</STRONG><BR>答案:<BR>#ifdef
__cplusplus<BR>cout<<"c++";<BR>#else<BR>cout<<"c";<BR>#endif</FONT></DIV>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -