江苏计算机二级VC++复习

更新时间:2024-04-23 07:30:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

江苏省计算机二级C++考试备考提纲

第一章 Visual C++程序设计入门

1> 定义标识符规则:第一个字符只能是英文字母或下画线,后面可跟字母,数字,下画线;不能是

C++语言的关键字。

2> 键盘上除去3个字符:@,¥,其余的可显示字符在程序代码中均能使用。

3> 编写程序的注意事项:/*和*/为多行注释,//为单行注释,从标识起至本行结束:程序一般包含输

入输出编译预处理命令;C++的程序有且只有一个主函数main;对于C++编译器而言,一条语句可以写成若干行,一行内也可以写若干条语句,:而且它严格区分大小写字母。

4> 运算符;1.求模/余运算符%,要求操作数必须都是整形数,若不是整型数必须将操作数强制转化

成整型再进行求余运算,否则将出现编译错误,如(int)5.2%3=2; 2.若操作数中有负值,求余原则为:先取绝对值求余,余数取与被除数相同的符号,如-10%3=-1,10%-3=1. 3。而除法运算符/和*,若两个操作数都是整型,则结果也是整型,若有一个是实型,则结果是实型。4。注意,如a=4,b=3,c=2,求a>b>c的值,因为原式=(a>b)>c,a>b值为1,则原式相当于1>c,所以最终结果是0。 5。自增、减运算符的操作数不能是常量或表达式,如2++,(x+1)++都是不合法的,再如,2*a++等价于2*(a++). 6.条件运算符“?:”是C++中唯一的三目运算符,条件表达式的一般格式为:逻辑表达式1?表达式2:表达式3.,1为真执行2,为假执行3,注意:条件表达式的功能相当于条件语句,但一般不能取代if语句;表达式1,2,3类型可不同,此时条件表达式的值取较高的类型,如a>b?2:5.5,ab时,值为2.0,而不是2。注意:逗号运算符计算方法:按先后顺序依次计算各个表达式的值,最后一个表达式的值作为整个逗号表达式的值。逗号运算符在在所有运算符中优先级最低;除法与求模运算符的第二个操作数不能为零。 5> 注意:m+++n相当于m++ n,因为++运算符为2级,+为4级,所以++高于+。

6> 变量:要先定义后使用;从键盘输入时,多个数据之间用分隔符(空格,制表符,换行符)分隔;

输出时,字符串照原样输出,变量输出其值;可用语句cout.setf(ios::fixed);设置小数位输出格式。 7> 常量:用指数法表示的数,在E或e的面前必须有数字且后面必须是整数;字符型常量是用单引

号引起来的单个字符,在计算机内部是以它们的ASCII码表示的,如‘b’+2等价于98+2;字符

串常量是用双引号引起来的若干个字符,在内存中按顺序逐个存放字符的ASCII码值,并在最后自动存放一个转义字符‘\\0’·,所以,“a”比‘a的实际长度大一。实型(浮点型)常量只能用十进制表示,其有两种表示形式:小数,如2.414,还有指数,如5.48e-3. 整型常量的三种表示方式:A十进制整数,有正负之分,B八进制整数,以0开头,后面为0~7的数字,C十六进制整数,以0X或0x开头,后面是0~9的数字或A~F(a~f)的字母,如0XA,等于十进制数的10

8> 类型转换:1。隐式类型转换(自动进行):A算术转换~“小级别向大级别转换”,

char~short~int~float~long~double~long double. 如:int a=10;float b=10.2;a+b;值为20.2,不是20。 B赋值转换~”不管赋值运算符右边是什么类型,都要转换成左边的类型”,当右边范围较大时,左边赋值所得到的值将失去右边数据的精度,如:int a;float b=10.2;a=b;值为10,而不是10.2。 2。强制类型转换,形式:(类型)表达式或类型(表达式),注意:在进行类型转换时,操作数的值和类型并不发生改变,改变的只是表示式值的类型,如:float b=10.2;cout<<(int)b<<””<

9> 表达式:A赋值~;B逗号表达式:最后一个表达式的值作为整个表达式的值。C左值:指能出现

在赋值表达式左边的表达式。注意:左值表达式必须要具有存放数据的空间,允许数据存放,所以,常量,表达式都不是都不是左值,不能放在赋值后的左边,如:‘a’=97就是错误的,因为‘a’是字符型常量,常量值在定以后就不能被修改。D逻辑表达式的求值优化 第二章 简单输入输出

1> C++没有专门的输入输出语句,所有输入输出都是通过输入输出流实现的,输入输出流定义在头文件iostream.h中,所以在输入输出前必须在程序的开头增加一行#include

2< 输入操作通过输入流cin来实现,它可输入整数,实数,字符及字符串等基本数据类型,cin>>

变量1>>变量2>>……“>>“为提取运算符

3< 输入字符:A:cin<<变量1<<变量2<<。。。。,在这种输入格式下,cin不能将空格和回车符赋给变量。

B:cin.get(字符变量);get为cin中的一个函数,它的参数是字符型变量,这种格式下,字符无论是空格或是回车符都不会被忽略,将依次赋给变量。

4< 输入操作是通过输出流cout来实现的,它可对表达式进行输出,<<为插入运算符。

5< 当输入或输出八进制或十六进制整数时,必须在cin或out中说明相应的数制,格式为:十六进

制:cin>>hex>>变量1>>变量2>>。。。八进制,把hex改为oct就行了。注意,当指明使用某种某种数制后,将一直保持以这种数制进行输入输出,直到再次指明另一种数制输入输出为止。 第三章:C++的流程控制语句

1> 顺序结构:注意,空语句只有一个分号构成,它不产生任何操作。

2> 选择结构:1,条件语句是允许嵌套的,当嵌套数较多时,其配对原则是:每个else都与它前面

