C、C++、VC概念总结

时间:2024.4.27

1. 结构化程序设计和面向对象程序设计?

结构化程序设计又称为面向过程的程序设计,问题被看作一系列需要完成的任务,函数(在此泛指例程、函数、过程)用于完成这些任务,解决问题的焦点集中于函数,它关注如何根据规定的条件完成指定的任务。面向对象:将现实中的事物抽象成对象。面向对象程序设计:把面向对象的思想应用于软件开发过程中,根据需求决定所需的类、类的操作以及类之间关联的过程。并且面向对象程序设计必须具有:封装,继承,多态。

2. 什么是深拷贝,什么是浅拷贝?

深拷贝:创建新对象时,不仅复制了对象,并对其资源(堆内存)也进行了复制。 浅拷贝:创建新对象时,只是复制了对象,并没有对其资源(堆内存)进行复制。

3. 什么是重载,覆盖和隐藏?

重载:在同一个类中,函数名相同,参数列表(参数类型,个数,顺序)不相同的函数。 1) 相同的范围(同一个类中);2) 函数名字相同;3) 参数不同;4) virtual关键字可有可无。 覆盖:在继承时,派生类重新定义了基类的虚函数(函数名、参数列表、返回值类型)必须同父类中的相对应的函数严格一致。1) 不同的范围(分别位于派生类与基类);2) 函数名字相同;3) 参数相同;4) 基类函数必须有virtual关键字。隐藏:派生类的函数屏蔽了与其同名的基类函数,规则如下:1) 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。2) 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

4.析构函数定义为虚函数?

如果一个类不用作基类或者不需具有多态性,便不应该为它声明虚的。

在用基类的指针指向派生类的时候,才会出现这种情况。因为这个时候虚函数发挥了动态的作用。析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全,造成内存泄露。构造函数和析构函数都无返回值

5.什么是虚函数?什么是多态?

所谓虚函数就是在成员函数前加上virtual关键字。虚函数:在多态情况下只执行一个,在继承中,子类重写了基类的成员函数,当传递的是一个派生类的对象,基类的指针指向一个派生类的对象,调用成员函数时,运行这段代码无法在编译时被确定调用基类还是子类的成员函数,为了指明某个成员函数具有多太性,用关键字virtual标其为虚函数.

虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,虚函数表示函数是以间接的方式被调用,而不是由一个固定的函数入口地址来调用,一个函数调用可以对应不同的函数入口地址。虚函数除了不能作为内联函数外,它遵循普通成员函数的所有语法规则。函数声明语法:virtual return_type name( arguments );

在函数的定义部分和它的派生类的声明部分无需重复使用virtual关键字,它的所有派生类都保持virtual类型把函数转变为虚函数的作用是为了配合通过基类指针访问某一对象的操作。如果在派生类里没有对某一函数进行重载,也就不必把此函数声明成虚函数。在进行函数调用时,虚函数的表现要略逊于普通函数,而且它也比代码相同的实函数占据较多的内存空间。 虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism)

c++支持两种多态性:静态多态和动态多态,静态多态是通过重载实现的,动态多态是通过虚函数实现的。多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。子类把基类的虚函数从新执行了一遍。一个接口,

多种实现。在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。

实现动态联编需要三个条件:1、 必须把动态联编的行为定义为类的虚函数。2、 类之间存在子类型关系,一般表现为一个类从另一个类公有派生而来。3、 必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。

多态的工作方式:编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。通过这些手段,编译器在看到一个虚函数调用的时候,就会将这个调用改写,成功调用了各自的成员函数。

抽象类:含有纯虚函数(被初始化为0的虚函数)的类, 不能被实例化,抽象类中不适合定义变量,因为他的构造函数一般不会被调用。

6.Static变量?

静态数据成员在类声明外分配空间和初始化。静态成员变量在一个类的所有数据间共享,不允许静态成员去存放某一个对象数据,想限制静态成员变量的访问,则必须把它声明为保护和私有的,但可以通过公有静态成员函数访问。静态成员变量不能在构造函数中初始化(每构造一个对象就初始化一次,失去了他的功效),他的初始化在.cpp中(数据类型 类名 ::变量 = 值)。静态成员函数属于类,不属于任何对象,可以通过(类名::函数名)或 者(对象名.函数名)来调用,他只能访问静态成员变量和全局变量.

Static的用途:(1)限制变量的作用域, 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

(2)设置变量的存储域,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 局部和静态对象,以声明的顺序构造,所有的变量和对象都在函数开始时,统一定义。静态对象只被构造一次,文件作用域的静态对象在主函数开始运行之前全部构造完毕。所有全局对象,变量在主函数开始运行之前全部构造。全局对象构造时无特殊顺序。

7.static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?

全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。 static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件

static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他

