}
9.对象都具有的二方面特征是什么?
分别是什么含义?
答:
对象都具有的特征是:
静态特征和动态特征。
静态特征是指能描述对象的一些属性,动态特征是指对象表现出来的行为
10、函数重载是什么意思?
它与虚函数的概念有什么区别?
函数重载是一个同名函数完成不同的功能,编译系统在编译阶段通过函数参数个数、参数类型不同,函数的返回值来区分该调用哪一个函数,即实现的是静态的多态性。
但是记住:
不能仅仅通过函数返回值不同来实现函数重载。
而虚函数实现的是在基类中通过使用关键字virtual来申明一个函数为虚函数,含义就是该函数的功能可能在将来的派生类中定义或者在基类的基础之上进行扩展,系统只能在运行阶段才能动态决定该调用哪一个函数,所以实现的是动态的多态性。
它体现的是一个纵向的概念,也即在基类和派生类间实现。
虚拟函数与普通成员函数的区别?
内联函数和构造函数能否为虚拟函数?
答案:
区别:
虚拟函数有virtual关键字,有虚拟指针和虚函数表,虚拟指针就是虚拟函数的接口,而普通成员函数没有。
内联函数和构造函数不能为虚拟函数。
什么时候需要用虚析构函数?
当基类指针指向用new运算符生成的派生类对象时,delete基类指针时,派生类部分没有释放掉而造成释放不彻底现象,需要虚析构函数。
11、什么是多态:
面向对象的多态:
虚函数和运算符的重载;
类的多态:
父类指针指向子类成员函数已实现不同功能
1.一个基类的指针或引用指向一个派生类对象,
2.虚函数
主要是两个:
1.隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
2.接口重用:
为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用
12、解释堆和栈的区别。
栈区(stack)—由编译器自动分配释放,
存放函数的参数值,局部变量的值等。
存放局部变量,函数调用参数,函数返回值,函数返回地址。
由系统管理
堆:
一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
程序运行时动态申请,new和malloc申请的内存就在堆上
描述内存分配方式以及它们的区别?
1)从静态存储区域分配。
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。
例如全局变量,static变量。
2)在栈上创建。
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。
栈内存分配运算内置于处理器的指令集。
3)从堆上分配,亦称动态内存分配。
程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。
动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
14、struct(结构)和union(联合)的区别?
1.结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了一个被选中的成员(所有成员共用一块地址空间),而结构的所有成员都存在(不同成员的存放地址不同)。
struct和class的区别
答案:
struct的成员默认是公有的,而类的成员默认是私有的。
struct和class在其他方面是功能相当的。
从感情上讲,大多数的开发者感到类和结构有很大的差别。
感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。
既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!
)时,你也许应该使用struct关键字,否则,你应该使用class关键字。
2.对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结构的不同成员赋值是互不影响的。
15、windows消息系统由哪几部分构成?
由一下3部分组成:
1.消息队列:
操作系统负责为进程维护一个消息队列,程序运行时不断从该消息队列中获取消息、处理消息;
2.消息循环:
应用程序通过消息循环不断获取消息、处理消息。
3.消息处理:
消息循环负责将消息派发到相关的窗口上使用关联的窗口过程函数进行处理。
16、什么是消息映射?
消息映射就是让程序员指定MFC类(有消息处理能力的类)处理某个消息。
然后由程序员完成对该处理函数的编写,以实现消息处理功能。
17、进程间主要的通讯方式?
信号量,管道,消息,共享内存
18、构成Win32API函数的三个动态链接库是什么?
答:
内核库,用户界面管理库,图形设备界面库。
动态链接库英文为DLL,是DynamicLinkLibrary的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
19、创建一个窗口的步骤是?
答:
定义一个窗口类结构->
注册这个窗口类->
然后再创建窗口->
显示窗口->
更新窗口。
20、模态对话框和非模态对话框有什么区别?
答:
1.调用规则不同:
前者是用DoModal()调用,后者通过属性和ShowWindow()来显示。
2.模态对话框在没有关闭前用户不能进行其他操作,而非模态对话框可以。
3.非模态对话框创建时必须编写自己的共有构造函数,还要调用Create()函数。
21、简单介绍GDI?
答;GDI是GraphicsDeviceInterface的缩写,译为:
图形设备接口;是一个在Windows应用程序中执行与设备无关的函数库,这些函数在不同的输出设备上产生图形以及文字输出。
23、已知strcpy函数的原型是:
char*strcpy(char*strDest,constchar*strSrc);不调用库函数,实现strcpy函数。
答案:
char*strcpy(char*strDest,constchar*strSrc)
{
if(strDest==NULL||strSrc==NULL)
returnNULL;//如果都为空就返回NULL;
if(strDest==strSrc)
returnstrDest;//如果复制字符串和目标字符串相等直接返回目标字符串
char*tempptr=strDest;
while((*strDest++=*strSrc++)!
=);//一个字节一个字节地复制直到赋值到‘\\0’
returntempptr;
}
24、在类的内部定义成员函数的函数体,这种函数会具备那种属性?
答:
这种函数会自动为内联函数,这种函数在函数调用的地方在编译阶段都会进行代码替换。
26、delete与delete[]区别:
delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数。
Newdelete与mallocfree的联系与区别?
答案:
都是在堆(heap)上进行动态的内存操作。
用malloc函数需要指定内存分配的字节数并且不能初始化对象,new会自动调用对象的构造函数。
delete会调用对象的destructor,而free不会调用对象的destructor.
29、用什么函数开启新进程、线程。
答案:
线程:
CreateThread/AfxBeginThread等
进程:
CreateProcess等
30、SendMessage和PostMessage有什么区别
答案:
SendMessage是阻塞的,等消息被处理后,代码才能走到SendMessage的下一行。
PostMessage是非阻塞的,不管消息是否已被处理,代码马上走到PostMessage的下一行。
31、CMemoryState主要功能是什么
答案:
查看内存使用情况,解决内存泄露问题。
32、总结const的应用和作用?
(1)欲阻止一个变量被改变,可以使用const关键字。
在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
33、什么是指针?
谈谈你对指针的理解?
指针是一个变量,该变量专门存放内存地址;
指针变量的类型取决于其指向的数据类型,在所指数据类型前加*
指针变量的特点是它可以访问所指向的内存。
智能指针:
当一个类中,存在一个指向另一个类对象的指针时,对指针运算符进行重载,那么当前类对象可以通过指针像调用自身成员一样调用另一个类的成员。
“引用”与指针的区别是什么?
指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。
程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
此外,就是上面提到的对函数传ref和pointer的区别。
34、static函数与普通函数有什么区别?
——生命周期上
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
36、简述VisualC++、Win32API和MFC之间的关系?
(1)VisualC+是一个以C++程序设计语言为基础的、集成的、可视化的编程环境;
(2)Win32API是32位Windows操作系以C/C++形式提供的一组应用程序接口;
(3)MFC是对Win32API的封装,简化了开发过程。
22、memset、strcpy()和memcpy()的区别?
strcpy()和memcpy()都可以用来拷贝字符串,strcpy()拷贝以’\0’结束,但memcpy()必须指定拷贝的长度。
memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为'\0'。
41、类成员函数的重载、覆盖和隐藏区别
答案:
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)基类函数virtual关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual关键字。
“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。
此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。
此时,基类的函数被隐藏(注意别与覆盖混淆)
42、.符串A和B,输出A和B中的最大公共子串。
比如A="aocdfe"B="pmcdfa"则输出"cdf"
*/
//Author:
azhen
#include
#include
#include
char*commanstring(charshortstring[],charlongstring[])
{
inti,j;
char*substring=malloc(256);
if(strstr(longstring,shortstring)!
=NULL)//如果……,那么返回shortstring
returnshortstring;
for(i=strlen(shortstring)-1;i>0;i--)//否则,开始循环计算
{
for(j=0;j<=strlen(shortstring)-i;j++){
memcpy(substring,&shortstring[j],i);
substring[i]='\0';
if(strstr(longstring,substring)!
=NULL)
returnsubstring;
}
}
returnNULL;
}
main()
{
char*str1=malloc(256);
char*str2=malloc(256);
char*comman=NULL;
gets(str1);
gets(str2);
if(strlen(str1)>strlen(str2))//将短的字符串放前面
comman=commanstring(str2,str1);
else
comman=commanstring(str1,str2);
printf("thelongestcommanstringis:
%s\n",comman);
}
44、strcmpstrcat原型
编写strcat函数(6分)
已知strcat函数的原型是char*strcat(char*strDest,constchar*strSrc);
其中strDest是目的字符串,strSrc是源字符串。
(1)不调用C++/C的字符串库函数,请编写函数strcat
答:
VC源码:
char*__cdeclstrcat(char*dst,constchar*src)
{
char*cp=dst;
while(*cp)
cp++;/*findendofdst*/
while(*cp++=*src++);/*Copysrctoendofdst*/
return(dst);/*returndst*/
}
请用标准C语言实现下列标准库函数,设计中不得使用其他库函数。
char*strstr(char*str1,char*str2);
在字符串str1中,寻找字串str2,若找到返回找到的位置,否则返回NULL。
答:
函数为
char*strstr(constchar*str1,constchar*str2)
{
char*cp=(char*)str1;
char*s1,*s2;
if(!
*str2)
return((char*)str1);
while(*cp)
{
s1=cp;
s2=(char*)str2;
while(*s1&&*s2&&!
(*s1-*s2))
s1++,s2++;
if(!
*s2)
return(cp);
cp++;
}
return(NULL);
47、函数模板与类模板有什么区别?
答:
函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。
48、
实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数;
答:
双向链表删除一个节点P
template
voidlist:
:
delnode(intp)
{
intk=1;
listnode*ptr,*t;
ptr=first;
while(ptr->next!
=NULL&&k!
=p)
{
ptr=ptr->next;
k++;
}
t=ptr->next;
cout<<"你已经将数据项"<data<<"删除"<ptr->next=ptr->next->next;
length--;
deletet;
}
在节点P后插入一个节点:
templateboollist:
:
insert(typet,intp)
{
listnode*ptr;
ptr=first;
intk=1;
while(ptr!
=NULL&&k
{
ptr=ptr->next;
k++;
}
if(ptr==NULL&&k!
=p)
returnfalse;
else
{
listnode*tp;
tp=newlistnode;
tp->data=t;
tp->next=ptr->next;
ptr->next=tp;
length++;
returntrue;
}
}
49、
完成下列程序
*
*.*.
*..*..*..
*...*...*...*...
*....*....*....*....*....
*.....*.....*.....*.....*.....*.....
*......*......*......*......*......*......*......
*.......*.......*.......*.......*.......*.......*.......*.......
#include
usingnamespacestd;
constintn=8;
main()
{
inti;
intj;
intk;
for(i=n;i>=1;i--)
{
for(j=0;j{
cout<<"*";
for(k=1;k{
cout<<".";
}
}
cout<}
system("pause");
}
50、
写一个函数,完成内存之间的拷贝。
[考虑问题是否全面]
答:
void*mymemcpy(void*dest,constvoid*src,size_tcount)
{
char*pdest=static_cast(dest);//强制类