的且离它最近的未配对的if进行配对。 2,switch语句:A:switch后的表达式的值必须是或最终可以转化成整型,字符型或者枚举表达式;而case后的常量表达式的值也只能是整型或字符型,并且各case分支的常量表达式的值应各不相同。 B:该语句的执行过程:当表达式的值与某个case后的常量表达式的值相等时,执行其后的语句序列,如果语句序列后有break语句,则跳出switch结构;否则执行下一而case分支;若所有case后的常量表达式的值都不能与表达式的值匹配,则执行default分支中的语句。

3> 重复结构:1,for语句:一般格式:for(表达式1;2;3) 循环体。注意(1)表达式1是可以省略

的,但分号不能省,省略后应在for语句之前设置循环变量的初值。(2)表达式2也可以省略,但省略后循环体将无休止的进行下去,只有在循环体中加入break语句才能结束循环。(3)表达式3(修改循环条件)也可以省略,但程序应在循环体中对循环变量进行修改,以保证循环能正常结束。(4)当三者同时省略时,for( ; ; )是一种最简单的for循环语句,但同时它也是一个死循环。 2,while语句:注意,A:在循环条件不满足的情况下,循环体可能一次也不执行;B:当条件表达式不成立,即其值为0或循环体内遇到break,return等语句时,将退出循环。 3,do…..while语句:注意 A:在while语句的条件表达式后面不能加分号,而在do…while语句的条件表达式后面必须加分号。B:无论条件成立与否循环体都至少执行一次,要与while 语句区分开。 4,以上三种循环结构内都可以嵌套自己本身或其它的循环语句组成多重循环,但不能嵌套定义。

4> break和continue语句:1,break语句的用途,A:用在switch语句的每个分支后,用于执行完某

个分支后跳出switch语句。 B:用在重复结构的循环体中,用于跳出其所在层次的那个循环。 2,continue语句用途:用在循环体中,结束本次循环,跳回到循环控制表达式部分。 3,区别:前者语句将结束本层循环;后者语句只是结束了本次循环,本次循环中将不再执行其后的语句,但整个循环并没有因此而结束。 第四章 函数和编译预处理

1> 函数的定义和调用:1,main函数称为主函数,它是C++程序不可缺少的部分,每个程序都是从

主函数开始执行的,它是整个程序的唯一入口,其它函数可以是库函数(使用时应将说明此函数的头文件包含进程序中)或用户自定义函数(必须先定义后使用)。 2,函数的定义 A:无参函数定义:数据类型 函数名(void)。void可以省略,其中数据类型为函数返回值类型,如果函数不需要返回任何值,则需定义为void;如果省略返回类型,则默认返回类型为int. B:有参函数定义:数据类型 函数名(类型 变量名1,变量名2,·····),括号内的内容为函数的形式参数,之间用逗号隔开,它们构成了形参表。 3,函数的调用:格式:无参 函数名();有参 函数名(实参表)。注意:A:实参表中若实参个数多余一个,用逗号隔开,实参可以是表达式,变量,常量或者甚至可以是一个具有返回值的函数;函数调用时,实参个数和类型应尽量与形参相符,否则,则需要进行类型转换,当两种类型兼容时进行自动类型转换,否则要用户进行强制类型转换。B:函数调用应遵循先定义后使用的原则,若被调用函数的定义放在调用语句之后时,应在调用此函数之前增加函数的原型说明(一般格式:数据类型 函数名(参数表)),它的作用是向编译系统说明程序所要用到的函数的相关信息,函数原型的参数可以写成完整的参数表,即和后面函数定义中的完全相同,也可以只写出参数的类型,而不写参数的变量名。

2> return语句和函数返回值:1.,return语句一般形式:return(表达式);或return 表达式; 作

用:用于返回函数的返回值;用于中断函数的运行。若函数没有返回值,则return语句后面不加表达式,此时return语句将终止函数的运行,程序返回到主调函数。 注意:A:函数类型与return语句中表达式值的类型应尽量保持一致,若不一致,以函数类型为准自动进行类型转换;B:当被调函数没有返回值时,函数体中不需要使用return语句,此时函数返回值类型应说明为void型,避免调用时错误。

3> 参数的三种传递方式:1,值传递:A;在值传递过程中,是将每个实参的值传递给相应的形参,

但函数处理后的结果并不能通过实参带回给调用者,所以形参在函数内的变化并不能改变函数之外实参的值,因此函数只能通过return语句返回一个值,值传递好处在于函数具有相对独立性,函数的执行对函数之外的变量没有影响。帮助理解:值传递时,实参传递给形参的并不是它本身,而是一个复本,所以函数体内所有对函数的操作,只不过是对实参复本的操作,并不会改变实参本身。 B:实参对形参的数据传送是单向的,实参和形参占用不同的内存单元,所以二者同名也不会相互影响。

4> 递归函数的定义和调用:A 定义:函数的递归调用是函数嵌套的一种特殊情况,分两种情况,一

是在函数调用时,函数可以相互调用,形成循环;二是函数调用自身,这种函数成为直接递归函数。 B是用递归的条件,略 。C递归的执行过程,略。

5> 作用域:指程序中定义的标识符的作用范围。(1)块作用域:用花括号{}括起来的程序称为一个

块,在一个块中说明的标识符的作用域为块作用域,此作用域开始于声明点,结束于块结束处,具有块作用域的变量称为局部变量。 (2)文件作用域:函数定义之外声明的标识符或用extern说明的标识符称为全局标识符,其作用域为文件作用域,它开始于声明点,结束于源文件结束。注意:当全局标识符与块中标识符同名时,全局标识符将被屏蔽,块中标识符将作为变量使用,若要在块中引用全局标识符,则需使用作用域运算符“::”。 (3)函数原型作用域:在函数原型参数表中声明的参数的作用域。它从说明处开始,到函数原型说明结束处结束。由此可见,函数原型中所说明的参数对函数定义中的变量无关,所以在函数原型参数表中的标识符可以与函数定义参数表中的标识符不同,甚至可以省略。 (4)函数作用域:在函数内定义的标识符,在函数中处处有效,C++中只有标号具有函数作用域。 (5)类的作用域: 6> 存储类: 存储类型 关键字 存储方式 作用 补充