文件单元中被引用; static局部变量和普通局部变量区别:static局部变量只被初始化一次,下一次依据上一次结果值;static函数与普通函数区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

8. 普通函数直接访问保护或私有数据成员引进了友员。友元函数和普通函数只有在声明部分有区别,其余部分一样,友元函数要访问成员变量必须通过对象的引用或指针作为参数来实现;友元函数可以访问类的全部成员。友元类的每个成员函数都可以访问另一个类中的保护或私有的数据成员

使用宏,const,枚举变量声明常量。内联函数不能为虚函数。

常量必须在构造函数的初始化列表里初始化或将其置为static。析构函数可以是内联函数,

9.如何引用一个已经定义过的全局变量?

答:extern ,可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错

10.全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?

答:可以,在不同的C文件中以static形式来声明同名全局变量。

可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错

11. C++中struct和class除了,class默认成员是private,struct默认是public类型,其余的均是一样的c++中的类允许有成员函数,而c中的struct不允许这样做。c++中的类有重载、继承、封装特性,而c中的struct却没有。

12. 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状 态,等待服务器确认;第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1), 此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

13. 进程和线程的差别

进程:程序的一次执行

线程:进程内的最小执行单元,也是进程内的可调度实体.

与进程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.

(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

14. 网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别?

1,进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。 2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其它 线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。 两者都可以提高程序的并发 度,提高程序运行效率和响应时间。 线程和进程在使用上各有优缺点:线程执行开销小

资源利用率好,但不利于资源管理和保护;线程产生的速度快,线程间通信快,切换快,线

程使用公共变量和内存时需要使用同步机制,因为他们在同一地址空间内;而进程正相反,

同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

15.const用途?

(1)定义常量。(2)修饰函数的参数,返回值。

被Const修饰的受强制保护,预防意外变动。

与宏的区别:Const有数据类型。有些集成的调试工具能对const进行调试。

内联函数与普通函数相比,可加快程序运行速度,不需要中断调用,编译时直接嵌到目标代

码中,宏,简单替换。内联函数需要做参数类型检查,无需跳转,带来效率提升,安全可靠,

但增加了空间消耗。Inline一般用于:一个函数不断被重复调用,函数只要简单几行,不

含for,while,switch.

16.文件的操作?

1.基于c的文件操作。一、流式文件操作,FILE *fopen(const char *filename,const char

*mode),"r" 以只读方式打开文件 "w" 以只写方式打开文件 "a" 以追加方式打开文件

"r+" 以读/写方式打开文件,如无文件出错 "w+" 以读/写方式打开文件,如无文件生成新

文件,"rb"表示以二进制模式打开只读文件,"w+t"或"wt+"表示以文本模式打开读/写文件。

fclose()的功能就是关闭用fopen()打开的文件,其原型是:int fclose(FILE *fp);如果成功,返

回0,失败返回EOF。fputc()向流写一个字符,原型是int fputc(int c, FILE *stream); 成功返回

这个字符,失败返回EOF。fgetc()从流中读一个字符,原型是int fputc(FILE *stream); 成功返

回这个字符,失败返回EOF。fseek()此函数一般用于二进制模式打开的文件中,功能是定位

到流中指定的位置,原型是int fseek(FILE *stream, long offset, int whence);如果成功返回0,

参数offset是移动的字符数,whence是移动的基准,0 文件开头1当前读写的位置2文件

尾部,fseek(fp,0L,2);把读写位置移动到文件尾fputs()写一个字符串到流中,fputs("I Love

You",fp),fgets()从流中读一行或指定个字符,fgets(str1,4,fp), 按格式输入到流 fprintf(fp,"%2d%s",4,"Hahaha")从流中按格式读fscanf(fp,"%d%d" ,&x,&y); 二、直接I/O文件

操作,这是C提供的另一种文件操作,它是通过直接存/取文件来完成对文件的处理,而上

篇所说流式文件操作是通过缓冲区来进行;流式文件操作是围绕一个FILE指针来进行,而

此类文件操作是围绕一个文件的“句柄”来进行。

2.基于c++的文件操作,加头文fstream.h,打开文件void open(const char* filename,int

mode,int access);参数:filename:要打开的文件名 mode:要打开文件的方式 access:

打开文件的属性ios::app:以追加的方式打开文件 ios::ate:文件打开后定位到文件尾,

ios:app就包含有此属性 ios::binary:以二进制方式打开文件,缺省的方式是文本方式。

两种方式的区别见前文件ios::in文件以输入方式打开 ios::out:文件以输出方式打开

ios::nocreate:不建立文件,所以文件不存在时打开失败ios::noreplace:不覆盖文件,

所以打开文件时如果文件存在失败 ios::trunc:如果文件存在,把文件长度设为0 可以用

“或”把以上属性连接起来,如ios::out|ios::binary打开文件的属性取值是:0:普通文

件,打开访问 1:只读文件2:隐含文件 4:系统文件 ifstream file2("c:\\pdos.def");//

以输入方式打开文件ofstream file3("c:\\x.123");//以输出方式打开文件,

file1.close();就把file1相连的文件关闭。file1.put(''c'');就是向流写一个字符''c''。

file2.get(str1,127,''A'');//从文件中读取字符到字符串str1,当遇到字符''A''或读取了127个字符

时终止。unsigned char str1[]="I Love You";int n[5];ifstream in("xxx.xxx");ofstream

out("yyy.yyy");out.write(str1,strlen(str1));//把字符串str1全部写到yyy.yyy中in.read((unsigned

char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换in.close();out.close();成员函

数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();

例:if(in.eof())ShowMessage("已经到达文件尾!");

17. 关键字volatile有什么含意 并给出三个不同的例子。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

1). 并行设备的硬件寄存器(如:状态寄存器)

2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)