自动类型变量 auto 动态(局部) 是使用最广泛的一函数内凡省略说明的变量种类型;不赋初值,均作为自动变量 其初值为不确定值 静态类型变量 static 静态(全局或局具有记忆功能,将上变量仅限于本源程序文件部) 次对该变量的调用内使用 结果进行保留 寄存器类型变量 register 动态(局部) 用于使用频率最高其变量的值存放在CPU的变量 的寄存器中,而不是存储器中,以提高效率 外部类型变量 extern 静态(全局) 用于多个文件组成全局变量的使用在定义之的程序中,指同一变前时应将它说明为外部变量 量 补充说明:1.变量分静态和动态两种,静态变量是程序开始执行时就分配存储空间,直到程序运行结束;动态变量是程序运行过程中用到时才分配内存空间,到其作用域之外时,收回其内存。 2外部类型变量一般用于多个文件组成的程序中,指同一变量,它只能在一个文件中的函数体外定义一次,且只能在一个文件中为其赋初值,但可以在多个文件中被说明并使用,是全局变量。 3,auto和register类型变量没有默认初始值,后两者有,整型为0,浮点型为0.0,字符型为空。 7> 函数的重载:指几个不同的函数共用一个相同的函数名。在调用重载函数时,编译器通过识别不

同的实参而调用不同的函数,对于同名函数,只有参数表不同(类型或个数不同)才可以实现重载,仅返回值不同不能实现重载。

8> 编译预处理:注意:若程序没有预处理命令,将直接进行编译;C++语言提供了多种预处理功能,

如宏定义,文件包含,条件编译等。它么均以#号开始,由于预处理不属于C++语句,故不以分号结束。

9> “宏”:1,不带参数的宏:一般格式:#define 宏名 字符串或字符; 2,带参数的宏:一般

格式:#define 宏名(参数表) 字符或字符串,注意:其中宏名与参数表间不能有空格;参数

表中若参数多于一个,参数之间用逗号分隔;参数只作标识符使用,不能指定参数类型。 3,使用宏定义应注意:A:宏展开时,只作简单替换,不作任何运算和语法检查。 B:若宏定义多于一行,必须使用“、”进行换行。C:宏定义中可以引用已定义过的宏名。 D:带参的宏定义与函数在定义和使用的形式都有一些相似之处,但还是有本质区别的,区别如下:(1)函数调用时须将实参表达式的值先求出再赋予形参而宏展开则对实参表达式不作任何计算直接代换形参;(2)函数是在程序运行时被调用的,而宏展开则是在编译前进行的;(3)函数的形参和实参都是有类型的,而且二者的类型应一致,否则须进行类型转换。而宏的形参是没有类型的,它只是一个符号,展开时代入指定的字符即可而不必进行类型检查。

10> 文件包含:1定义:指在一个源程序文件中将另一个源程序文件的全部内容包含进来,它可以用

来把多个源程序文件连成一个源程序文件进行编译,结果将生成一个目标文件。2,语法格式:#include <被包含文件名>或#include “被包含文件名” 。第一种格式用于包含c++库文件,编译器从制定的库文件(即从约定的目录include开始查找)目录查找;而后者用于包含用户文件,编译器先从当前目录开始查找,再从约定的目录include开始查找。 3,注意点:A:从理论上说,#include命令可以包含任何类型的文件,只要符合C++语法(如.cpp文件),但一般用于包含扩展名为 .h的头文件; B:#include可以放在程序的任何位置,一般在开头,其定义可以嵌套; C:一个include命令只能指定一个被包含文件。 第五章 数组

1> 一维数组:(1)定义方式:数据类型 数组[常量表达式]。注意点:A:数组元素下标的下界为0;

B:定义数组的表达式只能是常量表达式(一个最终可以转换成正整数值的相关表达式),不能包含变量;C:数组名代表整个数组的首地址,它是一个常量,其值不能改变,所以不能进行自增自减运算或被赋予它值。 (2)初始化:A:只给部分元素赋初值,其余未赋值元素初值为0; B:给全部元素赋初值;C:编译系统根据初值个数确定数组大小; D:若不对static数组元素赋初值,则系统会自动为全部元素赋以0值。(3)使用情况:A:表示形式:数组名[下标表达式],其中下标为正整型常量或值为正整型的表达式。注意点:数组必须先定义后使用; 引用数组元素时,只能逐个元素地引用,不能一次引用整个数组; 数组元素下标从0开始,数组的最后一个元素地

下标是数组的长度大小减1; C++语言程序设计自由度大,对数组下标越界不作检查,因此需要由程序员自己保证数组访问的正确性。

2> 二维数组:(1)定义方式:数据类型 数组名[常量表达式1][常量表达式2] 1表行,2表列。 注

意点:行和列的下标都从0开始;数组在内存中存放时按行序优先原则(即先顺序存放本行各元素,再存放次行元素); 在C++中,二维数组可以看作是对一维数组的直接扩展,即把二维数组看作一种特殊的一维数组来定义,它的每一个元素又是一个一维数组。 (2)初始化:A:对数组的全部元素赋初值。可以按行赋,每行元素用花括号括起来,也可以按元素排列顺序赋,注意:第一维的长度可以不指定,但第二维长度必须指定。 B:对数组的部分元素赋初值。格式类型同上,未赋值元素初值为0。(3)使用情况:类比一维数组。

3> 数组与函数:1,由于数组结构上的特殊性,数组作为函数的参数时存在两种形式:A:单个数组

元素作为函数的参数——值传递,如:void fun(int x){x=200}。由于数组的每个元素都是一个具有相同数据类型的变量,所以,从函数的角度来看,单个数组元素作为函数的参数与普通变量作为函数的参数是没有区别的,都属于值传递,所以函数体对形参的修改并不改变实参的值。 B:数组名作为函数的参数——地址传递。传递给形参的是数组的地址。由于形参和实参表示的是内存中的同一地址,函数中对形参的一切操作实际是对它所对应的内存地址中的值进行的,因而可能改变实参的值。 此时我们往往将数组名作为第一个参数,数组大小作为第二个参数,如:void fun(inta[],int n){a[0]=200}.

4> 字符数组:1,定义:char 数组名 [常量表达式] 注意点:1,字符数组是一种特殊的一维数组,

一维数组所有的使用方法同样适用于字符数组,此外字符数组还有自己特殊的操作方法;2,字符数组与整形数组之间有着密切的关系,但含义不同,字符数组中的每个元素都是一个字符,如:char s1[5]={1,2,0}, s2[5]={?1?,?2?,?0?}; int a[5]={1,2,0};则s1和a中存放的内容相同,但与s2不同,s2相当于整形数组{49,50,48,0,0}; 3,字符数组与字符串非常接近,但字符串一定有结束标识,而字符数组不一定有。 2,初始化:(1)将字符逐个依次赋给数组(即给部分或全部元素赋值,未赋值元素初值为0),如:char s1[]={?a?,?b?,?c?,?d?,?e?}; (2)将整个字符串赋给数组:如:char s3[]={“abcde”}; char s4[10]=”abcde”; 注意:1以上数组,s1有五个元素,不含结束标志;s3

有6个元素,最后一个元素为系统自动添加的结束标志(‘、0’);s4有十个元素,后5个元素都是结束标志。2,用字符串给字符数组初始化,最后总隐含一个结束标志,所以用来初始化的字符串的可见字符个数要小于字符数。3,一个字符串是否结束,判断的唯一标志是结束标志‘、0’。 5> 字符串处理函数:1,字符串拷贝(复制)函数strcpy:格式:strcpy(字符数组1,字符串2)注意:

A,作用是将2中第一个结束标志前的内容(包括第一个结束标志)复制到1中;B: 1必须定义的足够大,以便容纳被拷贝的字符串; C:字符数组1必须写成数组名形式,而字符串2可以是字符数组名,也可以是一个字符串常量; D:字符串整体赋值时只能用strcpy函数,不能用赋值运算符=,它只能对一个字符进行赋值。 2,求字符串长度函数:格式:strlen(字符串),注意点:A;该函数返回的是字符串的长度,不包括结束符,即第一个结束标志前的字符个数; B:sizeof()所求的是数据或类型(常量,变量,类型,数组等)在内存中所占用的字节数。 3,字符串比较函数:格式:strcmp(字符数组1,字符数组2)。A作用:用于比较两个字符数组或字符串的大小,若相等返回0,前者大返回1,后者大返回-1;B:比较规则:从两个字符数组或字符串的首字符开始,从左到右依次比较字符的ASCII码值,直到出现两个字符不同或遇到结束符为止。注意:结束标志的值小于空格字符的值。 4,字符串拼接函数:格式:strcat(字符数组1,字符数组2),作用:将2中第一个结束标志前的内容(包括第一个结束标志)拼接到1中第一个结束标志的后面,从1的结束标志处开始拼接,该结束标志被删除,字符数组2同样可以是一个字符串常量,操作结果放在字符数组1中,函数返回的是字符数组1的地址。注意:字符数组1必须足够大以便容纳连接后的新字符串。 第六章 结构体·共同体和枚举类型

1> 结构体:(1)定义:A:要定义结构体变量必须先定义结构体类型,定义格式:struct 结构体类型

名{类型名 成员1; 类型名 成员2;····}; 注意点:花括号后面的分号不能忘记;结构体是一种数据类型,定义结构体时系统并不会给成员分配内存;其定义是可以嵌套的。 B:结构体变量定义格式:struct 结构体类型 变量名;或 struct{···}变量;其中第一种格式关键字可省,但前提是结构体类型已经定义了;第二种格式则是在定义结构体类型的同时定义了变量。 注意点:A系统不为结构体类型分配内存,不能对其进行赋值等运算;但结构体变量是占用系统内

存的,故可对其进行赋值等运算。B结构体类型变量的作用域与一般变量的作用域相同。 (2)初始化:对结构体变量初始化的方法是使用花括号将每个成员的值括起来进行赋值。 (3)结构体变量的引用:不能整体引用,只能引用变量成员,引用方式:结构体变量名·成员名 ,其中·为成员运算符,结合性从左到右。注意:只有同类型的结构体变量才可以相互赋值;若结构体类型存在嵌套时,对变量的成员需逐级(由外到内)进行依次引用;结构体变量可以作为函数的参数,函数也可以返回结构体的值。 (4)结构体数组:定义以及初始化与结构体变量类似,注意以下几点即可:A:由于结构体数组的每个元素都是结构体(相当于一个结构体变量),故要将一个元素的所有成员值放在一个花括号中,以便区分每个元素; B:数组元素的引用方式:结构体数组名[下标]·成员名。

2> 共同体(联合体union):是C++的一种构造数据类型,也是一种由用户自己定义的数据类型。 与

结构体相似处:由若干数据类型组合而成,组成共用型数据的若干个数据也成为成员; 不同处:共同体的共用型数据中所有成员占用相同的内存单元,因此变量中的所有成员的首地址相同,变量的地址就是该变量成员的地址;共同体变量中的所有成员共享一段公共存储区,故共同体变量所占内存字节数等于最长成员所占字节数,而结构体变量中的每个成员分别占有独立的存储空间,所以其所占字节数是成员所占字节数的总和。

3> 枚举类型:(1)定义方法:enum 枚举类型名{枚举常量1,2,3····,n};其中每个枚举常量对应一

个整数值作为序号,依次是0,1,2····n-1;用户也可以自己为枚举常量确定对应的序号,在枚举类型执行期间,每一个枚举类型的元素用一个整数来表示,若没有规定元素所取的整数值时(若其前一个元素有规定,则根据前一个元素的整数值加1),把枚举元素的序号从0开始作为对应元素的值,其后元素在前一个元素的基础上加1即可(2)枚举类型变量的定义与结构体变量定义方法类同(3)赋值运算:A:同类型变量间可以相互赋值;B:可将枚举常量表中的某一常量赋给枚举变量;C:1,一个整数不能赋给一个枚举常量,它们属于不同类型,应先进行强制类型转换才能赋值,如:day2=2是不对的,而day2=(enum week)2 就是正确的,它相当于将顺序号为2的枚举元素赋值给week,甚至可以是表达式,如:day2=(enum week)”(5-3); 2,关系运算是在同类型变量间进行的,比较的是变量所取的枚举常量的序号; 3,枚举类型变量不能直接从键盘输