3). 多线程应用中被几个任务共享的变量

回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。

1). 一个参数既可以是const还可以是volatile吗?解释为什么。

2). 一个指针可以是volatile 吗?解释为什么。

3). 下面的函数有什么错误:

int square(volatile int *ptr) {

return *ptr * *ptr; }

下面是答案:

1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr) {

int a,b;

a = *ptr;

b = *ptr;

return a * b; }

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr) {

int a;

a = *ptr;

return a * a; }

更多相关推荐:
C总结

金屯镇中心小学开展校园环境卫生整治活动总结为进一步加强学校环境综合治理工作,推动创建文明校园活动的深入开展,维护学校及周边环境秩序,根据上级创建卫生城的要求,我校切实落实校园及周边卫生环境专项整治的各项工作,现…

C总结

这一周的C语言实训就要结束了,这一周我们实训的课题是蛇行数组,就是使一个n*n的二维数组按按蛇行走的样子一样从左上角排列到右下角,这次的题目很难。不仅用到了数组语句,还用到了控制语句;如for语句。C语言中的f…

c++总结

C++课程设计实训总结姓名:班级:学号:指导教师:一实训选题人事考勤系统二实训设计作品内容这次的课程设计,我们需要做一个人事考勤系统的登录界面及主界面和三个子界面。完成各个界面之间的跳转。三设计中遇到的问题及解…

C#总结

常见异常:1、数据不在数据词典中的异常:产生原因:由于在创建实体类型时,没有将用到的实体序列化,导致在Config文件中找不到所要的字段;解决办法:在相应的实体类中开头添加[Serializable],并且在相…

深层探索C和C++总结

一、调用函数以及压栈:(1)、每个int占4个字节。(2)、通常栈是王内存低地址方向增长的,也就是说,先压栈的内容存放在高地址区域,后压的存放在低地址区域。(3)、一般调用函数时,汇编中call(通常调用函数都…

大学物理C-总结

大学物理C复习总结第一章流体力学1.表面张力系数的两种定义;2.弯曲液面的附加压强公式、拉普拉斯公式3.接触角的概念4.毛细现象,朱伦公式及物理含义第二章气体分子动理论1.理想气体的概念;2.理想气体的压强公式…

C总结_5(字节序)

C总结_5(字节序)-------------------------测试字节序程序(编译环境VC++6.0)#includestdio.hintmain(){}输出结果128结论:Window平台上使用小字写…

Objective-C语法总结

一XCodeObjectiveCCocoa说的是几样东西答案三样东西XCode你可以把它看成是一个开发环境就好像VisualStudio或者Netbeans或者SharpDevelop一样的玩意你可以将Inte...

c语言总结

备考建议大家可以看出指针数组字符串无论在笔试还是上机都是重中之重既是重点又是难点C语言程序初步顺序结构选择结构循环结构函数是基础编译预处理作用域与存储类位运算文件等是难点但不是重点每年都会考到但题量都不大结构体...

NOIP算法分类总结(C语言)

模块目录一排序1选择排序2插入排序3冒泡排序4快速排序5堆排序6归并排序7线性时间排序二高精度1高精度比较2高精度加法3高精度减法4单精度乘法5高精度乘法6单精度除法7高精度除法8进制转换三数论1欧几里德算法2...

study WW C总结

指针数组类型的识别参数可变的函数一指针它的本质是地址的类型在许多语言中根本就没有这个概念但是它却正是C灵活高效在面向过程的时代所向披靡的原因所在因为C的内存模型基本上对应了现在vonNeumann冯诺伊曼计算机...

c语言总结

总体上必须清楚的1程序结构是三种三个循环结构if和switch2读程序都要从main入口然后从最上面顺序往下读碰到循环做循环碰到选择做选择3计算机的数据在电脑中保存是以二进制的形式数据存放的位置就是他的地址4b...

c++总结(54篇)