入的,但可直接输出,输出值为变量所取的枚举常量的序号。 第七章 指针与引用

1> 指针变量:用于存放内存单元地址的变量。A:定义格式:类型 * 指针变量名 。注意:(1)要

定义多个相同类型的指针时,每个变量之前都必须有*;(2)*仅仅表示该变量为指针变量,指针变量名不包含*;(3)指针变量应先赋值后引用,定义指针变量时若没对其进行初始化,那么它所存放的值(地址)通常是不确定的随机值,可能导致程序不能运行,严重时甚至导致系统崩溃;(4)不同类型的指针变量所分配的内存单元都是4个字节,原因是指针变量的值是一个地址,而地址通常用4个字节表示。 B:取地址运算符&:用来获取某一变量的地址,它是一目运算符,它的操作数只能是变量或对象,不允许是常量或表达式。 C:初始化:(1)使用&,把变量地址赋给指针变量:int i ,p=&i;(2)将一个指针变量的值赋给另一个指针变量:int *p1=&I; int *p2=p1; 2> 指针的运算:(1)间址运算符* :为一目运算符,操作数必须为指针,运算结果为操作数所指向

的地址中所存放的数据值。(2)指针的赋值运算:对指针的初始化同样可对其赋值,但赋值时应注意:A;对于指针常量(用const或#define定义的量,如:char *const p=”hello”;),指针本身的值不能通过赋值来改变。B;对于指向常量的指针(如:const char * p=”hello”;),不能通过指针来改变所指对象的值(如:*p=”others”;是错误的),但指针本身是可以改变的,通过赋值可指向其它的对象(如:p=NULL;是正确的)。 (3)指针的算术运算:指针可以进行自加或自减运算并可进行加减运算。注意:对指针进行加减运算时,若加1或减1,其中的1实际代表的字节数是由所指向变量的类型决定的,在32位机中,整数是占4个字节,所以加1实际移动了4个字节。 (4)指针的比较运算:用于类型相同的指针变量或地址之间进行比较,两指针相等指的是其指向相同的内存单元。此外指针还能与NULL和0进行比较(如:p= =0;或p= =NULL;),用于判断指针是否为空,二者比较结果相同,但意义不同。

3> 指针与数组:(1)通过数组名引用一维数组元素:数组名代表数组首地址,即第一元素地址,它

可作为指针来使用;(2)通过指针引用一维数组元素:即将某个数组元素的地址赋给一个指针变量, 便可通过指针引用数组元素,如:数组a[3]={0,1,2},*p=a;*p=&a[1],都是正确的引用。 (3)二维数组与指针:一个二维数组可以看成一个以一维数组作为其每个元素的一维数组形式。注意:

以下是几个容易混淆的概念:A:a是数组名,始终不变的指向二维数组的起始单元,对它增减1将越过二维数组的一行,是行地址,a+i表示第i行第0列元素的起始地址。 B:a[0]:相当于一个一维数组名,代表了该行的首地址(指向该行第0列这个内存单元),对其增减1将越过二维数组的一个元素,是元素地址。a[0]+1表示二维数组第0行第1列元素的地址,*(a[0]+1)表示的是元素。 C:a[0][0]:表示二维数组第0行第0列的元素。 (4)使用指针变量表示字符串与字符数组表示字符串的区别:A:定义格式不同:前者:char * str=”hello”; str是字符指针变量,存放的是字符串首地址,而不是整个字符串; 后者:char str[]=”hello”;其中字符数组是由若干个数组元素组成的,它存放了整个字符串。 B:赋值方式不同:前者可以对变量str赋值(因为字符指针变量本身是一个变量,其值可变,可通过赋值使其指向新的字符串。);后者只能对其各个元素赋值,不能对数组名赋值(数组名代表首地址,不可改变)。

4> 指针变量与结构体:1结构体指针变量:指向结构体变量的指针变量。2,指针变量也可以指向结

构体数组。3,要通过运算符—>引用结构体中的成员。

5> 指针变量与函数:(1)指针变量作为函数参数:此时传递给函数的是变量的地址,即地址传递。

函数调用时,实参将地址传递给形参,使得二者指向同一内存地址,函数体内形参指针对所指变量的改变将直接影响实参所指向的对象的值,从而达到了在函数体内修改函数体外的变量值的目的。(2)返回指针的函数:格式:数据类型 * 函数名(形参表)。函数返回指针的最主要目的就是在函数结束时,通过指针返回大量的所需要的数据。因为,返回指针实质上是返回了地址,通过这些地址我们可以得到其中存放的内容,从而返回了大量的数据。 (3)指向函数的指针变量:每个函数在内存中都占有一定的内存空间,也有一个起始地址称为函数的入口地址,若将函数的起始地址赋给指针变量,则可使指针变量指向该函数,可通过指针变量来调用此函数。具体步骤为:A:定义一个指向函数的指针变量,格式为:数据类型 (*指针变量名)(形参表),数据类型表明指针变量所指向的函数的返回值类型; B:将函数的入口地址赋给指针变量。注意:利用指针变量调用函数时,若不作强制类型转换,指向函数的指针变量只能指向与该指针变量具有相同返回值类型和相同参数的任一函数。 C:通过指针变量调用函数。

6> 指针数组:若干同类型指针所组成的数组。定义格式:数据类型 * 指针数组名[元素个数]。

7> 二级指针:指针变量作为一种变量,它也有内存地址,是二级地址。用于存放指针变量的地址的

指针变量称为二级指针,即指向指针的指针。定义格式:数据类型 **指针变量名;使用时应注意:不能将变量的地址赋值给二级指针(其容纳的是指针的地址)。

8> new与delete的应用:1,new运算符:用于动态分配内存。执行new操作时,若操作成功,返

回的是内存地址,可赋给一个指针;如果无内存分配,则返回空指针NULL,所以,在使用new分配内存时,应检查内存分配是否成功。 使用格式:A:指针变量=new 类型名(初值);如:char *p=new char(?a?); B:指针变量=new 类型名[元素个数];如:cin>>n;char *p=new char[n];系统根据运行时n的值动态的为数组分配内存,若分配成功,则p将指向数组的第一个元素。 2,delete运算符:用于释放由new操作符分配且不需再用的内存空间。使用格式:A:delete 指针变量;或delete []指针变量;前者用于释放指针所指向的变量所占用的内存,若指针指向的是一个数组,则使用后者。 应注意:释放一个已释放的内存可能导致程序崩溃,所以释放后最好将指针变量置为0

9> 引用:1,引用本质上是一个别名,它不占存储空间,而是与它所关联的变量或对象占用同一个内

存空间,因此,所有对引用的操作实际上就是对引用的目标对象操作。定义格式:类型 & 引用名=变量名;注意点:在定义引用变量时,必须对其进行初始化;不能有空引用,引用必须维系一定的目标对象,空引用是无意义的;不能建立引用数组;不能定义引用的指针,也没有引用的引用。 2,引用作为函数参数:这种参数传递的方式称为引用传递。因为引用与其所关联的变量或对象占用同一个内存空间,因此,当引用作为函数的形参时,函数体内对引用形参的修改实际上是对引用所关联的变量的修改,即实参要根据形参的改变而改变。 3,引用为函数的返回值:如:int &f(inta,intb) .注意规则:A不能返回局部变量的引用,因为局部变量会在函数返回后被销毁,因此被返回的引用就成为了“无所指”的引用,程序会进入未知状态。B不能返回函数内部new分配的内存引用。 10> 单向链表的处理:略。 第八章 类和对象

1> 类:类是C++语言中的一种数据类型,在类中即可包含数据,又可包含对数据进行操作的函数,

类中成员包含数据成员和成员函数两部分,从访问权限上可分为三类:public,protected,private。 注意:在定义时:1,关键字出现的次数和次序可以是任意的;2,系统未对类分配内存空间,所以此时不能对其数据成员进行初始化;3,任何成员不能使用extern,auto,register。

2> 对象:是类的实例。对象的定义方法与定义结构体变量的方法类似:可以先定义类,后定义对象;

也可以同时定义,如:Local a,b;定义了类Local的两个对象a,b。 注意:通过运算符‘.’来访问对象的成员;同类的对象可直接赋值,如:b=a; 可以定义指向对象的指针; 对象也可以像其它变量一样作为数组的元素,函数的参数; 一个对象也可以作为其它类的成员使用。

3> 数据成员和成员函数:A:访问权限:1,public:允许被该类以外的函数访问; 2,protected:只

能被该类成员函数以及该类的派生类中成员函数访问;3private:只允许该类中的成员函数访问。 B:成员函数的重载:在类中说明2个或以上的函数的名字是相同但其参数类型或个数却不同的成员函数,编译器根据参数个数或类型的不同来判断调用哪一个函数。 C:this指针: 4> 类与结构体的异同:同:格式类同,结构体可以看成是类的一个特例; 异:类中成员的缺省访问

权限是private,而结构体中为public。 第九章 构造函数和析构函数 1> 对比表: 定义格式 构造函数 析构函数 类名(形参表);类外:类名::类名~类名(){······} (~) 作用 为对象分配内存,对类的数据成员进在对象消失时执行一些清理任务 行初始化并执行对象的其它内部管理操作 参数 返回值 重载 可以有 无 能 无 无 不能

默认~函数 调用 没有参数,函数体为空 创建对象时,自动被调用 函数体为空 某个对象生存期结束时自动被调用 是 与类名相同,函数名前有一波浪线 调用时间 类的成员函数 是 特点 对象类型 全局对象 局部对象 程序运行时 对象定义处 与类名相同 程序结束时 离开程序块时 程序结束时 Delete显示撤销时 静态局部对象 第一次执行对象定义时 new创建的对创建对象处 象 注意点:1,构造函数与对象的初始化:A:当定义类的对象时(系统为对象分配内存),类的构造函数可以完成对此对象的初始化(系统将参数传递给构造函数,从而给对象的数据成员赋了初值)。 B:使用new来动态建立对象时(该对象不再使用时需用delete释放对象所占有的空间),系统也自动调用构造函数为对象进行初始化,最后返回此对象的起始地址。 2,构造函数与对象成员:在定义一个新类时,可把一个已定义类的对象作为类的成员,对这样的对象成员进行初始化必须通过在新类的构造函数中调用对象成员的构造函数来实现。对象成员的构造函数的调用顺序与它们在成员初始化列表的次序无关,而是取决于它们在类定义中的声明次序。 3,通常析构函数中的主要工作是使用运算符delete释放由new动态生成的对象和对象数组所占有的内存空间,new与delete必须配套使用。 4,类型转换构造函数: 5:拷贝构造函数:当创建一个对象时,用另一个同类的对象对其初始化,系统会自动调用其。定义格式:类名 (类名&对象名);构造函数的参数必须是同类对象的引用。两种调用情况:如A(A&a);A a;A b=a;或A a;A b(a)。 5:每个类均有构造函数(一个或多个),若用户不定义,编译器将自动产生一个默认构造函数,形式为:类名::类名()。其有三种使用情形:(1)用户没有定义构造函数;(2)用户定义的没有形参的构造函数;(3)用户定义的每个形参都有默认值的构造函数。 注意:每个类只能有一个默认构造函数。 第十章 继承和派生类

1> 概念:A:定义格式:class 派生类名:继承方式 基类名1,基类名2······{}; B:继承方式:

其影响的是派生类对基类的原有成员的访问权限,但无论采用何种继承方式,基类中的私有成员在派生类中是不可访问的。 因此继承方式实际影响的只是对基类中原有的公用成员和保护成员的访问权限。 所以:共有派生:~保持原有的访问权限; 保护派生:~都成为派生类的保护成员; 私有派生:~都作为派生类的私有成员。

2> 初始化基类成员:构造函数是不可继承的。因此,派生类的构造函数必须通过调用基类的构造函

数初始化基类成员,派生类的构造函数的格式:派生类名(形参表):基类名1(形参表1),:基类名2(形参表2)··· 注意:A:在创建派生类对象时,先调用基类的构造函数,(派生类定义对象时)再调用对象成员的构造函数,最后调用派生类的构造函数;撤销对象时,析构函数被调用的顺序则相反。 B:多重继承时,先调用哪一个基类的构造函数,由派生类定义时先继承哪一个决定。 C:当派生类中包含对象成员时,则派生类的构造初始化成员列表中既要列出基类的构造函数也要列出对象的构造函数。 D:当类中有多个对象成员时,调用对象成员所属类(比一定是基类)的构造函数的顺序由对象成员定义的先后顺序决定。 E:基类中有缺省函数时(有默认的构造函数或未定义构造函数时),派生类构造函数后的成员初始化列表中可省略对基类构造函数的定义。

3> 冲突,支配规则和赋值兼容性:A:冲突:当多重继承时,不同基类中的成员常常有相同的名字,

从而导致派生出的成员重名的现象。 解决方法:1,使基类成员名各不相同;2,将所有基类的数据成员设为私有成员;3,使用作用域运算符来说明成员是属于哪个类的(常用方法),格式:类名::成员名。 B:支配规则:C++中允许派生类新增加的成员名与其基类名成员名相同,当没有使用作用域运算符时,派生类的定义的成员名优先于基类中的成员名,此关系即为支配规则; C:赋值兼容性规则:是指在公有派生情况下,一个派生类的对象可以用在其基类对象可使用的地方(即将一个派生类对象赋给基类的对象,这个赋值是将派生类从基类中继承来的成员赋给基类对象相应的成员),具体规则为:1,派生类的对象可以向基类的对象赋值,反之则不允许;2,派生类的对象可以初始化基类的引用;3,派生类对象的地址可以赋给指向基类类型的指针。3,以上情况只能访问从相应基类中继承来的成员,而不能访问其它基类的成员或在派生类中增加的成员。

4> 虚基类:为了使公共基类在它的派生类中只有一个拷贝(消除二义性),可将基类定义为虚基类。

1,定义格式为:class 派生类名:virtual 继承方式 基类名{···};或:将virtual后移一格。 2,虚基类构造函数:(1)若一个派生类有一个直接或间接的虚基类,则每个派生类的构造函数的初始化成员列表中都必须列出对虚基类构造函数的调用,若未被列出,则表示使用该虚基类的缺省构造函数来初始化派生类对象中的虚基类对象的成员;(2)在一个成员初始化列表中若同时出现对虚基类和非虚基类构造函数的调用,则应先调用虚基类的构造函数。

5> 友元函数:当类的成员访问权限被定义为私有或保护时,在类外只能通过该类的成员函数来访问,

为了提高程序的运行效率,引入友元函数。A:定义格式:friend 类型 函数名(形参){};B:友元成员函数:一个类的友元函数可以是一个不属于任何类的普通函数,也可以是另一个类的成员函数,此时友元函数称为~;C:友元类:当类A作为类B的友元时,即意味着类A中可使用类B的所有成员。 D:注意点:(1)友元函数不是类的成员函数,类的内外都可以定义友元函数;在类内定义时,并不表示它是该类的成员函数,它不属于任何类,在类外定义时,与普通函数定义一样,不应在函数名前加上类名;(2)友元函数可以访问类中的任何成员;(3)不可带this指针,所以可以用对象名,对象的应用和对象的地址作为友元函数的参数,在函数体中使用运算符“·”或“—>”来访问对象的成员;(4)在类中对友元函数指定的访问权限无效;(5)可以将普通函数,成员函数或者类作友元;(6)其调用不同于成员函数的调用,必须直接调用。 6> 静态成员:A:静态数据成员:由关键字static修饰的数据成员。必须在类体内作引用性说明,同

时在类体外对其作定义性说明(初始化格式:类型 类名::静态成员名=初始值;缺省初值为0。在类体外的使用格式:类名::静态成员名或对象名·静态成员名)。注意点:(1)在说明一个类的不同对象时,其成员之间是独立的,当我们将一个类的某些数据成员的存储类型指定为静态类型时,由该类所产生的所有对象均共享为静态成员分配的一个存储空间,在说明对象时,并不为静态类型的成员分配空间;(2)其初始化必须放在类外的全局范围内进行,不能在类的构造函数中对其初始化,因为构造函数将多次被调用,而静态数据成员只能初始化一次;静态数据成员是类的成员,而不是某个对象的成员,并且初始化时前面不加static,也不使用成员的访问权限控制符public等进行修饰。B:静态成员函数:类体内外均可定义,在类外时,不能用static修饰。

在类外可通过:“类名::静态成员函数名(实参)或对象名·静态成员函数名(实参)”来调用使用其。 注意点:在静态成员函数的实现中,不能直接引用类中说明的非静态成员(可通过对象来引用),只能直接引用本类中说明的静态成员; 为了保持静态数据的一致性,通常在构造函数中不给静态数据成员置初值,而在静态数据的定义性说明时置初值。 第十一章 多态性

1> C++中,多态性可分为:编译时的多态性(或称静态多态性)和运行时的多态性(或称动态多态

性)。编译时的多态性是通过函数重载或运算符重载来实现的;运行时的多态性是通过继承和虚函数来实现的。若某类中的成员函数被说明为虚函数,则该函数在派生类中可以有不同的实现。 2> 虚函数:1定义格式:A:在类体中定义:virtual 返回类型 函数名(形参表){函数体}; B:

在类体中原型说明(virtual 类型 函数名(形参);),在类体外定义:类型 类名::函数名(形参){函数名}; 2,注意点:A:虚函数可以在一个或多个派生类中被重定义(基类的虚函数在派生类中一定要重新定义),此时必须与基类中的函数原型完全相同(包括函数名,返回类型,参数个数和类型的顺序),而且无论在派生类的相应成员函数前是否加上关键字virtual,都将视其为虚函数。若果与函数原型不同,只是函数名相同,将其视为一般的函数重载,而不是虚函数。 B:实现运行时的多态性,必须使用基类类型的指针变量或者对基类的引用使指针指向不同派生类的对象,并通过调用指针所指向的虚函数才能实现动态的多态性(即只有基类的指针才能指向基类的对象和派生类的对象,且以“指针—>虚函数”的方式调用)。若通过“对象·虚函数”的方式调用虽然也能得到同样的结果,但不是运行时的多态性。 C:虚函数只能是类的一个成员函数,不能是静态成员函数,更不能是友元函数。 D:虚函数与重载函数的区别(二者都是在程序中设置一组同名函数,都反映了面向对象程序的多态性):虚函数不仅同名,而且同原型,而函数重载并不是原型完全相同; 虚函数仅用于基类和派生类之中,而函数重载则不需要通过继承关系来体现。E:构造函数不能定义为虚函数,但析构函数可以。

3> 纯虚函数:定义格式:virtual 返回类型 函数名(形参表)=0。 注意点:A:函数名赋予0表

示该函数无函数体,并不表示赋值运算; B:定义纯虚函数时,不能定义函数的实现部分,它的实现留给其派生类去完成; C:由于纯虚函数没有函数体,是一个不完整的函数,含纯虚函数的

类也是一个不完整的类,所以不能用含纯虚函数的类来说明对象; D:至少包含一个纯虚函数的类称为抽象类,它只能作为派生类的基类,不能声明抽象类的对象。抽象类的唯一用途就是为派生类提供基类;纯虚函数的作用是作为派生类中的成员函数的基础,并实现动态的多态性(其实现方法与一般的虚函数相似,所不同的是它要经过两次继承和派生)。

4> 运算符重载:就是对已有的运算符重新定义,按照用户规定的要求去完成特定的操作,其本质是

通过函数重载来实现的。 A:一般定义格式:类型 类名::operator@(形参表){···};其中:类型为运算符重载函数的返回值类型;类名为运算符重载函数所在的类名;operator为关键字;@代表被重载的运算符;形参表中参数的个数由运算符的目数及函数的类型来决定,函数的类型是指运算符重载函数可以是类的成员函数(定义格式:类型 operator 运算符(参数表){函数体}),也可以是类的友元函数(定义格式:friend~)。 B:使用成员函数重载运算符(运算符重载函数的参数个数为0个或1个)的方法:1:对于只有一目操作数的运算符,在重载这种运算符时,通常不能有参数;而对于有两目操作数的运算符,只能带一个参数,不允许重载三目操作数的运算符。 2:成员函数实现运算符的重载时运算符的左操作数一定是当前对象,右操作数作为调用运算符重载函数的参数,参数可以是对象,对象的引用,或其它类型的参数; 3:成员函数实现一元运算符重载的一般格式为:类型 类名::operator@(){···};其中@为被重载的一元运算符,成员函数的this指针所指向的对象作为运算符的操作数,但由于运算符++ ,——存在前置和后置的问题,在定义运算符重载时有所区别:++作前置运算时,运算符重载函数格式为:类型 类名::operator ++(){···};作后置运算时,格式为:类型 类名::operator ++(int a){···};此处参数仅作为与前置运算的区分,没有实际意义,所以变量名可有可无,——的重载函数的定义与此类同。 4:成员函数实现二元运算符重载的格式:类型 类名::operator @(参数表){···};其中,参数表中的参数只能有一个,运算符的左操作数一定是成员函数所在类的对象,成员函数的this指针指向此对象;运算符的右操作数作为函数的参数,它可以是对象,对象的引用或是其它类型的数据。 C:使用友元函数重载运算符的方法:由于友元函数不是类的成员函数,对于只有一目操作数的运算符,在重载这种运算符时,有一个参数;而对于有两目操作数的运算符,带有两个参数。 1:友元函数实现一元运算符重载的格式:friend 类型 operator @(X&x){···};

其中,运算符重载函数是类X的友元,X为类名,x为类X的对象。++作前置运算符时,其运算符重载函数格式为:friend 类型 类名::operator ++(类名&){···};后置时:~(类名&,int a)~ ,此处参数仅作为与前置运算的区分,无实际意义,变量名可有可无,——的重载函数的定义与此类同。 2:友元函数实现二元运算符重载格式:friend 类型 operator @(参数1,参数2){···}; 3:通常我们将二元运算符重载为友元运算符,一元运算符重载为类运算符。 D:成员函数重载运算符和友元函数重载运算符的联系与区别:(1)在类外定义时,成员函数的类型后面一定要有类名和作用域运算符,而友元函数则不能有; (2)成员函数可以通过this指针传递当前对象,而友元函数没有this指针,所以重载同一个运算符时,友元函数通常比成员函数多一个对象类型的参数(可以是对象,对象的引用或类类型的指针)注:对象作参数是值传递,为了把操作结果带回主函数,应以对象的引用或类类型的指针作参数。 (3)在函数体中,成员函数可以直接使用类的成员,而友元函数一定要指明成员所属的对象,即使用方式为:对象·成员,(*指针)·成员或 指针—>成员 。(4)二者实现的功能是一样的,对象表达式也是相同的,但其含义是不同的,函数的调用形式也是不同的。 E:重载运算符时的注意事项:(1)运算符重载是改变已有运算符的操作数范围和操作内容,而不能创造新的运算符,也不能改变运算符的优先级,目数和结合性等基本性质;(2)不允许重载运算符: ·(成员操作符),*(成员指针操作符), ::(作用域运算符), ?:(三目运算符), #(编译预处理符号), sizeof()(求字节数运算符)。 只能用成员函数重载:=,[],(),—>。 只能用友元函数重载: << , >> 。

本文来源:https://www.bwwdw.com/article/d2ap.html

Top