资源预览内容
第1页 / 共442页
第2页 / 共442页
第3页 / 共442页
第4页 / 共442页
第5页 / 共442页
第6页 / 共442页
第7页 / 共442页
第8页 / 共442页
第9页 / 共442页
第10页 / 共442页
亲,该文档总共442页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
C+C+面向对象面向对象程序设计程序设计C+面向对象程序设计面向对象程序设计教材: C+参考大全学时:40(理论)+24(实践)考试:70%(笔试)+30%(平时)第一章第一章 C+编程基础编程基础一、程序语言的发展一、程序语言的发展1、机器语言(用二进制代码表示)、机器语言(用二进制代码表示)2、汇编语言(用符号表示)、汇编语言(用符号表示)3、高级语言(类似自然语言)、高级语言(类似自然语言)第一章第一章 C+编程基础编程基础二、二、C+与与C的联系的联系1、C+是在是在C的基础上发展而来,的基础上发展而来, 是带类的是带类的C语言。语言。2、C语言支持结构化程序设计,语言支持结构化程序设计,C+ 语言支持面向对象程序设计。语言支持面向对象程序设计。3、结构化程序设计的思想:、结构化程序设计的思想: 功能分解功能分解,并逐并逐 步求精。步求精。 面向对象程序设计的本质:面向对象程序设计的本质: 把数据和处理数据的过程把数据和处理数据的过程 看成一个整体看成一个整体对象。对象。第一章第一章 C+编程基础编程基础第一章第一章 C+编程基础编程基础三、三、C+中几个重要概念中几个重要概念1、程序:数据、程序:数据+操作操作2、数据类型:不同的数据组织方式、数据类型:不同的数据组织方式 得到不同的数据类型得到不同的数据类型3、表达式:操作符、表达式:操作符+操作数操作数4、语句控制:数据操作的流程、语句控制:数据操作的流程第一章第一章 C+编程基础编程基础四、开发一个四、开发一个C+程序的四个步骤:程序的四个步骤:1、编辑(产生源文件,扩展名为、编辑(产生源文件,扩展名为CPP)2、编译(产生目标文件,扩展名为编译(产生目标文件,扩展名为OBJ)3 3、连接(产生执行文件,扩展名为连接(产生执行文件,扩展名为EXE)4、运行运行第一章第一章 C+编程基础编程基础五、集成开发环境(五、集成开发环境(IDE)1、定义:、定义:集文字处理、编译、连接、项目管理、程集文字处理、编译、连接、项目管理、程序排误等多功能为一体的软件开发工具序排误等多功能为一体的软件开发工具。2、常见的集成开发环境:、常见的集成开发环境: Borland C+,Visual C+第一章第一章 C+编程基础编程基础六、程序风格六、程序风格1、良好的编程风格,不仅有利于、良好的编程风格,不仅有利于 自己对程序的调自己对程序的调 试,而且会大试,而且会大 大增加程序的可复用机会。大增加程序的可复用机会。第一章第一章 C+编程基础编程基础2、注释、注释(1)定义:为增加程序的可读性而在)定义:为增加程序的可读性而在 程序中附加的说明性文字。程序中附加的说明性文字。(2)形式)形式: 以符号以符号/打头,只占一行。打头,只占一行。 C+特有的注释形式。特有的注释形式。 包含在符号包含在符号/与与/之间,可占多行。之间,可占多行。 继承继承C的注释形式。的注释形式。第一章第一章 C+编程基础编程基础六、程序风格六、程序风格3、命名(为常量、变量、函数取名)、命名(为常量、变量、函数取名)(1)名字必须符合标识符的规范。)名字必须符合标识符的规范。(2)标识符:由字母、数字、下划线组成,)标识符:由字母、数字、下划线组成, 而且而且 只能以字母、下划线打头。只能以字母、下划线打头。(3)名字不能是保留字(系统有固定用途)名字不能是保留字(系统有固定用途 的标识符)。的标识符)。(4)字母的大小写有区别。)字母的大小写有区别。(5)名字最好能表达一定的含义。)名字最好能表达一定的含义。第一章第一章 C+编程基础编程基础4、编排、编排编排时使用缩进、空行、空格编排时使用缩进、空行、空格使程序更清晰。使程序更清晰。第一章第一章 C+编程基础编程基础七、简单性原则七、简单性原则1、可以用一句话说清楚的,不要用一页、可以用一句话说清楚的,不要用一页 纸纸 去说明,可以用一个简单的语句完去说明,可以用一个简单的语句完 成的功能,不要用许多语句来完成。成的功能,不要用许多语句来完成。2、不要写太长的函数,可以用函数调用、不要写太长的函数,可以用函数调用 来缩短函数的定义。来缩短函数的定义。3、不要写太长的语句,可以用多条语句、不要写太长的语句,可以用多条语句 来代替一条语句。来代替一条语句。第一章第一章 C+编程基础编程基础4、如果文件太长,将它分成几个小文件。、如果文件太长,将它分成几个小文件。5、不要用太多的嵌套,可以考用、不要用太多的嵌套,可以考用switch 语句或者引入新的函数来解决问题。语句或者引入新的函数来解决问题。6、定义类时,一个文件放一个类的定义。、定义类时,一个文件放一个类的定义。第一章第一章 C+编程基础编程基础八、一致性原则八、一致性原则1、变量的命名应该有意义。、变量的命名应该有意义。2、在程序中加上适当的注释。、在程序中加上适当的注释。3、利用缩进使程序清晰。、利用缩进使程序清晰。4、相关的内容组织在一起。、相关的内容组织在一起。5、能简单,则简单。、能简单,则简单。第二章第二章 基本基本C+程序结构程序结构例例1:#include void main( ) cout ” 同学们同学们,你们好你们好! ”; 程序功能程序功能:在屏幕上显示输出在屏幕上显示输出 同学们同学们,你们好你们好!说明一说明一说明二说明二说明三说明三说明四说明四说明五说明五说明六说明六第二章第二章 基本基本C+程序结构程序结构一、编译预处理命令一、编译预处理命令#include1、#:预处理命令的标志。预处理命令的标志。2、 #include:包含命令;包含命令; 把一个文本文件的内容插入到该命令处。把一个文本文件的内容插入到该命令处。3、命令参数;命令参数; 给出要插入文件的文件名。给出要插入文件的文件名。返回返回第二章第二章 基本基本C+程序结构程序结构二、头文件:以二、头文件:以h为扩展名的文本文件为扩展名的文本文件 如果程序文件中引用到的函数、变量、如果程序文件中引用到的函数、变量、 常量、对象、数据类型等是由别的文件常量、对象、数据类型等是由别的文件 提供的,则必须在程序文件的开始部分提供的,则必须在程序文件的开始部分 用用#include命令把有关的头文件包含进来。命令把有关的头文件包含进来。返回返回第二章第二章 基本基本C+程序结构程序结构三、函数(具有特定功能的程序模块)三、函数(具有特定功能的程序模块)1、定义格式:、定义格式:返回类型返回类型 函数名(形式参数表)函数名(形式参数表)函数体函数体void main ( ) cout ” 同学们同学们, 你们好你们好! ”;返回返回第二章第二章 基本基本C+程序结构程序结构 (1)类型修饰符)类型修饰符 :函数返回值的类型。:函数返回值的类型。 (2)函数名:非保留字的标识符。)函数名:非保留字的标识符。 (3)形式参数表:由一系列用逗号隔)形式参数表:由一系列用逗号隔 开的参数组成。开的参数组成。 (4)函数体:包含在一对)函数体:包含在一对 中的语句序列。中的语句序列。第二章第二章 基本基本C+程序结构程序结构2、主函数(、主函数(main函数)函数)每个程序中至少要有一个函数,这个不可缺少每个程序中至少要有一个函数,这个不可缺少的函数就是主函数,约定主函数名为:的函数就是主函数,约定主函数名为: main(1)程序由一个或多个函数组成。程序由一个或多个函数组成。(2)如果程序中只有一个函数,则)如果程序中只有一个函数,则 一定是一定是main函数。函数。(3)如果程序中有多个函数,则有)如果程序中有多个函数,则有 且仅有一个为且仅有一个为main函数。函数。第二章第二章 基本基本C+程序结构程序结构(4) main函数是程序的入口,程序是从函数是程序的入口,程序是从 main函数开始执行的。函数开始执行的。(5) main函数的返回值函数的返回值 void:无返回值。无返回值。 int: 有有返回值。返回值。 (0表示程序正常结束表示程序正常结束 非非0表示程序非正常结束)表示程序非正常结束)第二章第二章 基本基本C+程序结构程序结构四、四、C+语句语句基本语句:以分号;作为结束标志。基本语句:以分号;作为结束标志。复合语句:包含在复合语句:包含在 中的基本语句序列。中的基本语句序列。返回返回第二章第二章 基本基本C+程序结构程序结构五、常量五、常量数据的一种重要表现形式,常量的值数据的一种重要表现形式,常量的值不可改变不可改变1、整型常量(整型常数)如:、整型常量(整型常数)如:1232、实型常量(实型常数)如:、实型常量(实型常数)如:1.233、字符常量(用、字符常量(用 括起的一个括起的一个字符)字符) 如:如: a 第二章第二章 基本基本C+程序结构程序结构4、字符串常量(用字符串常量(用 ” ”括起的括起的字符序列)字符序列) 如:如: ” student ”5 5、枚举枚举常量常量注:除字符串常量中引号内的字符以及注:除字符串常量中引号内的字符以及 注释外,其它字符必须是半角字符。注释外,其它字符必须是半角字符。 尤其注意不要误用中文标点。尤其注意不要误用中文标点。返回返回第二章第二章 基本基本C+程序结构程序结构六、六、cout和数据的显示输出和数据的显示输出1 1、 cout:连接显示器的输出流对象。连接显示器的输出流对象。2 2、 :输出操作符(插入操作符):输出操作符(插入操作符)第二章第二章 基本基本C+程序结构程序结构3、显示输出语句的格式:、显示输出语句的格式: cout 表达式表达式【 表达式表达式】 ; 注:注:【 】中内容可有可无,中内容可有可无, 若有,可重复多次。若有,可重复多次。 如:如:cout100; 屏幕输出屏幕输出 100 cout100200100+200; 屏幕输出屏幕输出 100200300返回返回第二章第二章 基本基本C+程序结构程序结构4、插入空格:(空格符为、插入空格:(空格符为 )如:如:cout 100 200100+200; ;屏幕输出屏幕输出 :100 200 300:100 200 300第二章第二章 基本基本C+程序结构程序结构5、换行输出、换行输出换行符号:换行符号:n 换行控制符:换行控制符:endl如:如:cout 100n200; cout 100endl200;则这两个语句的输出结果相同:则这两个语句的输出结果相同:100100200200第二章第二章 基本基本C+程序结构程序结构四点四点注意:注意:1 1、要输出的字符串需要用双引号、要输出的字符串需要用双引号” ”括起括起 来。但输出到屏幕上时,来。但输出到屏幕上时,双引号双引号” ” 并并 不显示。不显示。2 2、语句的最后要用分号、语句的最后要用分号 ;表示结束。表示结束。 第二章第二章 基本基本C+程序结构程序结构3 3、换行符号、换行符号n n 和换行控制和换行控制符符endlendl写写法不同,但效果相同。法不同,但效果相同。4 4、可以作为输出内容的不止是字符串,还、可以作为输出内容的不止是字符串,还可以是数、表达式等等。可以是数、表达式等等。返回返回第二章第二章 基本基本C+程序结构程序结构例例2:#include void main( ) float radius,circum; const float PI=3.14; cinradius; circum=2* * PI* *radius; cout ”circum=”circum; 说明一说明一说明二说明二说明三说明三第二章第二章 基本基本C+程序结构程序结构 程序功能:程序功能: 根据从键盘输入的半径,计算并输出根据从键盘输入的半径,计算并输出 圆的周长。圆的周长。 如:键盘输入如:键盘输入2.02.0,则屏幕输出:,则屏幕输出: circum=12.56 返回返回第二章第二章 基本基本C+程序结构程序结构 一、变量一、变量 数据的一种重要表现形式,变量的值数据的一种重要表现形式,变量的值 可以改变。可以改变。 1、变量必须先定义后使用。、变量必须先定义后使用。 定义格式:定义格式: 变量类型变量类型 变量名;变量名; 如:如: int age;返回返回第二章第二章 基本基本C+程序结构程序结构2、变量赋值和初始化变量赋值和初始化如:如:int age; age=20;/变量赋值变量赋值 int age=20;/变量初始化变量初始化第二章第二章 基本基本C+程序结构程序结构3、常值变量、常值变量在一般变量定义前加上保留字在一般变量定义前加上保留字const如:如:const float PI=3.14;注:常值变量定义时必须初始化,且值注:常值变量定义时必须初始化,且值 不可改变。常值变量名通常大写。不可改变。常值变量名通常大写。第二章第二章 基本基本C+程序结构程序结构 1、定义:由操作符和操作数按照一定、定义:由操作符和操作数按照一定 的语法规则组的语法规则组 成的符号序列。成的符号序列。 如:如:2* * PI* *radius /算术表达式算术表达式 circum=2* * PI* *radius /赋值赋值表达式表达式 注:最简单的表达式:注:最简单的表达式: 常量,变量,函数调用。常量,变量,函数调用。 二、表达式二、表达式返回返回第二章第二章 基本基本C+程序结构程序结构2、优先级和结合性:、优先级和结合性:优先级:不同操作符出现在同一表达式中,优先级:不同操作符出现在同一表达式中, 谁先运算的级别。谁先运算的级别。如:如:a+bc / 优先级高于优先级高于+结合性:同等优先级的操作符出现在同一表结合性:同等优先级的操作符出现在同一表 达式中,谁先运算的规定。达式中,谁先运算的规定。如:如:a+b-c /从左到右从左到右第二章第二章 基本基本C+程序结构程序结构3 3、表达式语句:、表达式语句:表达式后加表达式后加;如:如: circum=2* * PI* *radius;4、C+表达式的写法:表达式的写法:(1)所有字符写在同一水平线上。所有字符写在同一水平线上。(2)乘号:)乘号: 除号:除号: /(3)算术运算符不可省略。)算术运算符不可省略。第二章第二章 基本基本C+程序结构程序结构5、表达式的值、表达式的值(1)算术表达式)算术表达式算术运算符:算术运算符:+,-,/,% %(取模操作符):(取模操作符): 求两整数相除后所得的余数。求两整数相除后所得的余数。 如:如:22%7=1第二章第二章 基本基本C+程序结构程序结构 若两操作数都为整数,则计算结果为整数。若两操作数都为整数,则计算结果为整数。 如:如:345/10=34 若两操作数有一个为实数,则计算结果若两操作数有一个为实数,则计算结果 为实数。为实数。 如:如:345.0/10=34.5 第二章第二章 基本基本C+程序结构程序结构(2)赋值表达式:)赋值表达式:赋值操作符赋值操作符 =赋值表达式格式赋值表达式格式 变量变量=表达式表达式 如:如: circum=2 PIradius第二章第二章 基本基本C+程序结构程序结构 赋值表达式的值:赋值操作符左边表达赋值表达式的值:赋值操作符左边表达式的值。式的值。 如:如: cout(x=5):输入操作符(提取操作符):输入操作符(提取操作符) 键盘输入语句的格式:键盘输入语句的格式: cin 变量变量【 变量变量】;返回返回第二章第二章 基本基本C+程序结构程序结构1、【 】中内容可有可无,若有,可重复多次。中内容可有可无,若有,可重复多次。如:如:int a,b,c; cina; cinabc;2、格式中格式中cin后跟的是变量,不可是常量或后跟的是变量,不可是常量或 表达式。表达式。如:如:cin100;() cin100+200;()注:若在程序中用到注:若在程序中用到cin或或cout,则在程序中应则在程序中应 有有#include第三章第三章 数据类型数据类型一、一、C+数据类型分类图数据类型分类图数数 据据 类类 型型基本数据类型基本数据类型整整型(型(int)浮点浮点型型(float)字符型字符型(char)双精度型双精度型(double)无无值值(void)构造数据类型构造数据类型引申数据类型引申数据类型指针指针(*)引用引用(&)结构化数据类型结构化数据类型数组数组( )结构结构(struct)联合联合(union)位域位域枚举枚举(enum)类类(class)第三章第三章 数据类型数据类型 二、基本数据类型概况:二、基本数据类型概况: 1、数据在计算机中的存储、数据在计算机中的存储 (1)计算机内存单元的单位是字节,)计算机内存单元的单位是字节, 一个字节是一个字节是8个二进制位。个二进制位。 如:如:0000 0000 1010 1010 是两个字节。是两个字节。 第三章第三章 数据类型数据类型(2)不同的计算机中,同一数据类型)不同的计算机中,同一数据类型 占用的空间不一定相同。占用的空间不一定相同。 如:如:16位计算机中,整型占两个字节;位计算机中,整型占两个字节; 32位计算机中,整型占四个字节;位计算机中,整型占四个字节;第三章第三章 数据类型数据类型(3)数据占用内存字节的多少决定了其)数据占用内存字节的多少决定了其 能表达的数据的范围。能表达的数据的范围。 如:两个字节的整数表示范围是如:两个字节的整数表示范围是 -3276832767 第三章第三章 数据类型数据类型(4)计算机对内存中存放的同样信息解释)计算机对内存中存放的同样信息解释 会因其所能表示的数据类型的不同而会因其所能表示的数据类型的不同而 不同。不同。 如:如:0000 0000 0000 1010 在在16位计算机中位计算机中 若表示整数,则为一个整数若表示整数,则为一个整数 若表示字符,则为两个字符若表示字符,则为两个字符第三章第三章 数据类型数据类型注:定义变量时,数据类型有两个含义:注:定义变量时,数据类型有两个含义: 为该变量分配多大的存储空间;为该变量分配多大的存储空间; 如何解释该存储空间中的二进制数位。如何解释该存储空间中的二进制数位。 如:定义变量如:定义变量float radius; 则表示则表示radius 将要占用将要占用4个字节的存储空间,并且对这个字节的存储空间,并且对这 个空间的值的存放和解释都按小数进行个空间的值的存放和解释都按小数进行。第三章第三章 数据类型数据类型2、修饰符号、修饰符号long(长型符长型符) short(短型符短型符) signed(有符号型有符号型) unsigned(无符号型无符号型)第三章第三章 数据类型数据类型使用修饰符号后的基本数据类型使用修饰符号后的基本数据类型所属类型所属类型加修饰符后加修饰符后的类型的类型16位计算机位计算机中所占字节中所占字节数数简写简写 charchar1unsigned char 1signed char1 char第三章第三章 数据类型数据类型所属类型所属类型加修饰符后加修饰符后的类型的类型16位计算位计算机中所占机中所占字节数字节数简写简写 intint2unsigned int2signed int2 int所属类型所属类型加修饰符后的类加修饰符后的类型型16位计位计算机中算机中所占字所占字节数节数简写简写short intshort int2shortunsigned short int2signed short int2第三章第三章 数据类型数据类型所属类型所属类型加修饰符后加修饰符后的类型的类型16位计算位计算机中所占机中所占字节数字节数备备注注 long intlong int4longunsigned long int4signed long int4第三章第三章 数据类型数据类型所属类型所属类型加修饰符后加修饰符后的类型的类型16位计算位计算机中所占机中所占字节数字节数备备注注实型实型float4double8long double10第三章第三章 数据类型数据类型第三章第三章 数据类型数据类型 3、基本数据类型、基本数据类型 (1)void:实际上不能算是一种数据实际上不能算是一种数据 类型,它表示根本就没有值,通类型,它表示根本就没有值,通 常用于表示函数没有返回值。常用于表示函数没有返回值。第三章第三章 数据类型数据类型(2)整型)整型 整数的三种表示方式:整数的三种表示方式: 十进制:无前缀十进制:无前缀 如:如:12 八进制:八进制:0前缀前缀 如:如:012 十六进制:十六进制:OX(或(或ox)前缀前缀 如:如:OX12第三章第三章 数据类型数据类型(3)实型)实型 浮点数浮点数(float)和双精度数和双精度数(double)的区别的区别 表示的数据范围不同表示的数据范围不同 表示的精度不同表示的精度不同第三章第三章 数据类型数据类型 实数的两种表示形式实数的两种表示形式 定点数形式定点数形式 如:如:3.14 指数形式指数形式 如:如: 31400 3.14E4 0.314 3.14E-1第三章第三章 数据类型数据类型(4)字符型)字符型 字符型和整型的关系字符型和整型的关系 字符在内存中是以字符在内存中是以ASCII码存储,所以码存储,所以 字符和整数在一定范字符和整数在一定范 围内可以通用。围内可以通用。 如如:char c=60; int i = &; 第三章第三章 数据类型数据类型整数值的范围比字符类型值的范围整数值的范围比字符类型值的范围要大,所以在赋值时要注意不能超要大,所以在赋值时要注意不能超过字符的范围。过字符的范围。如:如:char c=1234;()第三章第三章 数据类型数据类型 尽管整数和字符可以在一定范围内尽管整数和字符可以在一定范围内 相互赋值,但它们表示的含义不同,相互赋值,但它们表示的含义不同, 一个表示整数,而另一个表示字符。一个表示整数,而另一个表示字符。 第三章第三章 数据类型数据类型 例例3:#include void main( ) int i=60; char c=i; cout ” The value of integer:”iendl; cout ” The value of character: ” c endl; 该程序的输出结果是:该程序的输出结果是: The value of integer:60 The value of character:第三章第三章 数据类型数据类型特殊字符(转义字符):以特殊字符(转义字符):以 开头的字符序开头的字符序列。列。名称名称符号符号名称名称符号符号空字符空字符0水平制表水平制表t换行换行n垂直制表垂直制表v换页换页f问号问号?回车回车r反斜线反斜线回格回格b单引号单引号响铃响铃a双双引号引号”第三章第三章 数据类型数据类型如:如:cout” How are you!”; 则屏幕输出:则屏幕输出: How are you! cout” ”How are you! ” ”; 则屏幕输出:则屏幕输出: ” How are you! ”第三章第三章 数据类型数据类型字符串(用字符串(用” ”括起来的字符序列)括起来的字符序列) 0:字符串结束符;不显示,但占一个:字符串结束符;不显示,但占一个 字节的存储空间。字节的存储空间。 如:如: ”Hello ” 内存表示为:内存表示为: H e l l o0 第三章第三章 数据类型数据类型如:如:”0”与与0的差别:的差别:”0”为字符串,内存表示为:为字符串,内存表示为: 0为字符,内存表示为:为字符,内存表示为: 00 0第三章第三章 数据类型数据类型 4、数据类型长度的确定、数据类型长度的确定 格式格式:sizeof(数据类型数据类型) 如如:cout ” Size of int is:”sizeof(int); 则屏幕输出:则屏幕输出: Size of int is:2 表示在表示在16位计算机中,位计算机中, int型的型的长度为长度为2个个字节。字节。第三章第三章 数据类型数据类型5、选择数据类型的原则、选择数据类型的原则 根据所表示的数据的类型选择。根据所表示的数据的类型选择。 根据所表示的数据的范围选择。根据所表示的数据的范围选择。第三章第三章 数据类型数据类型三、结构化数据类型概况三、结构化数据类型概况1、数组、数组数组变量可以存放一组具有相同类型的数组变量可以存放一组具有相同类型的数据。数据。数组变量的定义格式:数组变量的定义格式: 数据类型数据类型 数组名数组名 数组元素个数数组元素个数 如:如:int grade50; 则将变量则将变量grade定义成一个可存放定义成一个可存放50个整个整 数的整型数组数的整型数组。第三章第三章 数据类型数据类型下标访问下标访问 通过下标访问操作符通过下标访问操作符 访问指定的数组访问指定的数组元素。元素。 若数组元素个数若数组元素个数为为n,则下标范围是:则下标范围是:0n-1如:如: grade0表示该数组的第一个元素。表示该数组的第一个元素。 grade49表示该数组的最后一个元素。表示该数组的最后一个元素。第三章第三章 数据类型数据类型2、枚举、枚举枚举是一种用户自定义的类型,使用前必枚举是一种用户自定义的类型,使用前必须先定义。须先定义。 枚举类型的定义格式:枚举类型的定义格式: enum 枚举类型名枚举类型名常量常量1,常量,常量2,常常量量n;如如:enumWEEKDAYSun,Mon,Tue,Wed,Thu,Fri,Sat; 第三章第三章 数据类型数据类型定义了一个枚举类型后定义了一个枚举类型后,就可以用该就可以用该类型来定义变量类型来定义变量. 如如: WEEKDAY w1,w2=sat;第三章第三章 数据类型数据类型某一枚举类型的变量,它的取值范围限某一枚举类型的变量,它的取值范围限定在定在 中的中的n个变量。个变量。 如:如: WEEKDAY类型的两个变量类型的两个变量w1,w2,它们只能它们只能Sun,Mon,Tue,Wed,Thu,Fri,Sat这七个这七个符符号常量中取值。号常量中取值。第三章第三章 数据类型数据类型枚举类型中的每个符号常量对应一个整数。枚举类型中的每个符号常量对应一个整数。 两种对应关系:两种对应关系: 依此与整数依此与整数0,1,2,n对应。对应。 用赋值号规定其对应关系。用赋值号规定其对应关系。第三章第三章 数据类型数据类型 如:如: enum WEEKDAYSun,Mon,Tue,Wed,Thu, Fri,Sat; 此枚举类型中此枚举类型中: Sun,Mon,Tue,Wed,Thu,Fri,Sat对应的整数分别对应的整数分别为:为:0,1,2,3,4,5,6第三章第三章 数据类型数据类型如:如:enum SomeDigitsONE=1,TWO,FIVE=5,SIX,SEVEN;此枚举类型中此枚举类型中:ONE=1,TWO=2,FIVE=5,SIX=6,SEVEN=7第三章第三章 数据类型数据类型3、结构、结构结构是一种用户自定义的类型,结构是一种用户自定义的类型,使用前必须先定义。使用前必须先定义。 第三章第三章 数据类型数据类型 结构类型的定义格式:结构类型的定义格式: struct 结构类型名结构类型名 成员成员1; 成员成员2; 成员成员n; ;第三章第三章 数据类型数据类型 如:如:struct Person char name10; int sex; int age; float pay; ;定义了一种结构类型后,可以用该类型来定义变量。定义了一种结构类型后,可以用该类型来定义变量。如:如:Person p1;第三章第三章 数据类型数据类型对结构变量进行赋值:对结构变量进行赋值: 对各成员进行赋值对各成员进行赋值如:如:p1.name= ” WangPin”; p1.sex=1; p1.age=35; p1.pay=1000.0; 在定义结构变量时进行初始化在定义结构变量时进行初始化如:如:Person p1=” WangPin”,1,35,10001,35,1000、. .第四章第四章 程序流程控制程序流程控制一、复合语句一、复合语句 1、最常用的四类语句:、最常用的四类语句: (1)说明和定义语句。)说明和定义语句。 如如:char a,b; (2)表达式语句表达式语句 如:如:c=a+b; (3)流程控制语句流程控制语句 (4)异常处理语句)异常处理语句第四章第四章 程序流程控制程序流程控制2、复合语句、复合语句 包含在一对包含在一对 的语句序列。的语句序列。 如:如: int i=4; couti; (3)couti2;计算机按语句的先后顺序依此执行计算机按语句的先后顺序依此执行(1)()(2)()(3)第四章第四章 程序流程控程序流程控制制 四、分支流程四、分支流程 (一)(一)if 语句语句 1、格式一:、格式一: if (条件)条件) 语句;语句; 功能:如果条件为真,则执行语句;功能:如果条件为真,则执行语句; 否则什么都不做。否则什么都不做。第四章第四章 程序流程控制程序流程控制例例1:#include void main( ) float score; cin score; if(score=60) cout ”及格及格”; 第四章第四章 程序流程控制程序流程控制2、格式二:、格式二: if (条件)条件) 语句语句1 else 语句语句2功能:如果条件为真,则执行语句功能:如果条件为真,则执行语句1; 条件为假,则执行语句条件为假,则执行语句2 。第四章第四章 程序流程控制程序流程控制例例2:#include void main( ) float score; cin score; if(score=60) cout ”及格及格”; else cout ”不及格不及格”; 第四章第四章 程序流程控制程序流程控制3、 if语句的嵌套:语句的嵌套: if语句中又含有语句中又含有if语句。语句。例例3:#include void main( ) float score; cin score; if(score=60) if(score=90) cout=80) cout ”良好良好”; else cout ”及格及格”; else cout ”不及格不及格”; 注:注: elseelse总是与离它最近的尚未配对总是与离它最近的尚未配对的的ifif配对配对。第四章第四章 程序流程控程序流程控制制4、if多分支结构多分支结构通过规范化通过规范化的的if嵌套所构成的多分支结构。嵌套所构成的多分支结构。if嵌套放在嵌套放在elseelse之后之后第四章第四章 程序流程控制程序流程控制 格式:格式: if(条件条件1)语句)语句1 else else if(条件条件2)语句)语句2 else else if(条件条件3)语句)语句3 else else if(条件条件n)语句语句n 【 else else 语句语句n+1 】第四章第四章 程序流程控制程序流程控制例例4:#include void main( ) float score; cin score; if(score100) cout ”输输入入错错误误!”; else if (score 60) cout ”不及格不及格”; else if (score 70) cout ”及格及格”; else if (score 80) cout ”中等中等”; else if (score 90) cout ”良好良好”; else cout ”优秀优秀”; 第四章第四章 程序流程控制程序流程控制二二switch语句语句 1、格式:、格式: switch(表达式)表达式) case 常量表达式常量表达式1:语句:语句1; case 常量表达式常量表达式2:语句:语句2; case 常量表达式常量表达式n:语句语句n; 【default:语句语句n+1; 】 第四章第四章 程序流程控制程序流程控制 2、执行顺序:、执行顺序: 先计算先计算switch语句中表达式的值,然后在语句中表达式的值,然后在case 语句中寻找值相等的常量表达式,并以此为入语句中寻找值相等的常量表达式,并以此为入口,由此开始口,由此开始 顺序执行。如果没有找到顺序执行。如果没有找到 相等相等的常量表达式的常量表达式,且,且default 后的后的语句语句n+1存在,存在,则执行语句则执行语句n+1,否则什么都不做。否则什么都不做。第四章第四章 程序流程控制程序流程控制3、五点注意:、五点注意:(1) case后表达式的值必须是整型的。后表达式的值必须是整型的。(2)各常量表达式的值不能相同。)各常量表达式的值不能相同。(3)每个)每个case语句的分支可以有多条语句,语句的分支可以有多条语句, 但不必用但不必用 。第四章第四章 程序流程控制程序流程控制(4)每个)每个case语句只是一个入口标号,并语句只是一个入口标号,并不能确定执行的终止点,因此每个不能确定执行的终止点,因此每个case分分支的最后最好加上支的最后最好加上break语句,用来结语句,用来结 束当前束当前switch语句的执行;否则会从入口语句的执行;否则会从入口点开始一直执行点开始一直执行到到switch语句的结束。语句的结束。(5)当若干分支需要执行相同操作时,可)当若干分支需要执行相同操作时,可以使多个以使多个case分支共用一组语句。分支共用一组语句。第四章第四章 程序流程控制程序流程控制例例5:根据整型变量:根据整型变量dayoftheweek(0-6)值输出其表示值输出其表示的星期几的英语单词。的星期几的英语单词。(无(无break语句)语句) Switch(dayoftheweek) case 0: cout ”Sunday”; case 1: cout ”Monday”; case 2: cout ”Tuesday”; case 3: cout ”Wednesday”; case 4: cout ”Thursday”; case 5: cout ”Friday”; case 6: cout ”Saturday”; default:cout ”Unknown week day”; ;第四章第四章 程序流程控制程序流程控制若若dayoftheweek的值为的值为4,则输出结果为:则输出结果为:ThursdayFridaySaturdayUnknown week day第四章第四章 程序流程控制程序流程控制(有(有break语句)语句) Switch(dayoftheweek) case 0: cout ”Sunday”; break; case 1: cout ”Monday”; break; case 2: cout ”Tuesday”; break; case 3: cout ”Wednesday”; break; case 4: cout ”Thursday”; break; case 5: cout ”Friday”; break; case 6: cout ”Saturday”; break; default:cout ”Unknown week day”; break; ;第四章第四章 程序流程控制程序流程控制若若dayoftheweek的值为的值为4,则输出结果为:则输出结果为:Thursday第四章第四章 程序流程控制程序流程控制(三)(三) if多分支结构和多分支结构和switch语句的改写语句的改写 改写条件:改写条件: switch语句中每个非空语句序列语句中每个非空语句序列 的最后一个语的最后一个语 句为句为break语句。语句。第四章第四章 程序流程控制程序流程控制例例6:例:例5的后一个的后一个switch语句可改写语句可改写为为if多分支结构多分支结构 if(dayoftheweek=0=0) cout ” Sunday”; else if (dayoftheweek = 1 1) cout ” Monday”; else if (dayoftheweek =2=2) cout ” Tuesday”; else if (dayoftheweek =3=3) cout ” Wednesday”; else if (dayoftheweek =4=4) cout ” Thursday”; else if (dayoftheweek =5=5) cout ” Friday”; else if (dayoftheweek =6=6) cout ” Saturday”; else cout ” Unknown week day”;第四章第四章 程序流程控制程序流程控制五、循环流程五、循环流程 (一)(一)while语句语句 1、格式:、格式: while(循环条件)循环条件) 循环体循环体注:循环体是单个语句注:循环体是单个语句,或者是复合语句。或者是复合语句。第四章第四章 程序流程控制程序流程控制2、执行过程:、执行过程:当循环条件为真时,当循环条件为真时,执行循环体,否则执行循环体,否则退出循环。退出循环。 3、流程图(见右上图)、流程图(见右上图) 循环条件?循环条件? 循环体循环体YN第四章第四章 程序流程控制程序流程控制例例7:#include void main( ) int sum=0; int i=1; while(I=100) int sum=sum+i; i+; cout ”sum=”sum; 程序功能:计算并输出从程序功能:计算并输出从1加到加到100的和。的和。输出结果:输出结果: sum=5050第四章第四章 程序流程控制程序流程控制(二)(二)dowhile语句语句 1、格式:、格式: do 循环体循环体 while(循环条件)循环条件);第四章第四章 程序流程控制程序流程控制2、执行过程:、执行过程:循环执行语句,循环执行语句,直到循环条件为假时,直到循环条件为假时,退出循环。退出循环。3、流程图(见右上图)、流程图(见右上图)循环体循环体循环条件?循环条件?YN第四章第四章 程序流程控制程序流程控制例例8:#include void main( ) int sum=0; int i=1; do sum=sum+i; i+; while(i=100) cout ” sum=”sum; 第四章第四章 程序流程控制程序流程控制3、 dowhile语句语句与与while语句唯一的区别:语句唯一的区别: while语句的循环体有可能一次不执行。语句的循环体有可能一次不执行。 dowhile语句的循环体至少执行一次语句的循环体至少执行一次。第四章第四章 程序流程控制程序流程控制(三)(三)for语句语句1、格式:、格式:for(循环初始化;循环条件;循环参数调整)循环初始化;循环条件;循环参数调整) 循环体循环体第四章第四章 程序流程控制程序流程控制 2、执行过程:、执行过程:(1)进行循环初始化;)进行循环初始化;(2)判断循环条件;)判断循环条件;(3)如果循环条件为真,则执行循环体、对)如果循环条件为真,则执行循环体、对 循环参数调整,然后转向步骤(循环参数调整,然后转向步骤(2);如);如 果循环条件为假,则结束循环。果循环条件为假,则结束循环。第四章第四章 程序流程控制程序流程控制3、流程图、流程图:循环初始化循环初始化循环条件?循环条件?循环体循环体循环参数调整循环参数调整YN第四章第四章 程序流程控制程序流程控制例例9:#include void main( ) int sum=0; for(int i=1; i=100; i+) sum=sum+i; cout ”sum=”sum; 第四章第四章 程序流程控制程序流程控制3、for语句语句和和while语句的区别:语句的区别:(1) for语句一般用于循环次数已知的情况;语句一般用于循环次数已知的情况;(2) while语句不仅可以用于循环次数已知语句不仅可以用于循环次数已知 的情的情 况,也可以用于循环次数未知的情况;况,也可以用于循环次数未知的情况;(3)一切)一切用用for语句实现的循环都可以语句实现的循环都可以用用while语句来代替,反之不可以语句来代替,反之不可以。第四章第四章 程序流程控制程序流程控制六、转向语句六、转向语句(一)(一)break语句语句(break;)功能:循环体中的功能:循环体中的break语句使程序流程跳出语句使程序流程跳出 所在的循环语句,转而执行循环语句的所在的循环语句,转而执行循环语句的 下一条语句;如果存在多重循环,则下一条语句;如果存在多重循环,则 break只能从它所在层的循环语句中跳出,只能从它所在层的循环语句中跳出, 并不能跳出所有的循环。并不能跳出所有的循环。第四章第四章 程序流程控制程序流程控制例例10:计算并输出从键盘输入的若干个整:计算并输出从键盘输入的若干个整数的平均值,以数的平均值,以0作为输入的结束标志。作为输入的结束标志。 若从键盘输入若从键盘输入10 15 20 则输出:则输出: sum/num=15. .0第四章第四章 程序流程控制程序流程控制例例10:#include void main( ) int sum=0;/ sum存放输入的整数的和存放输入的整数的和 int inval; / inval存放当前输入的整数存放当前输入的整数 int num=0; / num存放输入的整数个数存放输入的整数个数 while(1) cininval; if(inval=0)break; sum=sum+inval;num+; cout ”sum/num=”(float)sum/num; 第四章第四章 程序流程控制程序流程控制(二)(二)continue语句语句(continue;) 功能:循环体中的功能:循环体中的continue语句表示结束语句表示结束 当前的一次循环,跳转到循环开始当前的一次循环,跳转到循环开始 处,继续执行下一次循环。处,继续执行下一次循环。第四章第四章 程序流程控程序流程控制制例例11:从键盘输入若干个整数,计算并:从键盘输入若干个整数,计算并 输输 出其中正数的平均值,以出其中正数的平均值,以0作作 为输入的结束标志。为输入的结束标志。 若从键盘输入若从键盘输入10 -15 15 -30 20 则输出:则输出: sum/num=15. .0第四章第四章 程序流程控制程序流程控制例例11:#include void main( ) int sum=0; int inval; int num=0; while(1) cininval; if(inval=0)break; if(inval 0)continue; sum=sum+inval; num+; cout ”sum/num=”(float)sum/num; 第四章第四章 程序流程控程序流程控制制(三三)goto语句语句格式:格式: goto 标号;标号; 标号:标号: 功能:将程序的执行转移到标号处。功能:将程序的执行转移到标号处。例例12:将例:将例10中的中的break语句语句用用goto语句代替。语句代替。第四章第四章 程序流程控制程序流程控制例例12:#include void main( ) int sum=0; int inval; int num=0; while(1) cininval; if(inval=0) goto loop; sum=sum+inval; num+; loop: cout ”sum/num=”=y) return x; else return y; 第五章第五章 函数函数(一)返回类型一)返回类型1、函数返回结果值的数据类型。、函数返回结果值的数据类型。2、返回类型可以是除数组以外的、返回类型可以是除数组以外的 任意数据类型。任意数据类型。3、若函数的返回类型为、若函数的返回类型为void, 则表示此函数无返回值。则表示此函数无返回值。第五章第五章 函数函数4、若函数有返回值,则在函数体中应、若函数有返回值,则在函数体中应 有有return语句语句: return (表达式表达式); 或或 return 表达式表达式; 若函数无返回值,则在函数体中可若函数无返回值,则在函数体中可 以没有以没有return语句语句,也可以用空的也可以用空的return语句语句: return;第五章第五章 函数函数(二二)函数名函数名1、函数名应是一个非保留字的标识符。、函数名应是一个非保留字的标识符。2、函数名代表一个函数。、函数名代表一个函数。3、函数命名时,应该尽量使名字能代表、函数命名时,应该尽量使名字能代表 函数所完成的功能。函数所完成的功能。第五章第五章 函数函数(三)函数参数三)函数参数1、函数参数是函数完成功能所需要的输入信息。、函数参数是函数完成功能所需要的输入信息。2、函数参数可有、函数参数可有0个或多个,参数之间用,隔开。个或多个,参数之间用,隔开。3、每个函数参数由参数类型和参数名来表示;、每个函数参数由参数类型和参数名来表示;参数类型可以是任意数据类型,参数名是非保留参数类型可以是任意数据类型,参数名是非保留字的标识符。字的标识符。第五章第五章 函数函数4、函数定义中的函数参数称为形式参数,、函数定义中的函数参数称为形式参数, 函数调用中的函数参数称为实在参数。函数调用中的函数参数称为实在参数。 函数的形式参数和实在参数在类型和函数的形式参数和实在参数在类型和 数量上应该保持一致。数量上应该保持一致。第五章第五章 函数函数(四)函数体四)函数体1、函数体是函数功能的实现部分。、函数体是函数功能的实现部分。2、函数体由一系列语句构成,这些语、函数体由一系列语句构成,这些语句包含在一对句包含在一对 中。中。3、定义在函数体中的变量或常量是局、定义在函数体中的变量或常量是局部量,只能在定义它们的函数中使用;部量,只能在定义它们的函数中使用; 定义在任何函数外的变量或常量是全定义在任何函数外的变量或常量是全 局局 量,它可以在所有的函数中使用。量,它可以在所有的函数中使用。第五章第五章 函数函数三、函数调用三、函数调用(一)函数调用就是暂时中断现有程序一)函数调用就是暂时中断现有程序 的运行,转去执行被调用函数,的运行,转去执行被调用函数, 当被调用函数执行结束之后,再当被调用函数执行结束之后,再 返回到中断处继续执行。返回到中断处继续执行。(二)函数调用格式:(二)函数调用格式: 函数名函数名 (实在参数表)(实在参数表)第五章第五章 函数函数例例2:#include int max(int x,int y) if (xy) return x; else return y; void main( ) int val1,val2; cinval1val2; coutmax(val1,val2);程序功能:程序功能:从键盘输入两个整数,输出两者中较大的一个。从键盘输入两个整数,输出两者中较大的一个。如:从键盘输入:如:从键盘输入:3 5 3 5 则屏幕输出:则屏幕输出:5 5 注:注:函数调用本身也可以看成是一个表达式。函数调用本身也可以看成是一个表达式。第五章第五章 函数函数第五章第五章 函数函数四、程序运行时的内存分布四、程序运行时的内存分布(一)程序的内存区域(一)程序的内存区域1、程序代码区:存放函数编译成的二、程序代码区:存放函数编译成的二 进制代码。进制代码。2、全局数据区:存放全局变量和静态、全局数据区:存放全局变量和静态 变量。变量。3、堆:存放动态数据。、堆:存放动态数据。4、栈:存放局部数据。、栈:存放局部数据。第五章第五章 函数函数(二)每次进行函数调用时,内存应存放二)每次进行函数调用时,内存应存放 以下信息:以下信息:1、当前函数的运行状态和返回地址;、当前函数的运行状态和返回地址;如果是如果是main函数,则保存操作系统的函数,则保存操作系统的当前状态和返回地址。当前状态和返回地址。2、被调用函数的参数。、被调用函数的参数。3、被调用函数的局部变量。、被调用函数的局部变量。第五章第五章 函数函数(三)每进行一次函数调用,系统应作三)每进行一次函数调用,系统应作 如下工作:如下工作:1、建立被调用函数的栈空间。、建立被调用函数的栈空间。2、保存调用函数的运行状态和返回地址。、保存调用函数的运行状态和返回地址。3、将实在参数的值传递给被调用函数。、将实在参数的值传递给被调用函数。4、将程序控制交给被调用函数。、将程序控制交给被调用函数。第五章第五章 函数函数(四)当一个函数执行结束之后,系统四)当一个函数执行结束之后,系统 应作如下工作:应作如下工作:1、如果函数有返回值,将函数的返回值放到、如果函数有返回值,将函数的返回值放到 一个临时的变量空间。一个临时的变量空间。2、根据栈顶记录的信息,恢复调用函数的运、根据栈顶记录的信息,恢复调用函数的运 行状态。行状态。3、释放栈顶空间。、释放栈顶空间。4、根据函数的返回地址,继续调用函数的运、根据函数的返回地址,继续调用函数的运 行。行。注:注:在不再需要所申请的内存空间时,一定要及在不再需要所申请的内存空间时,一定要及时释放。时释放。第五章第五章 函数函数五、函数的参数五、函数的参数(一)函数参数的传递(一)函数参数的传递 1 1、函数调用时:实在参数函数调用时:实在参数 形式参数形式参数 2 2、函数参数的传递方式:、函数参数的传递方式: 按值传递按值传递 按地址传递按地址传递 按引用传递按引用传递第五章第五章 函数函数(二)二)main函数的参数函数的参数1、 main函数一般情况下无参数。函数一般情况下无参数。2、 main函数若有参数,则规定其有两函数若有参数,则规定其有两个参数,其中一个参数是字符串数组,个参数,其中一个参数是字符串数组,另一个参数是整数。字符串数组就是另一个参数是整数。字符串数组就是输入的命令,整数就是字符串的个数。输入的命令,整数就是字符串的个数。通常这两个参数的名字称作通常这两个参数的名字称作argc和和argv。 即:即:void main (int argc,char *argv );第五章第五章 函数函数六、六、const参数、参数、 const返回值与返回值与const函数函数(一)一) const参数参数 1、出现在函数参数中的、出现在函数参数中的const表示在表示在函数体中不能对这个参数做修改。函数体中不能对这个参数做修改。 2、 const通常用来限制函数的指针参通常用来限制函数的指针参数、引用参数和数组参数。数、引用参数和数组参数。如:如:int strcmp(const char*str1, const char*str2);第五章第五章 函数函数(二)二) const返回值返回值 1、函数返回值为、函数返回值为const,只有用在函数值为只有用在函数值为 引用类型的情况。引用类型的情况。 2、const返回值的函数调用不能放在赋值号返回值的函数调用不能放在赋值号 的左边。的左边。 如:如:const int &min(int&,int&); 则:则:min(a,b)=4;()第五章第五章 函数函数(三)三) const函数函数1、在函数头后面加上、在函数头后面加上const,表示这个表示这个 函数是一个只读函数。函数是一个只读函数。2、 const函数通常作为类的成员函数,函数通常作为类的成员函数, 表示此函数不能改变类对象的成员表示此函数不能改变类对象的成员 变量的值。变量的值。如:如:void printmessage(char*msg) const;第五章第五章 函数函数七、作用域七、作用域(一)作用域就是标识符在程序中能使用的一)作用域就是标识符在程序中能使用的 范围。范围。(二)(二)c+中标识符的作用域与标识符的声明中标识符的作用域与标识符的声明 位置密切相关。一个标识符的作用域一位置密切相关。一个标识符的作用域一 般开始于般开始于 标识符的声明处,而结束位置标识符的声明处,而结束位置 取决于标识符声明在程序中的位置。取决于标识符声明在程序中的位置。第五章第五章 函数函数(三)作用域分类:(三)作用域分类: 文件作用域、局部作用域、类作用域文件作用域、局部作用域、类作用域(四)局部作用域(四)局部作用域 1、当标识符的声明出现在函数定义中时,、当标识符的声明出现在函数定义中时, 它将具有局部作用域。它将具有局部作用域。第五章第五章 函数函数2、五种情况:、五种情况:(1)函数参数的作用域从函数头开始到)函数参数的作用域从函数头开始到 函数定义结束。函数定义结束。(2)函数体中定义的局部变量的作用域)函数体中定义的局部变量的作用域 从变量定义开始,到函数定义结束。从变量定义开始,到函数定义结束。 (3)如果函数体中定义的局部变量定义)如果函数体中定义的局部变量定义 在一个复合语句中,则变量作用域在一个复合语句中,则变量作用域 从变量定义开始,到该复合语句结束。从变量定义开始,到该复合语句结束。(4)在)在for语句的初始化表达式中定义的语句的初始化表达式中定义的 变量的作用域取决于编译器的实现,变量的作用域取决于编译器的实现, 在在ANSIc+中规定其作用域在中规定其作用域在for语语 句范围之内。句范围之内。第五章第五章 函数函数第五章第五章 函数函数(5)在函数中定义的标号语句(与)在函数中定义的标号语句(与goto语语 句配合使用)的作用域是整个函数体,句配合使用)的作用域是整个函数体, 因为因为goto语句可能跳转到函数内的任何语句可能跳转到函数内的任何 一处。一处。第五章第五章 函数函数例例3:从键盘输入一个整数:从键盘输入一个整数n,计算并输出计算并输出n!#includedouble factorial(int n) /n作用域开始作用域开始double retVal=1; / retVal作用域开始作用域开始 for(int i=1;in;if(n=0) goto END; fact=factorial(n); cout n”!=”factendl; while(1); /n作用域结束作用域结束END: cout ”Thank you!n”; /fact,END作用域结束作用域结束第五章第五章 函数函数第五章第五章 函数函数(五)文件作用域五)文件作用域1 1、在所有函数定义之外说明的标识符具有、在所有函数定义之外说明的标识符具有 文件作用域,其作用域从说明点开始,文件作用域,其作用域从说明点开始, 一直延伸到文件结束。一直延伸到文件结束。2 2、在头文件中定义的变量的作用域可以看、在头文件中定义的变量的作用域可以看 成从成从#include#include该头文件开始的位置到程该头文件开始的位置到程 序结束。序结束。例例4:#include /cin,cout的作用域开始的作用域开始double factorial(int n) / factorial的作用域开始的作用域开始 void main( ) / main的作用域开始的作用域开始 / cin,cout ,factorial和和main的作用域结束。的作用域结束。第五章第五章 函数函数第五章第五章 函数函数(六)覆盖问题六)覆盖问题1、如果作用域重叠,则局部变量将覆盖、如果作用域重叠,则局部变量将覆盖 全局变量,作用域小的局部变量将覆全局变量,作用域小的局部变量将覆 盖同名的作用域大的局部变量。盖同名的作用域大的局部变量。第五章第五章 函数函数例例5: #includeint x;void addx( )x+;coutxendl; int x=5; coutxendl;void main( )int x=10; coutxendl;addx( ); coutxendl;x+;coutxendl;运行结果为:运行结果为:10151011第五章第五章 函数函数2、若函数的参数和函数的局部变量、若函数的参数和函数的局部变量 名字相同,则同样满足:名字相同,则同样满足: 作用域小的覆盖同名的作用域大的。作用域小的覆盖同名的作用域大的。第五章第五章 函数函数例例6: #includevoid func(int a) coutaendl; if(a=10) int a=5; couta=y) return x; else return y; 此函数定义所对应的函数原此函数定义所对应的函数原型为:型为: int max(int ,int );第五章第五章 函数函数 (二)作用:(二)作用: 函数原型为函数调用提供所需的接口信息。函数原型为函数调用提供所需的接口信息。 注:注: 1、若函数定义在函数调用之前,则函数原、若函数定义在函数调用之前,则函数原 型可要可不要。型可要可不要。 2、若函数定义在函数调用之后,则必须使若函数定义在函数调用之后,则必须使 用函数原型。用函数原型。第五章第五章 函数函数(三)必须使用函数原型的情况三)必须使用函数原型的情况 1、多文件程序、多文件程序 2、函数之间的递归调用。、函数之间的递归调用。 3、使用函数库。、使用函数库。第五章第五章 函数函数九、特殊的函数用法九、特殊的函数用法 (一)内联函数(一)内联函数 1、内联函数在定义或声明时在前面、内联函数在定义或声明时在前面 加上保留字加上保留字inline 例例8:inline int max(int a,int b) return (ab) ?a:b;第五章第五章 函数函数2、在遇到调用内联函数的地方,会用函、在遇到调用内联函数的地方,会用函数体中的数体中的 代码来替换函数的调用。代码来替换函数的调用。例例9:int maxinum=max(val1,val2); int maxinum=(val1val2)?val1:val2);第五章第五章 函数函数3、内联函数定义必须写在函数调用之前。、内联函数定义必须写在函数调用之前。4、内联函数的作用:、内联函数的作用: 保证程序的可读性。保证程序的可读性。 提高程序的运行效率。提高程序的运行效率。第五章第五章 函数函数5、使用内联函数的限制、使用内联函数的限制 在内联函数中不能定义任何静态变量。在内联函数中不能定义任何静态变量。 内联函数中不能有复杂的流程控制语句。内联函数中不能有复杂的流程控制语句。 内联函数不能是递归的。内联函数不能是递归的。 内联函数中不能说明数组。内联函数中不能说明数组。第五章第五章 函数函数(二)函数重载二)函数重载1、允许定义同名的函数。、允许定义同名的函数。2、函数重载的条件:、函数重载的条件: 重载的函数必须在形式参数的数量或重载的函数必须在形式参数的数量或 类型上与其它同名函数有所不同。类型上与其它同名函数有所不同。第五章第五章 函数函数例例10: long add(long a,long b) return a+b; long add(double a,double b) return a+b; long add(float a,float b) return a+b;第五章第五章 函数函数 3、两点注意、两点注意(1)重载函数的区分是以函数参数来进行)重载函数的区分是以函数参数来进行 的的,而不是用函数的返回值来区分不同而不是用函数的返回值来区分不同 的函数,所以参数表完全相同而返回值的函数,所以参数表完全相同而返回值 不同的两个同名函数不能重载。不同的两个同名函数不能重载。(2)不能让功能不同的函数进行重载。)不能让功能不同的函数进行重载。第五章第五章 函数函数(三)函数的默认参数三)函数的默认参数 1、定义:、定义: 函数的形式参数表中,若给若干函数的形式参数表中,若给若干 个形式参数规定了默认值,则称这些参个形式参数规定了默认值,则称这些参 数为默认参数,又称可选参数。数为默认参数,又称可选参数。例例11:int f(int a,char b,char c= z,int d=100); 其中其中: c, d为为默认参数默认参数第五章第五章 函数函数2、函数调用时,若不给出默认参数所对应的、函数调用时,若不给出默认参数所对应的 实在参数,则实在参数取默认值。实在参数,则实在参数取默认值。 例例12: f(3,a , b ) f(3,a , b ,100100) f(3,a ) f(3,a , z ,100100)第五章第五章 函数函数3、几点说明、几点说明(1)默认值的指定可以在函数原型或函数)默认值的指定可以在函数原型或函数 定义中进行。但是,如果一个文件中定义中进行。但是,如果一个文件中 既有函数原型,又有函数定义,则只既有函数原型,又有函数定义,则只 能在函数原型中指定参数的默认值。能在函数原型中指定参数的默认值。(2)如果函数有多个参数,则具有默认值)如果函数有多个参数,则具有默认值 的参数必须排在那些没有默认值的参的参数必须排在那些没有默认值的参 数的右边。数的右边。第五章第五章 函数函数(3)当有多个参数具有默认值时,调用函数所)当有多个参数具有默认值时,调用函数所 给的实在参数与形式参数匹配是按照从左给的实在参数与形式参数匹配是按照从左 到右的顺到右的顺 序进行的。序进行的。(4)函数的原型可以说明多次,也可以在各个)函数的原型可以说明多次,也可以在各个 函数原型中设置不同的参数具有默认值。函数原型中设置不同的参数具有默认值。 但是,在一个文件中,函数的同一参数只但是,在一个文件中,函数的同一参数只 能在一次声明能在一次声明 中指明默认值。中指明默认值。第五章第五章 函数函数4、若函数含有可选参数,则应保证在逐个、若函数含有可选参数,则应保证在逐个 去掉可选参数后,仍然在参数的个数或去掉可选参数后,仍然在参数的个数或 类型上与其它同名函数有所不同。类型上与其它同名函数有所不同。例例13:若有函数原型:若有函数原型:int fp(char c,int k=0,double d=100.0);则下列函数中可以重载的是(则下列函数中可以重载的是(A,D)A、int fp( ); B、 void fp(char c);C、int fp(char,int); D、void fp(char,int,int)第五章第五章 函数函数第五章第五章 函数函数(四)递归函数(四)递归函数1、递归函数:、递归函数: 函数直接或间接地调用其自身。函数直接或间接地调用其自身。例:求例:求n! long fact(int n) if (n=0) return 1; return (n*fact(n-1);第五章第五章 函数函数fact(4)n=44*fact(3)n=33*fact(2)n=22*fact(1)n=11*fact(0)126242、递归调用过程、递归调用过程第五章第五章 函数函数3、递归必须满足的条件、递归必须满足的条件(1)有明确的结束递归的条件。)有明确的结束递归的条件。(2)要解决的问题可以转化为相对简单)要解决的问题可以转化为相对简单 的同类型的问题。的同类型的问题。(3)随着问题的逐次转换,最终能达到)随着问题的逐次转换,最终能达到 结束递归的条件。结束递归的条件。第五章第五章 函数函数4、递归程序的优缺点、递归程序的优缺点优点:程序代码少,程序简捷,设计方便。优点:程序代码少,程序简捷,设计方便。缺点:代价大,消耗大量的运行栈空间,缺点:代价大,消耗大量的运行栈空间, 同时也花费很多的同时也花费很多的CPU时间。时间。第五章第五章 函数函数(五)函数模板五)函数模板1、作用:、作用:让具有类似功能而参数不同的函数使用让具有类似功能而参数不同的函数使用相同的名字,提高程序代码的可复用性。相同的名字,提高程序代码的可复用性。2、格式:、格式:template函数定义函数定义第五章第五章 函数函数例:例: int max(int x,int y) if(xy) return x; return y; float max(float x, float y) if(xy) return x; return y; long max(long x, long y) if(xy) return x; return y; double max(double x, double y) if(xy) return x; return y;第五章第五章 函数函数前面这四个函数对应的函数模板为:前面这四个函数对应的函数模板为: template Type max(Type d1,Type d2) if (d1d2) return d1; return d2; 注:注:表示表示Type这个符号可以这个符号可以 被任一种具体数据类型所取代。被任一种具体数据类型所取代。第五章第五章 函数函数3、模板的实例化、模板的实例化(1)含义)含义 用具体的数据类型来代替模板用具体的数据类型来代替模板 中的类型参数。中的类型参数。(2)方法)方法 通过函数调用通过函数调用 通过函数原型通过函数原型第五章第五章 函数函数(3 3)模板函数:)模板函数: 由模板实例化得到的函数由模板实例化得到的函数(4 4)重载模板函数:重载模板函数: 定义与模板函数同名的具体函数定义与模板函数同名的具体函数第五章第五章 函数函数例:例:#include #include template Type max(Type d1,Type d2) if (d1d2) return d1; else return d2; int max (int,int); char max(char,char); char*max(char*str1,char*str2);第五章第五章 函数函数void main( )int ival1=10,ival2=4; float fval1=12、3,fval2=45、67coutmax(ival1,iva2)endl;coutmax(fval1,fva2)endl;coutmax( a, A )endl;coutmax(” Hello”, ” Hello,world ”)0) return s1; else return s2;第五章第五章 函数函数4、支持多种类型的模板、支持多种类型的模板例:例:template T1 funcName(T1 para1,T2 para2) if (d1d2) return d1; else return d2; 第六章第六章 简单程序设计简单程序设计一、程序开发过程一、程序开发过程源文件源文件源文件源文件源文件源文件头文件头文件头文件头文件头文件头文件项目配置项目配置文件文件预预编译编译编译编译连接连接函数库函数库可可执行程序执行程序第六章第六章 简单程序设计简单程序设计二、文件间的信息共享二、文件间的信息共享1、外部变量、外部变量(1)含义)含义 若要在一个文件中使用在另一个文件若要在一个文件中使用在另一个文件 中定义的变量,则将其说明为外部变量中定义的变量,则将其说明为外部变量(2)说明格式)说明格式 在一般变量定义在一般变量定义前加前加extern第六章第六章 简单程序设计简单程序设计例:例:/文件文件main.cppint x;int y;void main( )/文件文件file1.cppextern int x;int y;void func1( )第六章第六章 简单程序设计简单程序设计(3)几点注意)几点注意:当一个文件中出现当一个文件中出现了了extern变量的说明变量的说明 时,时, 必须保证在组成同一程序的其他文必须保证在组成同一程序的其他文 件中有且只有一个对该变量的定义。件中有且只有一个对该变量的定义。如果在说明一个外部变量时加上了对变如果在说明一个外部变量时加上了对变 量的初始化,编译器会当成变量定义,量的初始化,编译器会当成变量定义, 而不当成变量说明来使用。而不当成变量说明来使用。 extern说明的变量必须具有全局作用域,说明的变量必须具有全局作用域, 不能是函数的局部变量不能是函数的局部变量第六章第六章 简单程序设计简单程序设计2、外部函数、外部函数(1)若要在一个文件中使用在另一个文件)若要在一个文件中使用在另一个文件 中定义的函数,则将其说明为外部函数中定义的函数,则将其说明为外部函数(2)说明格式)说明格式 直接说明其函数原型即可。直接说明其函数原型即可。第六章第六章 简单程序设计简单程序设计/文件文件main.cppvoid print(char*)void main( )print(” Hello,friendn”);/文件文件file1.cpp#includevoid print(char*str)coutstr;第六章第六章 简单程序设计简单程序设计3、静态全局变量与静态函数、静态全局变量与静态函数(1)静态全局变量:)静态全局变量: 在全局变量定义前加在全局变量定义前加static 例:例:static int i;(2)静态函数:静态函数: 在函数定义前加在函数定义前加static 例例: static int max(intx,int y)(3)特点:只能在定义它的文件中使用特点:只能在定义它的文件中使用第六章第六章 简单程序设计简单程序设计(4)优点:)优点: 可以将一些文件的实现细节封装起可以将一些文件的实现细节封装起 来来,这些实现细节没有必要让其它文这些实现细节没有必要让其它文 件了解。这样既安全,也简化了文件件了解。这样既安全,也简化了文件 之间的接口;之间的接口; 不同的文件可以使用同样名字的变不同的文件可以使用同样名字的变 量和函数完成文件功能,而不用担量和函数完成文件功能,而不用担 心名字冲突。心名字冲突。第六章第六章 简单程序设计简单程序设计(5)两点说明)两点说明 内联函数默认是静态的函数。所以内联函数默认是静态的函数。所以内联函数只在定义它的文件范围有效。内联函数只在定义它的文件范围有效。 用用const定义的常量默认也具有静态定义的常量默认也具有静态特性特性,因此可以在不同的文件中定义同名因此可以在不同的文件中定义同名的常量。的常量。第六章第六章 简单程序设计简单程序设计三、头文件三、头文件1、#include指令指令(1)含义:)含义: 告诉预编译程序,将其后面所跟的文件告诉预编译程序,将其后面所跟的文件 的内容插入到当前文件中的内容插入到当前文件中(2)格式:)格式:#include 文件名文件名/包含系统定义的头文件包含系统定义的头文件#include ”文件名文件名” /包含用户自定义的头文件包含用户自定义的头文件第六章第六章 简单程序设计简单程序设计2、头文件、头文件(1)含义:以为)含义:以为h为扩展名的文本文件为扩展名的文本文件(2)包含的内容:)包含的内容: 预编译指令预编译指令 函数声明函数声明 内联函数定义内联函数定义 类型定义类型定义 外部数据声明外部数据声明 常量定义常量定义 注释注释第六章第六章 简单程序设计简单程序设计(3)检验一个内容能否放在头文件的标准)检验一个内容能否放在头文件的标准 这个内容是否可能要被多个文件使用。这个内容是否可能要被多个文件使用。 如果多个文件包含这个头文件,是否如果多个文件包含这个头文件,是否 会引起冲突。会引起冲突。第六章第六章 简单程序设计简单程序设计3、预编译指令、预编译指令(1)条件编译指令)条件编译指令 #if #else #elif #endif #ifdef #ifndef 条件编译指令的一个有效使用是条件编译指令的一个有效使用是 协调多个头文件。协调多个头文件。(2)#define指令指令 #define指令通常用来与条件编译指令通常用来与条件编译 指令配套使用,定义一个符号常量,它指令配套使用,定义一个符号常量,它的定义与否可以用的定义与否可以用#ifdef 和和#ifndef来来测试。测试。第六章第六章 简单程序设计简单程序设计四、生存期四、生存期标识符在程序运行过程中生存的时间标识符在程序运行过程中生存的时间1、局部生存期、局部生存期(1)存在于函数的执行期间)存在于函数的执行期间(2)局部变量具有局部生存期)局部变量具有局部生存期2、静态生存期、静态生存期(1)存在于整个程序的运行期间)存在于整个程序的运行期间(2)全局变量具有静态生存期)全局变量具有静态生存期3、动态生存期、动态生存期(1)从申请到释放的期间)从申请到释放的期间(2)动态申请的空间具有动态生存期)动态申请的空间具有动态生存期第六章第六章 简单程序设计简单程序设计4、生存期与内存、生存期与内存(1)全局数据区存放具有静态生存期的变量)全局数据区存放具有静态生存期的变量(2)堆区存放具有动态生存期的变量)堆区存放具有动态生存期的变量(3)栈区存放具有局部生存期的变量)栈区存放具有局部生存期的变量5、初始化问题、初始化问题 具有静态生存期的变量将由系统自动具有静态生存期的变量将由系统自动 初始化为初始化为0,但不对具有局部生存期和,但不对具有局部生存期和 动态生存期的变量进行初始化。动态生存期的变量进行初始化。第六章第六章 简单程序设计简单程序设计例:例:#includeint i;void main( )int j;cout ” Global variable i=”iendl;cout ” Local variable j=”jendl;输出结果:输出结果:Global variable i=0Local variable j=-858993460第六章第六章 简单程序设计简单程序设计6、静态局部变量、静态局部变量(1)在一般局部变量的定义前加上)在一般局部变量的定义前加上static 例:例: int addCount( ) static int count; count+; return count; 第六章第六章 简单程序设计简单程序设计(2)特性:特性: 具有静态生存期。也就是说,它的生存具有静态生存期。也就是说,它的生存 期和整个程序的运行期是一样的,并且期和整个程序的运行期是一样的,并且 变量处于内存的全局数据区,而不在栈变量处于内存的全局数据区,而不在栈 区区;并且系统自动将其初始化为并且系统自动将其初始化为0; 只被初始化一次;只被初始化一次; 在函数退出以后,静态局部变量不被释在函数退出以后,静态局部变量不被释 放,它保留它的值。因此下一次进入函放,它保留它的值。因此下一次进入函 数后,静态局部变量还能保留它的值。数后,静态局部变量还能保留它的值。第六章第六章 简单程序设计简单程序设计 例:例: int addCount( ) static int count=100; count+; return count; 则则语句语句coutaddCount( ) addCount( );的输出结果为:的输出结果为:101 102第七章第七章 数组与结构数组与结构7、1 数组数组一、作用:一、作用: 用来描述一组具有相同数据类型的元素用来描述一组具有相同数据类型的元素第七章第七章 数组与结构数组与结构二、数组的定义格式二、数组的定义格式类型说明类型说明 数组名数组名常量表达式常量表达式;1、数组元素的类型可以是任意数据类型、数组元素的类型可以是任意数据类型2、常量表达式的值表示数组的元素个数、常量表达式的值表示数组的元素个数例:例:int grade15; int grade22*3;第七章第七章 数组与结构数组与结构三、数组元素的访问三、数组元素的访问1、数组元素通过下标进行访问、数组元素通过下标进行访问(1)下标是标识数组元素位置的整型下标是标识数组元素位置的整型 表达式表达式(2)若数组元素个数为若数组元素个数为n,则下标的值则下标的值 的范围是的范围是0n-1第七章第七章 数组与结构数组与结构2、访问数组元素的格式:、访问数组元素的格式:数组名数组名下标下标例:若定义数组例:若定义数组 int art5;则数组则数组art的五个的五个元素分别表示为:元素分别表示为:art0 、art1 、art2 、art3、 art4第七章第七章 数组与结构数组与结构例:从键盘读入例:从键盘读入100个学生的成绩,并记录到个学生的成绩,并记录到一个数组中。然后输出学生的平均成绩。一个数组中。然后输出学生的平均成绩。#includeconst int studentNum=100;void main( )float studentScorestudentNum;int i;for(i=0;i studentScorei;float sum=0;for(i=0;i studentNum;i+) sum+= studentScorei;cout ” the average score is”sum/ studentNum;第七章第七章 数组与结构数组与结构四、数组复制四、数组复制数组变量之间不能直接赋值,必须一个数组变量之间不能直接赋值,必须一个一个元素进行复制一个元素进行复制例:若有两个元素个数为例:若有两个元素个数为20的数组的数组A,B, 要将要将A赋值给赋值给B,则:则:B=A;()for(int i=0;i=最大字符串的最大字符串的长度长度+1第七章第七章 数组与结构数组与结构八、数组参数八、数组参数1、将整个数组定义作为形式参数,将数组、将整个数组定义作为形式参数,将数组名作为实在参数。名作为实在参数。若为一维数组,则元素个数可以省略若为一维数组,则元素个数可以省略若为二维数组,则行数可以省略若为二维数组,则行数可以省略第七章第七章 数组与结构数组与结构2、若以数组作为函数的参数,则对、若以数组作为函数的参数,则对 形参数组的改变就是对实参数组形参数组的改变就是对实参数组 的改变的改变第七章第七章 数组与结构数组与结构#includevoid f(int ar )ar0=1;ar1=1;void main( )int a2=0;couta0 a1endl;f(a);couta0 a1endl;输出结果:输出结果:0 01 1第七章第七章 数组与结构数组与结构7、2 结构结构一、结构的概念一、结构的概念 结构是用户自定义的数据类型,用来将结构是用户自定义的数据类型,用来将具有内在联系的一些信息组合成一个逻具有内在联系的一些信息组合成一个逻辑上具有整体含义的数据类型辑上具有整体含义的数据类型第七章第七章 数组与结构数组与结构二、结构类型的定义格式二、结构类型的定义格式Struct 结构类型名结构类型名成员定义成员定义1; 成员定义成员定义2; 成员定义成员定义n; ;注:一个成员相当于一个变量注:一个成员相当于一个变量第七章第七章 数组与结构数组与结构例:例:struct studentchar name20; char id7; float score; 定义了一个名定义了一个名为为student结构类型,其中结构类型,其中含有三个成员含有三个成员name、 id和和score第七章第七章 数组与结构数组与结构三、结构变量的定义三、结构变量的定义 定义了一个结构类型后,就可以用它来定义了一个结构类型后,就可以用它来定义结构变量。定义结构变量。格式:格式:结构类型名结构类型名 变量名表;变量名表;student s1,s2;/定义了两个简单的结构变量定义了两个简单的结构变量student s33;/定义了一个结构数组定义了一个结构数组第七章第七章 数组与结构数组与结构四、结构成员的访问四、结构成员的访问 要访问结构的成员,用圆点操作符,要访问结构的成员,用圆点操作符,这是一个双目操作符,它的左边的操作这是一个双目操作符,它的左边的操作数是结构类型的变量名,右边是结构的数是结构类型的变量名,右边是结构的成员名成员名如:如:s1 score s2 score s32 score第七章第七章 数组与结构数组与结构五、结构变量的初始化五、结构变量的初始化分别对结构变量中的各成员进行初始化分别对结构变量中的各成员进行初始化如:如:student s1=”wang ”, ” 12345 ”,93 student s23=” wang ”, ” 1234 ”,76,” zhang ”, ” 3333 ”,83,” li ”, ” 5678 ”,90;第七章第七章 数组与结构数组与结构六、结构的赋值六、结构的赋值只有同类型的结构变量才可以相互赋值只有同类型的结构变量才可以相互赋值如:如:student s1,s2;s1=s2;第七章第七章 数组与结构数组与结构七、结构成员的类型七、结构成员的类型1、可以是除自身以外的任何已有类型、可以是除自身以外的任何已有类型2、可以定义指向任何已有类型(包括、可以定义指向任何已有类型(包括 自身)的指针自身)的指针第七章第七章 数组与结构数组与结构例:例:struct Bchar ch; int x,y; double z;struct Eint d;B b;struct Fdouble data;F*next;第七章第七章 数组与结构数组与结构八、结构嵌套八、结构嵌套 可以在结构中定义并使用另一个结构。可以在结构中定义并使用另一个结构。 注:只有一个结构的使用范围只局限在另注:只有一个结构的使用范围只局限在另一个结构之内时,才会定义成结构嵌套,一个结构之内时,才会定义成结构嵌套,结构嵌套很少用。结构嵌套很少用。第七章第七章 数组与结构数组与结构例:例:struct Student struct Dateint year; int month; int day; char name20; Date birthday; float score; ; 结构结构Student中嵌套了结构中嵌套了结构Date,只有在结构只有在结构Student内部才可以使用结构内部才可以使用结构Date第八章第八章 指针和引用指针和引用8、1 指针的定义与初始化指针的定义与初始化一、指针:存储特定类型数据的地址。一、指针:存储特定类型数据的地址。二、指针定义与初始化的格式:二、指针定义与初始化的格式:类型修饰符类型修饰符 指针变量名指针变量名【=变量名变量名】如:如:int i; intip=&i; float score; floatpf=&score;第八章第八章 指针和引用指针和引用8、2 指针的间接访问指针的间接访问 指针的间接访问通过间接引用操作符指针的间接访问通过间接引用操作符 来实现。来实现。 是一个单目操作符。是一个单目操作符。 指针变量名指针变量名表示对指针所指的空间的引用。表示对指针所指的空间的引用。 如:如: int i; intip=&i; ip=5; /等价于等价于i=5; cout ip; /等价于等价于cout i;第八章第八章 指针和引用指针和引用注:注: ip:指针变量。指针变量。 ip:指针所指空间存放的内容指针所指空间存放的内容。5iip(ip=i)第八章第八章 指针和引用指针和引用8、3 指针的类型指针的类型一、指针的类型就是它所指的数据的类型。一、指针的类型就是它所指的数据的类型。 如:如:int i; intip=&i; / ip是一个整型指针是一个整型指针二、两种特殊的指针二、两种特殊的指针 1、NULL指针(空指针):不指向任何类型指针(空指针):不指向任何类型的数据。(用地址的数据。(用地址0表示)表示) 如:如:intip= NULL;第八章第八章 指针和引用指针和引用2、void指针:可以指向任何类型的数据。指针:可以指向任何类型的数据。注:注:使用使用void指针时,首先应将其强制转指针时,首先应将其强制转 换为具有某种具体的数据类型。换为具有某种具体的数据类型。例例:int a=20; void pv=&a; int ip=(int )pv; cout ip; cout (int )pv);第八章第八章 指针和引用指针和引用8、4 用用const来限定指针来限定指针一、指向常量的指针一、指向常量的指针1、定义:在指针定义前、定义:在指针定义前加加const。如:如: int i; const intip=&i;第八章第八章 指针和引用指针和引用2、含义:不能改变该指针所指的数据。、含义:不能改变该指针所指的数据。 如:如:int i; const intip=&i; ip=25;(;()第八章第八章 指针和引用指针和引用3、三点注意:、三点注意:(1)指向常量的指针只限制指针的间接)指向常量的指针只限制指针的间接 访问操作,而不会限制指针变量本访问操作,而不会限制指针变量本 身的操作。身的操作。如:如: int i,j; const intip=&i; ip=25;() ip=&j; ()第八章第八章 指针和引用指针和引用 (2)指向常量的指针只限制指针的间接)指向常量的指针只限制指针的间接 访问操作,而不会限制对指针所指访问操作,而不会限制对指针所指 空间的操作。空间的操作。 如:如:int i; const intip=&i; ip=25; ( ) i=25; ()第八章第八章 指针和引用指针和引用(3)如果要给一个指针赋一个常量的地)如果要给一个指针赋一个常量的地 址,则这个指针必须定义为指向常址,则这个指针必须定义为指向常 量的指针。量的指针。如:如:const int ci=30; const int ip1=&ci;() int ip2=&ci;()第八章第八章 指针和引用指针和引用二、指针常量二、指针常量1、定义:在指针变量名前加、定义:在指针变量名前加const。 如:如:int i; int const ip=&i;第八章第八章 指针和引用指针和引用2、含义:不能改变指针变量本身的值,、含义:不能改变指针变量本身的值, 但是可以改变指针所指的数据。但是可以改变指针所指的数据。 如如:int i,j; int const ip=&i; ip=&j;() ip=32;()第八章第八章 指针和引用指针和引用三、指向常量的指针常量三、指向常量的指针常量1、定义:在指针定义前和变量名前各加一、定义:在指针定义前和变量名前各加一 个个const。 如:如:int i; const int const ip=&i;第八章第八章 指针和引用指针和引用2、含义:既不能改变指针变量本身的值,、含义:既不能改变指针变量本身的值, 也不能改变指针所指的数据。也不能改变指针所指的数据。 如:如:int i,j; const int const ip=&i; ip=&j;() ip=32;()第八章第八章 指针和引用指针和引用8、5 指针与数组指针与数组一、一维数组的数组名是指向该数组首一、一维数组的数组名是指向该数组首 元素的指针。元素的指针。 如:如:int array5=10,20,30,40,50; 则:则:array=&array0;第八章第八章 指针和引用指针和引用二、指向数组的指针可以当作数组名使用。二、指向数组的指针可以当作数组名使用。 如:如:int array100; intpArray=array; 则则pArray为为指向一维数组的指针,此时指向一维数组的指针,此时访问数组访问数组中第中第i+1个个元素,下面两种方式元素,下面两种方式是等价的:是等价的: arrayi pArrayi第八章第八章 指针和引用指针和引用例:例:#includevoid main( )int array5; intpArray=array;for(int i=0;i5;i+)arrayi=i;coutpArrayi” ” arrayi endl;此程序的运行结果为:此程序的运行结果为:0 01 12 23 34 4第八章第八章 指针和引用指针和引用三、数组名是指针常量,而不是指针变量。三、数组名是指针常量,而不是指针变量。如:如: int array100;则:则:array=&array1;()四、指针的加减四、指针的加减1、指针加减的含义:、指针加减的含义:指针指针+1:指针向后移动一个数组元素。:指针向后移动一个数组元素。指针指针-1: 指针向前移动一个数组元素。指针向前移动一个数组元素。第八章第八章 指针和引用指针和引用如:如:int array5=10,20,30,40,50;int pa=array;102030405001234array pa pa+1 pa+2 pa+3 pa+4第八章第八章 指针和引用指针和引用2、指针的加减是以指针所指数据的类型、指针的加减是以指针所指数据的类型 大小为单位进行的。大小为单位进行的。 (例见(例见181页页182页)页)注:注:如果指针指向的是一个结构数组,如果指针指向的是一个结构数组, 则指针的运算就以一个结构元素则指针的运算就以一个结构元素 所占内存空间大小为单位。所占内存空间大小为单位。 (例见(例见182页)页)第八章第八章 指针和引用指针和引用五、用指针对数组进行操作五、用指针对数组进行操作 1、通过指针的加减来访问数组元素。、通过指针的加减来访问数组元素。 (例见(例见183页、页、184页)页)第八章第八章 指针和引用指针和引用2、访问数组、访问数组的第的第i+1个元素的四种方式:个元素的四种方式: 若有:若有:int array5=10,20,30,40,50; int pa=array; 则有:则有: pai arrayi (pa+i) (array+i)第八章第八章 指针和引用指针和引用3、取数组中第、取数组中第i+1个元素地址的四种方式个元素地址的四种方式 若有若有:int array5=10,20,30,40,50; int pa=array; 则有则有: pai arrayi pa+i array+i第八章第八章 指针和引用指针和引用4、在对指针进行加减运算时,必须保证、在对指针进行加减运算时,必须保证 经过运算得到的新地址是程序能够支经过运算得到的新地址是程序能够支 配的地址。配的地址。 若若有:有:int array10; int pa=array; 则:则: pa+20()第八章第八章 指针和引用指针和引用六、指针与字符串六、指针与字符串 1、字符串:以、字符串:以0 为结束符的字符序为结束符的字符序列。列。 2、可以将字符指针看成是一个字符串。、可以将字符指针看成是一个字符串。 如:如:charstr= ” a string”;astring0 str第八章第八章 指针和引用指针和引用3、输出字符指针将输出整个字符串。、输出字符指针将输出整个字符串。如如:charstr= ” a string”; coutstr; 输出:输出: a string4、输出对一个字符指针的间接引用时,输出对一个字符指针的间接引用时, 将会输出字符串的第一个字符。将会输出字符串的第一个字符。如:如:coutstr; 输出:输出: a第八章第八章 指针和引用指针和引用8、6 动态内存申请动态内存申请一一、new与与delete1、内存空间申请内存空间申请(1) new操作符:表示从堆内存中申请操作符:表示从堆内存中申请 一块空间。一块空间。(2)返回值:)返回值: 申请成功:返回所申请到的空间的首地址。申请成功:返回所申请到的空间的首地址。 申请失败:返回空指针(申请失败:返回空指针(NULL)。)。第八章第八章 指针和引用指针和引用(3) new的三种的三种格式:格式: new 数据类型数据类型 new 数据类型(初始化值)数据类型(初始化值) new 数据类型数据类型常量表达式常量表达式例:例:intip1=new int; intip2=new int(3); intstr=new int10;第八章第八章 指针和引用指针和引用2、内存空间释放、内存空间释放(1)delete操作符:表示将从堆内存中操作符:表示将从堆内存中 申请的一块空间返还给堆。申请的一块空间返还给堆。(2) delete的两种格式:的两种格式: delete 指针指针名名 delete 指针名指针名第八章第八章 指针和引用指针和引用例:例:intpInt=new int; floatpFloat=new float(34.5); intarr=new int100; delete pInt; delete pFloat; delete arr;第八章第八章 指针和引用指针和引用(3)几点说明:)几点说明:new与与delete需要配套使用:需要配套使用:new 数据类型数据类型 new 数据类型(初始化值)数据类型(初始化值)new 数据类型数据类型常量表达式常量表达式delete 指针名指针名delete 指针名指针名第八章第八章 指针和引用指针和引用 在在用用delete来来释放一个指针所指的空间时,释放一个指针所指的空间时,必须保证这个指针所指的空间是用必须保证这个指针所指的空间是用new申请申请的,并且只能释放这个空间一次。的,并且只能释放这个空间一次。 例例:int i; intip=&i; delete ip;() floatfp=new float(3.4); delete fp;() delete fp; ()第八章第八章 指针和引用指针和引用 如果在程序中用如果在程序中用new申请了空间,就申请了空间,就 应该在结束程序前释放所有申请的空间。应该在结束程序前释放所有申请的空间。 当一个指针没有指向合法的空间,或当一个指针没有指向合法的空间,或 者指针所指的内存已经释放以后,最者指针所指的内存已经释放以后,最 好将指针的值设好将指针的值设为为NULL。第八章第八章 指针和引用指针和引用二、指针与动态数组二、指针与动态数组1、若申请的是一个简单的数据空间,则、若申请的是一个简单的数据空间,则 可以通过间接访问操作符可以通过间接访问操作符*来访问来访问 intip=new int; ip=34; coutip;第八章第八章 指针和引用指针和引用2 、若申请的是一个数组空间,那么指向、若申请的是一个数组空间,那么指向 这个空间的指针就相当于一个数组名这个空间的指针就相当于一个数组名 intarr=new int100; for(int i=0;i100;i+) arri=i4;第八章第八章 指针和引用指针和引用3、指针数组、指针数组数组中的每个元素都是指针数组中的每个元素都是指针例例:charweek7=”Sunday ”, ” Monday ”, ” Tuesday ”, ” Wednesday ”, ” Thursday ”, ” Friday ”, ” Saturday ”;第八章第八章 指针和引用指针和引用三、指针与动态结构三、指针与动态结构1、利用指针访问结构成员、利用指针访问结构成员 (指针名)指针名).成员名成员名 指针名指针名成员成员名名第八章第八章 指针和引用指针和引用例例:struct Student char name20; float score;Student st=”wanglin ”,98;Studentps=&st; 则有:则有:ps name=(ps).name=st.name= ”wanglin ”ps score=(ps) .score=st.score=98;第八章第八章 指针和引用指针和引用2、链表、链表(1)链表是由若干个结点链接而成的)链表是由若干个结点链接而成的表头表头结点结点表尾表尾结点结点第八章第八章 指针和引用指针和引用(2)结点用结构类型来描述)结点用结构类型来描述 结点由数据成员和指针成员组成。数据结点由数据成员和指针成员组成。数据成员描述每一个结点的信息;指针成员成员描述每一个结点的信息;指针成员用来指向链表中的下一个结点。用来指向链表中的下一个结点。数据成员数据成员第八章第八章 指针和引用指针和引用例:例:struct StudentNodechar name20;float score;StudentNodenext;namescorenext第八章第八章 指针和引用指针和引用(3)表头指针)表头指针(head) 指向表头结点的指针指向表头结点的指针 若是一个空链表,则表头指针为若是一个空链表,则表头指针为 空指针空指针(NULL)第八章第八章 指针和引用指针和引用(4)链表的建立)链表的建立 链表的建立过程就是一个个创建链表结链表的建立过程就是一个个创建链表结点并将它们连接在一起的过程点并将它们连接在一起的过程第八章第八章 指针和引用指针和引用创建结点创建结点例:创建一个例:创建一个StudentNode类型的动态结点类型的动态结点StudentNodepNew;pNew=new StudentNode;strcpy(pNewname, ”wangtao ”);pNewscore=67;pNewnext=NULL;”wangtao ” 67第八章第八章 指针和引用指针和引用在链表的表尾结点后插入一个新结点在链表的表尾结点后插入一个新结点例:例: 将将pNew所指的结点插到链表的表尾所指的结点插到链表的表尾StudentNode*tail;tail=head;while(tail != NULL & tailnext != NULL)tail=tailnext;tailnext=pNew;第八章第八章 指针和引用指针和引用示意图如下:示意图如下: ”wusan ” 89 ”Lishi ” 88 ”wangtao ” 67head ”wusan ” 89 ”Lishi ” 88 ”wangtao ” 67head tailpNew插入前插入前插入后插入后tailpNew第八章第八章 指针和引用指针和引用(5)链表结点的删除)链表结点的删除如果被删除结点是链表的第一个结点,如果被删除结点是链表的第一个结点,那么删除这个结点后,链表的头指针需那么删除这个结点后,链表的头指针需要发生变化;要发生变化;如果被删除结点不是链表的第一个结点,如果被删除结点不是链表的第一个结点,那么删除这个结点后,将导致这个结点那么删除这个结点后,将导致这个结点的前一个结点的指针发生变化的前一个结点的指针发生变化第八章第八章 指针和引用指针和引用第一种情况示意图第一种情况示意图:12nheadpDel12npDelhead删除前删除前删除后删除后head=headnext;delete pDel;第八章第八章 指针和引用指针和引用第二种情况示意图:第二种情况示意图:1i-1ini+1headpDel1i-1ii+1nheadpDel删除前删除前删除后删除后prenext= pDelnext;delete pDel;prepre第八章第八章 指针和引用指针和引用 将两种情况结合,则从一个以将两种情况结合,则从一个以head为表头为表头指针的链表中删除一个结点的程序如下:指针的链表中删除一个结点的程序如下:if(head=pDel) head=headnext;else pre=head; while(pre!=NULL & prenext!=pDel) pre=prenext; prenext=pDelnext;delete pDel;第八章第八章 指针和引用指针和引用四、指针常用的场合四、指针常用的场合1、动态空间申请、动态空间申请2、构建复杂的数据结构、构建复杂的数据结构3、作为函数的参数、作为函数的参数4、字符串操作、字符串操作第八章第八章 指针和引用指针和引用8、7 引用的概念引用的概念一、引用的说明一、引用的说明1、引用:、引用: C+语言中对一个变量或常量标识符起语言中对一个变量或常量标识符起 的别名。的别名。第八章第八章 指针和引用指针和引用2、引用的说明:、引用的说明: 说明一个引用时,在引用标识符的前面说明一个引用时,在引用标识符的前面 加上加上&,后面跟上它所引用的标识符,后面跟上它所引用的标识符的名字。的名字。如如:int val; int &rval=val;/ rval是对是对val的的引用引用第八章第八章 指针和引用指针和引用3、引用说明时必须初始化、引用说明时必须初始化 引用不是变量,所以必须在说明引用时引用不是变量,所以必须在说明引用时说明它所引用的对象。所引用的对象必说明它所引用的对象。所引用的对象必须有对应的内存空间。须有对应的内存空间。第八章第八章 指针和引用指针和引用4、对引用的操作与对被引用对象所做的、对引用的操作与对被引用对象所做的 操作,效果完全一样操作,效果完全一样第八章第八章 指针和引用指针和引用例:例:#includevoid main( )int val; int &rval=val; cout ” &val=” &valendl; cout ” &rval=” &rvalendl; val=34; cout ” val=” val ” rval=” rvalendl; rval=12; cout ” val=” val ” rval=” rvalendl; 第八章第八章 指针和引用指针和引用程序的输出结果为程序的输出结果为&val=0X0065FDF4&rval=0X0065FDF4val=34 rval=34val=12 rval=12第八章第八章 指针和引用指针和引用二、引用的数据类型二、引用的数据类型1、能够被引用的数据类型、能够被引用的数据类型(1)对简单数据类型变量或常量的引用)对简单数据类型变量或常量的引用如如:int & char & float & double & bool &第八章第八章 指针和引用指针和引用(2)对结构类型变量或常量的引用)对结构类型变量或常量的引用如:如:struct Student char name20; float score; Student stud1=”WangLin ”,45.6; Student &rstud= stud1; cout rstud.name rstud.score;第八章第八章 指针和引用指针和引用(3)对指针变量或常量的引用)对指针变量或常量的引用如如:int pInt=new int; int&rpInt= pInt; rpInt=45.6; delete rpInt;第八章第八章 指针和引用指针和引用2、不能被引用的情况、不能被引用的情况(1)不能)不能对对void引用引用 因为因为void本身就表示没有数据类型,对它本身就表示没有数据类型,对它的引用没有意义的引用没有意义。第八章第八章 指针和引用指针和引用(2)不能对数组名引用)不能对数组名引用如如:int arr10; int& rarr1=arr;() int& rarr2=arr0;()第八章第八章 指针和引用指针和引用(3)不能定义指向引用的指针)不能定义指向引用的指针如如:int i; int& ri=i; int& pr=&ri;()注:注: int& 和和 int& 的区别:的区别:int&表示对表示对int型型指针的引用指针的引用int& 表示指向表示指向int型型引用的指针引用的指针第八章第八章 指针和引用指针和引用三、三、const引用引用1、在引用说明前、在引用说明前加加const。2、不能改变不能改变const引用的值,但是可以引用的值,但是可以 改变它所引用的对象的值。改变它所引用的对象的值。如如:int i; const int& ri=i; ri=45;() i=45; ()第八章第八章 指针和引用指针和引用3、对一个常量进行引用时,必须将这个、对一个常量进行引用时,必须将这个 引用定义引用定义为为const引用引用如如:const int ci=45; int& ri=ci;() const int& rci=ci;()第八章第八章 指针和引用指针和引用8、8 指针和引用指针和引用例:例:int i=10; intpi=&i;/ pi是指向是指向i的指针的指针 int&ri=i; / ri是对是对i的引用的引用第八章第八章 指针和引用指针和引用pi、 ri在内存的示意图如下在内存的示意图如下:100x0065FDE4 0x0065FDE40x0065FDE8i、ripi指针变量具有独立的内存空间存放变量的值,而引用只是指针变量具有独立的内存空间存放变量的值,而引用只是一个依附于被引用变量的符号,没有独立的内存空间一个依附于被引用变量的符号,没有独立的内存空间第八章第八章 指针和引用指针和引用一、指针和引用的不同点一、指针和引用的不同点1、指针和引用对它们所指的或引用的变、指针和引用对它们所指的或引用的变 量的操作方式不同量的操作方式不同 指针通过间接访问操作符指针通过间接访问操作符*来访问来访问如:如:pi=40; 引用直接访问它所引用的空间引用直接访问它所引用的空间如:如:ri=40;第八章第八章 指针和引用指针和引用2、可以改变指针的值;、可以改变指针的值;如如:int j; pi=&j;引用一旦被初始化后,就不能改变。所引用一旦被初始化后,就不能改变。所有对引用的操作都被认为是对它所引用有对引用的操作都被认为是对它所引用的变量的操作的变量的操作如:如:ri=j; /表示的不是表示的不是ri改为对改为对j的的引用,引用,而表示将而表示将j的值赋给的值赋给ri所所引用的变量引用的变量i /第八章第八章 指针和引用指针和引用二、指针和引用的共性二、指针和引用的共性 指针和引用都是对某一个变量所代表的指针和引用都是对某一个变量所代表的空间进行间接操作的手段空间进行间接操作的手段指针是通过存放变量空间的地址来达到指针是通过存放变量空间的地址来达到间接操作的目的间接操作的目的引用是通过为变量定义别名来达到间接引用是通过为变量定义别名来达到间接操作的目的操作的目的第八章第八章 指针和引用指针和引用8、9 引用的应用引用的应用 引用最大的用途是作为函数的参数或返引用最大的用途是作为函数的参数或返回值类型回值类型例:设计一个例:设计一个swap函数,交换两个数的值,函数,交换两个数的值,其其 中以引用作为参数中以引用作为参数第八章第八章 指针和引用指针和引用#includevoid swap(int&a,int&b)int temp=a; a=b; b=temp;void main( )int val1=10,val2=20; cout”val1= ” val1 ” val2= ”val2endl; swap(val1,val2); cout”val1= ” val1 ” val2= ”val2endl;第八章第八章 指针和引用指针和引用程序的输出结果:程序的输出结果:val1=10 val2= 20val1=20 val2= 10引用参数通常使用的场合:引用参数通常使用的场合:1、函数需要返回多个值、函数需要返回多个值2、函数的参数是结构或类的对象、函数的参数是结构或类的对象第九章第九章 面向对象程序方法面向对象程序方法9、1 面向对象方法概述面向对象方法概述一、面向对象的基本思想一、面向对象的基本思想 从现实世界中客观存在的事物(对象)从现实世界中客观存在的事物(对象)出发来构造系统,并在系统构造中尽可出发来构造系统,并在系统构造中尽可能地运用人类的自然思维方式。能地运用人类的自然思维方式。第九章第九章 面向对象程序方法面向对象程序方法二、以面向对象思想构造软件系统的主要二、以面向对象思想构造软件系统的主要 内容内容1、对象是以面向对象方法构造的系统的基、对象是以面向对象方法构造的系统的基 本单位。对象是对问题域中客观存在的本单位。对象是对问题域中客观存在的事物的抽象事物的抽象。第九章第九章 面向对象程序方法面向对象程序方法2、对象的属性和操作组成一个完整的对象,、对象的属性和操作组成一个完整的对象, 对象具有一定的对外接口,外界对象可以对象具有一定的对外接口,外界对象可以通过该接口来访问对象。通过该接口来访问对象。3、以对象为基础,对对象分类,将具有共同、以对象为基础,对对象分类,将具有共同特性的对象进行抽象,形成对这些对象的特性的对象进行抽象,形成对这些对象的抽象描述抽象描述类,每个对象就是该类的一类,每个对象就是该类的一个实例个实例。第九章第九章 面向对象程序方法面向对象程序方法4、对形成的对象类进一步抽象,抽出这些、对形成的对象类进一步抽象,抽出这些类的共同特征,形成基本的类和派生的类的共同特征,形成基本的类和派生的类,派生的类又可以具有更多的派生类,类,派生的类又可以具有更多的派生类,这样就形成一个类簇。基本类和派生类这样就形成一个类簇。基本类和派生类的关系称为继承的关系称为继承。第九章第九章 面向对象程序方法面向对象程序方法5、一个系统就是由各个对象组成,对象和、一个系统就是由各个对象组成,对象和 对象之间存在静态关系和动态关系。对象之间存在静态关系和动态关系。 静态关系体现了对象之间固有的关系;静态关系体现了对象之间固有的关系; 动态关系是对象之间通过发送消息进行动态关系是对象之间通过发送消息进行 通信,相互协作,完成系统功能通信,相互协作,完成系统功能。第九章第九章 面向对象程序方法面向对象程序方法三、面向对象方法三、面向对象方法 面向对象方法是利用抽象、封装等机制,面向对象方法是利用抽象、封装等机制,借助于对象、类、继承、消息传递等概借助于对象、类、继承、消息传递等概念进行软件系统构造的软件开发方法。念进行软件系统构造的软件开发方法。第九章第九章 面向对象程序方法面向对象程序方法四、面向对象方法的形成四、面向对象方法的形成1、面向对象程序设计语言的三阶段、面向对象程序设计语言的三阶段发生发生发展发展成熟成熟第九章第九章 面向对象程序方法面向对象程序方法2、Smalltalk语言语言 Smalltalk是是第一个完善的、实用的纯面第一个完善的、实用的纯面向对象的语言。它有三个特点:向对象的语言。它有三个特点:(1)将任何东西都看成对象,包括类本身。)将任何东西都看成对象,包括类本身。对对象的方法的调用在对对象的方法的调用在Smalltalk中中称为称为发送消息给对象发送消息给对象。第九章第九章 面向对象程序方法面向对象程序方法(2)不进行任何类型检查操作,强调多态)不进行任何类型检查操作,强调多态性和动态连接。性和动态连接。(3) Smalltalk不仅是一种语言,它还是不仅是一种语言,它还是一个具有类库支持和交互式图形拥护界一个具有类库支持和交互式图形拥护界面的完整的程序设计环境面的完整的程序设计环境。第九章第九章 面向对象程序方法面向对象程序方法3、面向对象程序设计语言的分类、面向对象程序设计语言的分类(1)纯粹的面向对象程序设计语言)纯粹的面向对象程序设计语言 完全依照面向对象思想而设计的,它的完全依照面向对象思想而设计的,它的所有语言成分都以对象为核心。所有语言成分都以对象为核心。 如:如:Smalltalk、Eiffel、Actor和和JAVA等等第九章第九章 面向对象程序方法面向对象程序方法(2)混合的面向对象程序设计语言)混合的面向对象程序设计语言 在某种已经被广泛使用的其他语言的基在某种已经被广泛使用的其他语言的基础上增加了支持面向对象思想的语言成础上增加了支持面向对象思想的语言成分。分。 如:如:Object C、C+、Object Pascal、和、和 CLOS等等第九章第九章 面向对象程序方法面向对象程序方法9、2 面向对象方法的基本概念面向对象方法的基本概念一、对象一、对象1、定义、定义 对象是对问题域中客观存在的事物的抽对象是对问题域中客观存在的事物的抽象,它是一组属性和在这些属性上的操象,它是一组属性和在这些属性上的操作的封作的封装体。装体。第九章第九章 面向对象程序方法面向对象程序方法2、两大要素、两大要素属性(用来描述对象的静态特征)属性(用来描述对象的静态特征)操作(用来描述对象的动态特征)操作(用来描述对象的动态特征)第九章第九章 面向对象程序方法面向对象程序方法3、程序设计语言中的对象、程序设计语言中的对象 在程序设计语言中,用类来定义对象。在程序设计语言中,用类来定义对象。 类是一种用户自定义的数据类型,这类是一种用户自定义的数据类型,这种数据类型是一个由数据和作用在这些种数据类型是一个由数据和作用在这些数据之上的操作组成的整体。数据之上的操作组成的整体。 对象相当于该类型的一个变量。对象相当于该类型的一个变量。第九章第九章 面向对象程序方法面向对象程序方法例:定义一个类及对象例:定义一个类及对象/定义一个电话类定义一个电话类class Phoneprivate:char owner10;char address50;char phoneNumber10;第九章第九章 面向对象程序方法面向对象程序方法public:Phone(charowner,charaddress,charphoneNumber);chargetPhoneNumber( );chargetOwner( );chargetAddress( );chardial(char*);/定义一个电话类对象定义一个电话类对象Phone myphone(”王萍王萍” , ”清华清华园园” ,”62782622 ” ););第九章第九章 面向对象程序方法面向对象程序方法二、消息二、消息1、定义、定义 消息是向对象发出的服务请求。是面向消息是向对象发出的服务请求。是面向对象系统中对象之间交互的途径。对象系统中对象之间交互的途径。第九章第九章 面向对象程序方法面向对象程序方法2、关键要素、关键要素消息的发送者消息的发送者消息的接收者消息的接收者消息所要求的具体服务消息所要求的具体服务消息所要求的具体服务的一些参数消息所要求的具体服务的一些参数消息的应答消息的应答第九章第九章 面向对象程序方法面向对象程序方法例:老板对下属说:例:老板对下属说:“明天早上八点以前明天早上八点以前把有关饮料的市场调查报告放到我的办把有关饮料的市场调查报告放到我的办公桌上公桌上”。第九章第九章 面向对象程序方法面向对象程序方法3、程序设计语言中的消息、程序设计语言中的消息 在程序设计语言中,消息表现为对象在在程序设计语言中,消息表现为对象在其操作过程中对另一个对象的服务程序其操作过程中对另一个对象的服务程序的调用,即函数调用。的调用,即函数调用。例:给电话类对象例:给电话类对象myphone发送一个消息:发送一个消息: 拨电话号码。则发送方式为:拨电话号码。则发送方式为: charmyphone.dial(”82904456 ”);第九章第九章 面向对象程序方法面向对象程序方法三、类三、类1、定义、定义 类是具有相同属性和操作的一组对象的类是具有相同属性和操作的一组对象的集合,它为属于该类的全部对象提供了集合,它为属于该类的全部对象提供了统一的抽象描述统一的抽象描述。第九章第九章 面向对象程序方法面向对象程序方法2、类与对象的关系、类与对象的关系 类给出了属于该类的全部对象的抽象定类给出了属于该类的全部对象的抽象定义,而对象则是符合这种定义的一个实义,而对象则是符合这种定义的一个实体。体。 因此,对象又称为是类的一个因此,对象又称为是类的一个“实例实例(instance) ” ,类又称为是对象的类又称为是对象的“模模板板 (template) ” 。第九章第九章 面向对象程序方法面向对象程序方法3、程序设计语言中的类、程序设计语言中的类 在程序设计语言中,类是一个独立的程在程序设计语言中,类是一个独立的程序单位,它具有一个类名来唯一标识这序单位,它具有一个类名来唯一标识这种类,类的定义体包括属性和操作两部种类,类的定义体包括属性和操作两部分。分。 程序设计语言中,类与对象的关系如同程序设计语言中,类与对象的关系如同数据类型和这种类型的变量。数据类型和这种类型的变量。第九章第九章 面向对象程序方法面向对象程序方法四、继承四、继承1、定义、定义 特殊类的对象拥有一般类的全部属性和特殊类的对象拥有一般类的全部属性和操作,称做特殊类对一般类的继承操作,称做特殊类对一般类的继承。第九章第九章 面向对象程序方法面向对象程序方法2、意义、意义 简化了人们对事物的认识和描述简化了人们对事物的认识和描述 增强了类接口的一致性,减少了模块增强了类接口的一致性,减少了模块间的接口和界面,从而大大增加了程序间的接口和界面,从而大大增加了程序的易维护性。的易维护性。第九章第九章 面向对象程序方法面向对象程序方法3、分类、分类单继承单继承 一个类从一个一般类的继承。一个类从一个一般类的继承。多继承多继承 一个类继承多个一般类的特性,然后再一个类继承多个一般类的特性,然后再在继承来的这些一般类的基础上增加自在继承来的这些一般类的基础上增加自己的特殊性。己的特殊性。第九章第九章 面向对象程序方法面向对象程序方法baseClassderivedBderivedAderivedCbaseClassBbaseClassA单继承单继承多多继承继承第九章第九章 面向对象程序方法面向对象程序方法4、基类和派生类、基类和派生类基类基类(base class)继承关系中的一般类称为基类。继承关系中的一般类称为基类。派生类派生类(derived class)继承关系中的特殊类称为派生类。继承关系中的特殊类称为派生类。第九章第九章 面向对象程序方法面向对象程序方法5、程序设计语言中的继承、程序设计语言中的继承 在程序设计语言中提供的继承方式是在在程序设计语言中提供的继承方式是在定义派生类时指定其所继承的基定义派生类时指定其所继承的基类。类。第九章第九章 面向对象程序方法面向对象程序方法例:例:class A ; class B:public A ; class C:public B ;类类A是类是类B的直接基类的直接基类,是类是类C的间接基类的间接基类类类B是类是类A的直接派生类的直接派生类,类类C是类是类A的间接派生的间接派生类类第九章第九章 面向对象程序方法面向对象程序方法五、封装五、封装1、两个含义、两个含义包装包装 把对象的全部属性和操作结合在一起,形成把对象的全部属性和操作结合在一起,形成一个不可分割的整体。一个不可分割的整体。信息隐藏信息隐藏 这个整体尽可能对外隐藏它的细节,只对外这个整体尽可能对外隐藏它的细节,只对外公布一个有限的界面,通过这个界面和其公布一个有限的界面,通过这个界面和其他对象交互。他对象交互。第九章第九章 面向对象程序方法面向对象程序方法2、封装和继承、封装和继承 封装和继承都可以看成是一种共享代码封装和继承都可以看成是一种共享代码的手段:的手段: 封装通过与其他对象的交互实现代码的封装通过与其他对象的交互实现代码的动态共享动态共享 继承通过派生类对基类的继承实现代码继承通过派生类对基类的继承实现代码的静态共享的静态共享第九章第九章 面向对象程序方法面向对象程序方法3、程序设计语言中的封装、程序设计语言中的封装 在程序设计语言中用类来实现封装。在程序设计语言中用类来实现封装。 类是属性和操作的结合体,并且在定义类是属性和操作的结合体,并且在定义类的属性和操作时,规定了它们的可见类的属性和操作时,规定了它们的可见性。只有公有成员才能被外界访问性。只有公有成员才能被外界访问。第九章第九章 面向对象程序方法面向对象程序方法六、多态性六、多态性1、定义、定义 多态性是指在基类中定义的属性或操作多态性是指在基类中定义的属性或操作被派生类继承之后,可以具有不同的数被派生类继承之后,可以具有不同的数据类型或表现出不同的行为,从而同一据类型或表现出不同的行为,从而同一个属性或操作名称在各个派生类中具有个属性或操作名称在各个派生类中具有不同的含义。不同的含义。第九章第九章 面向对象程序方法面向对象程序方法例:一个经理第二天要到某地参加某个会例:一个经理第二天要到某地参加某个会议,他会把这同一个消息告诉给不同的议,他会把这同一个消息告诉给不同的人:他的夫人、秘书、下属,这些人听人:他的夫人、秘书、下属,这些人听到这个消息后,会有不同的反应:夫人到这个消息后,会有不同的反应:夫人为他准备行装,秘书为他安排机票和住为他准备行装,秘书为他安排机票和住宿,下属为他准备相应的材料。宿,下属为他准备相应的材料。 这就是一种多态性:发给不同对象的同这就是一种多态性:发给不同对象的同一条消息会引起不同的结果一条消息会引起不同的结果。第九章第九章 面向对象程序方法面向对象程序方法2、程序设计语言中的多态性、程序设计语言中的多态性 (1)在程序设计语言中多态性表现为以)在程序设计语言中多态性表现为以统一的方式对待具有相同的接口的不同统一的方式对待具有相同的接口的不同类的实例的能力。类的实例的能力。 (2)C+语言支持两种多态性语言支持两种多态性编译时的多态性(通过函数重载实现)编译时的多态性(通过函数重载实现)运行时的多态性(通过虚函数实现)运行时的多态性(通过虚函数实现)第九章第九章 面向对象程序方法面向对象程序方法9、3 面向对象的意义面向对象的意义一、模块化一、模块化软件质量保证软件质量保证1、软件的外部质量、软件的外部质量(1)正确性)正确性 软件产品准确执行软件需求规格说明中软件产品准确执行软件需求规格说明中所规定的任务的能力。所规定的任务的能力。第九章第九章 面向对象程序方法面向对象程序方法(2)可靠性)可靠性 软件系统在异常情况下也能保证系统的软件系统在异常情况下也能保证系统的完整性的能力。完整性的能力。(3)可维护性)可维护性 软件产品在需求发生变化、运行环境发软件产品在需求发生变化、运行环境发生变化或发现软件产品本身的错误或不生变化或发现软件产品本身的错误或不足时进行相应软件更新所需工作量的大足时进行相应软件更新所需工作量的大小小。第九章第九章 面向对象程序方法面向对象程序方法(4)可复用性)可复用性 可复用性是指软件产品可被全部或部分可复用性是指软件产品可被全部或部分地再用到新的应用中去的能力。地再用到新的应用中去的能力。(5)兼容性)兼容性 兼容性是指软件产品与其他软件组合成兼容性是指软件产品与其他软件组合成一个整体的难易程度一个整体的难易程度。第九章第九章 面向对象程序方法面向对象程序方法2、软件的内部质量、软件的内部质量 软件的外部质量最终是由软件的内部质软件的外部质量最终是由软件的内部质量来支持。要得到外部质量好的软件,量来支持。要得到外部质量好的软件,软件的系统结构应该是模块化的。软件的系统结构应该是模块化的。第九章第九章 面向对象程序方法面向对象程序方法二、复用二、复用软件快速开发的必由之路软件快速开发的必由之路三、走面向对象式道路三、走面向对象式道路1、结构化程序设计、结构化程序设计(1)基本思想)基本思想 自顶向下、逐步求精自顶向下、逐步求精第九章第九章 面向对象程序方法面向对象程序方法(2)结构化程序设计的缺陷)结构化程序设计的缺陷结构化程序设计以功能分解作为基本思结构化程序设计以功能分解作为基本思路,而功能是系统中最易变的部分。路,而功能是系统中最易变的部分。结构化程序设计认为每个系统的主功能结构化程序设计认为每个系统的主功能都可以在最高层次上抽象出来进行恰当都可以在最高层次上抽象出来进行恰当 描述,而实际上大多数系统都无法简单描述,而实际上大多数系统都无法简单地用一个顶层功能来描述,也没法简单地用一个顶层功能来描述,也没法简单地用一个主程序来描述系统的操作流程地用一个主程序来描述系统的操作流程。第九章第九章 面向对象程序方法面向对象程序方法结构化程序设计是一种面向过程的设计结构化程序设计是一种面向过程的设计方法,它将数据和过程分开,降低了可方法,它将数据和过程分开,降低了可复用性和一致性。复用性和一致性。自顶向下的程序设计方法与复用思想本自顶向下的程序设计方法与复用思想本质上是背道而驰的。质上是背道而驰的。第九章第九章 面向对象程序方法面向对象程序方法2、面向对象程序设计、面向对象程序设计(1)本质)本质 把数据和处理数据的过程看成一个整体把数据和处理数据的过程看成一个整体对象。对象。(2)优点)优点面向对象方法比以前的各种方法更直接面向对象方法比以前的各种方法更直接地表示现实世界,从而使从需求分析到地表示现实世界,从而使从需求分析到系统设计的转换更加自然。系统设计的转换更加自然。第九章第九章 面向对象程序方法面向对象程序方法面向对象方法,尤其是它的继承性,是面向对象方法,尤其是它的继承性,是代码重用的有效途径。代码重用的有效途径。类封装了数据和操作,使得对象相对独类封装了数据和操作,使得对象相对独立,对象的内部实现也与对象的接口分立,对象的内部实现也与对象的接口分开,对象之间的关系只能通过消息传递开,对象之间的关系只能通过消息传递来体现,因而一个对象的修改对其他对来体现,因而一个对象的修改对其他对象的影响很少象的影响很少。第九章第九章 面向对象程序方法面向对象程序方法多多态性态性增强了操作的透明性、可理解性增强了操作的透明性、可理解性和可维护性,因为用户不必再为相同的和可维护性,因为用户不必再为相同的操作作用于不同的对象而去费心区分每操作作用于不同的对象而去费心区分每类对象类对象。第九章第九章 面向对象程序方法面向对象程序方法9、4 面向对象的分析与设计面向对象的分析与设计一、面向对象开发方法的生命周期一、面向对象开发方法的生命周期 1、分析、分析 分析阶段侧重于对问题域中存在的事物分析阶段侧重于对问题域中存在的事物的分析,从中抽象出类来,并根据问题的分析,从中抽象出类来,并根据问题域和系统职责确定类的结构、类的接口域和系统职责确定类的结构、类的接口和类之间的关系和类之间的关系。第九章第九章 面向对象程序方法面向对象程序方法 2、设计、设计 设计阶段在分析阶段的基础上,结合具设计阶段在分析阶段的基础上,结合具体的开发环境,做详细的设计,除了对体的开发环境,做详细的设计,除了对问题域中的类进一步细化外,还需要考问题域中的类进一步细化外,还需要考虑系统的人机交互、数据管理以及该系虑系统的人机交互、数据管理以及该系统和其他系统的交互等更多与实现相关统和其他系统的交互等更多与实现相关的内容的内容。第九章第九章 面向对象程序方法面向对象程序方法 3、实现、实现 实现是根据设计结果,用具体的语言在实现是根据设计结果,用具体的语言在具体的开发环境中进行编码。具体的开发环境中进行编码。第九章第九章 面向对象程序方法面向对象程序方法二、面向对象分析二、面向对象分析(OOA)1、两个步骤两个步骤问题域分析问题域分析 问题域分析的目的是标识基本概念,识别问题域分析的目的是标识基本概念,识别 问题域的特性,把这些概念集成到问题域问题域的特性,把这些概念集成到问题域 的模型中。的模型中。应用分析应用分析 应用分析是将问题域模型映射到具体的系应用分析是将问题域模型映射到具体的系 统需求中统需求中第九章第九章 面向对象程序方法面向对象程序方法2、面向对象分析的过程、面向对象分析的过程(1)发现对象,并对它们进行抽象与分)发现对象,并对它们进行抽象与分 类,得到对象的类类,得到对象的类(2)识别对象的内部特征,包括对象的)识别对象的内部特征,包括对象的 属性和操作属性和操作(3)识别对象的外部特征,包括对象类)识别对象的外部特征,包括对象类 之间的一般之间的一般特殊关系、对象的整特殊关系、对象的整 体体部分关系以及对象之间的实例部分关系以及对象之间的实例 连接和对象之间的消息连接连接和对象之间的消息连接第九章第九章 面向对象程序方法面向对象程序方法(4)借助于其他表示进一步分析系统,)借助于其他表示进一步分析系统, 如建立主题图、建立对象交互图、如建立主题图、建立对象交互图、 建立状态迁移图等建立状态迁移图等(5)对上面建立的所有表示进行详细)对上面建立的所有表示进行详细 的说明的说明(6)如果需要,开发原型系统,辅助)如果需要,开发原型系统,辅助 分析分析第九章第九章 面向对象程序方法面向对象程序方法三、面向对象设计的四个方面三、面向对象设计的四个方面(1)问题域)问题域 在设计阶段,因为考虑了与实现相关的在设计阶段,因为考虑了与实现相关的因素,在分析阶段得到的独立与实现的因素,在分析阶段得到的独立与实现的概念性的类将与具体的实现环境相结合概念性的类将与具体的实现环境相结合。第九章第九章 面向对象程序方法面向对象程序方法(2)人机交互)人机交互 人机交互包括系统的输入和输出两个人机交互包括系统的输入和输出两个 部分的设计。部分的设计。(3)数据管理)数据管理 数据管理必须考虑采用什么样的手段数据管理必须考虑采用什么样的手段 保存数据、如何实现数据与问题域对保存数据、如何实现数据与问题域对 象之间的接口等。象之间的接口等。(4)系统交互)系统交互 系统交互是指系统与用户、系统外的系统交互是指系统与用户、系统外的 其他系统及设备之间的交互其他系统及设备之间的交互第九章第九章 面向对象程序方法面向对象程序方法9、5 面向对象方法与软件复用面向对象方法与软件复用一、复用级别一、复用级别1、子程序的复用、子程序的复用2、源代码的复用、源代码的复用3、设计结果的复用、设计结果的复用4、分析结果的复用、分析结果的复用5、测试信息的复用、测试信息的复用第九章第九章 面向对象程序方法面向对象程序方法二、复用的好处二、复用的好处1、提高生产率,降低软件生产的代价、提高生产率,降低软件生产的代价2、提高软件质量、提高软件质量3、体现较多的一致、体现较多的一致性性第九章第九章 面向对象程序方法面向对象程序方法三、面向对象方法对复用的支持三、面向对象方法对复用的支持1、对象与类、对象与类 可复用构件应该具备一定的独立性、完可复用构件应该具备一定的独立性、完整性。而对象与类正具备构件的特性。整性。而对象与类正具备构件的特性。2、抽象、抽象 抽象意味着忽略事物的某些差异而抽取抽象意味着忽略事物的某些差异而抽取其共同特征。一个软件构件也有相同的其共同特征。一个软件构件也有相同的原则。原则。第九章第九章 面向对象程序方法面向对象程序方法3、封装、封装 封装原则把对象的属性和操作结合为一封装原则把对象的属性和操作结合为一个完整的实体,屏蔽了对象的内部实现个完整的实体,屏蔽了对象的内部实现细节,对外呈现一定的接口,这使得对细节,对外呈现一定的接口,这使得对象具有了独立性和完整性,从而具备了象具有了独立性和完整性,从而具备了可复用构件的基本特性。可复用构件的基本特性。第九章第九章 面向对象程序方法面向对象程序方法4、继承、继承 通过继承形成的对象类之间的一般通过继承形成的对象类之间的一般特殊特殊结构体现了不同层次的抽象,从而使用于结构体现了不同层次的抽象,从而使用于不同的复用范围。不同的复用范围。5、聚合、聚合 聚合是对象之间的包含关系。可以通过将聚合是对象之间的包含关系。可以通过将各个已实现的对象组织成一个新的对象来各个已实现的对象组织成一个新的对象来构造新对象,从而实现了各种已有对象的构造新对象,从而实现了各种已有对象的复用。复用。第九章第九章 面向对象程序方法面向对象程序方法四、复用技术对面向对象软件开发的支持四、复用技术对面向对象软件开发的支持 复用技术对面向对象软件开发的支复用技术对面向对象软件开发的支 持表现为类库支持。类库是实现对持表现为类库支持。类库是实现对 象类复用的基本条件。象类复用的基本条件。 在面向对象在面向对象 的编程语言的编程语言(OOPL)问世之后,问世之后, 已经开发了许多基于各种已经开发了许多基于各种OOPL的编的编 程类库,有利地支持了源程序级的软程类库,有利地支持了源程序级的软 件复用。件复用。 第九章第九章 面向对象程序方法面向对象程序方法9、6 面向对象程序设计语言(面向对象程序设计语言(OOPL) 面向对象程序设计语言与以往的各种语面向对象程序设计语言与以往的各种语言的根本不同是,它的出发点就是为了言的根本不同是,它的出发点就是为了能更直接地描述问题域中客观存在的事能更直接地描述问题域中客观存在的事物以及它们之间的关系。主要体现在以物以及它们之间的关系。主要体现在以下几点:下几点:第九章第九章 面向对象程序方法面向对象程序方法1、OOPL用对象来描述现实世界中的对用对象来描述现实世界中的对 象,用对象的属性和操作描述现实世象,用对象的属性和操作描述现实世 界中的对象的静态特性和动态特性。界中的对象的静态特性和动态特性。2、OOPL用类来描述具有共同特性的对用类来描述具有共同特性的对 象象 ,这和现实世界中的对对象分类非,这和现实世界中的对对象分类非 常相似。常相似。3、OOPL用类继承来表现现实世界中事物用类继承来表现现实世界中事物 的共性和个性,共性在父类中实现,个的共性和个性,共性在父类中实现,个 性在派生类中实现。性在派生类中实现。 第九章第九章 面向对象程序方法面向对象程序方法4、OOPL中对象可以由其他对象组成,中对象可以由其他对象组成, 这体现了现实世界中对象之间的构这体现了现实世界中对象之间的构 成关系。成关系。5、 OOPL中对象可以通过发送消息给中对象可以通过发送消息给 另一对象来使用该对象的服务,这另一对象来使用该对象的服务,这 体现了现实世界中事物彼此之间相体现了现实世界中事物彼此之间相 互依存的关系。互依存的关系。第九章第九章 面向对象程序方法面向对象程序方法6、 OOPL中提供对象的封装机制,这模拟中提供对象的封装机制,这模拟了现实世界中各个事物相对独立,一个了现实世界中各个事物相对独立,一个事物的很多细节其他事物不必要也不允事物的很多细节其他事物不必要也不允许知道的事实。许知道的事实。第第10章章 类与对象类与对象 10.1 类的定义与使用类的定义与使用一、类是数据和对这些数据进行操作的函一、类是数据和对这些数据进行操作的函数的封装体。数的封装体。二、定义格式:二、定义格式:class 类名类名类定义体类定义体;class Rectanglepublic: float width,height; float Area( )return width*height; float Perimeter( )return 2*(width+height);第第10章章 类与对象类与对象三、类对象的定义三、类对象的定义一个类的变量被称为对象。一个类的变量被称为对象。如:如:Rectangle rect;则:则: rect是类是类Rectangle的的一个对象。一个对象。 rect含有两个数据成员:含有两个数据成员: width和和height; 含有两个函数成员:含有两个函数成员: Area和和Perimeter。第第10章章 类与对象类与对象10.2 成员的访问控制成员的访问控制一、类成员的访问权限一、类成员的访问权限 pubilc:公用公用访问权限;访问权限;成员可以为任意函数所访问。成员可以为任意函数所访问。 private:私有私有访问权限;访问权限;成员只能为该类的成员函数所访问。成员只能为该类的成员函数所访问。 protected:保护保护访问权限;访问权限;成员只能为该类的成员函数以及该类的成员只能为该类的成员函数以及该类的派生类中的成员函数所访问。派生类中的成员函数所访问。第第10章章 类与对象类与对象例例1:class Rectanglepublic: float width,height; float Area( )return width*height; float Perimeter( )return 2*(width+height);Rectangle rect;rect.width=45;rect.height=54.2;coutrect.Area( );coutrect. Perimeter( );第第10章章 类与对象类与对象例例2:class Rectangleprivate: float width,height; public: float Area( )return width*height; float Perimeter( )return 2*(width+height);Rectangle rect;rect.width=45;()rect.height=54.2;()coutrect.Area( );coutrect. Perimeter( );第第10章章 类与对象类与对象class Rectangleprivate: float width,height; public: void SetWidth(float newWidth)width= newWidth; void SetHeight (float newHeigh)heigh= newHeigh; float Area( )return width*height; float Perimeter( )return 2*(width+height);可以通过公有的可以通过公有的函数成员来访问函数成员来访问私有成员。私有成员。如:如:Rectangle rect;则:则:rect. SetWidth(45);rect. SetHeight (54.2);第第10章章 类与对象类与对象二、确定成员访问权限的方法:二、确定成员访问权限的方法:1、类的数据成员一般不公开。、类的数据成员一般不公开。2、表示类的接口的函数成员一般定义为公有。、表示类的接口的函数成员一般定义为公有。3、表示类的实现的函数成员一般定义为保护、表示类的实现的函数成员一般定义为保护 的或私有的。的或私有的。第第10章章 类与对象类与对象10.3 类的成员函数(函数成员)类的成员函数(函数成员)一、定义位置一、定义位置1、定义在类内。、定义在类内。class Rectangleprivate: float width,height; public: float Area( )return width*height; float Perimeter( )return 2*(width+height);第第10章章 类与对象类与对象2、定义在类外。(在函数名前加、定义在类外。(在函数名前加类名类名 )class Rectangleprivate: float width,height; public: float Area( ); float Perimeter( );float Rectangle Area( )return width*height;float Rectangle Perimeter( )return 2*(width+height);第第10章章 类与对象类与对象二、类作用域二、类作用域1、类作用域范围、类作用域范围 一个类作用域的范围是这个类的定义体一个类作用域的范围是这个类的定义体和这个类的所有成员函数的定义体所构成和这个类的所有成员函数的定义体所构成的程序范围。的程序范围。第第10章章 类与对象类与对象2、成员函数的类作用域、成员函数的类作用域(1)开始于函数名,结束于函数定义体的结束。)开始于函数名,结束于函数定义体的结束。(2)函数的返回值类型不在类作用域中。)函数的返回值类型不在类作用域中。(3)函数的参数表在类作用域中。)函数的参数表在类作用域中。(4)若在类中定义了一个数据类型,则可以直)若在类中定义了一个数据类型,则可以直接在参数表中使用这个类型名,而不能在返回接在参数表中使用这个类型名,而不能在返回值中使用,如需使用,必须加上值中使用,如需使用,必须加上类名类名 。 (例见(例见P234)第第10章章 类与对象类与对象3、对象作用域、对象作用域 只有类的数据成员或函数成员才具有类只有类的数据成员或函数成员才具有类作用域。而对象的作用域是对象作为一作用域。而对象的作用域是对象作为一种变量,在程序中能够起作用的范围。种变量,在程序中能够起作用的范围。第第10章章 类与对象类与对象三、内联成员函数与非内联成员函数三、内联成员函数与非内联成员函数1、 内联成员函数:定义在类内。内联成员函数:定义在类内。 非内联成员函数:定义在类外。非内联成员函数:定义在类外。 (例见(例见P235)2、将非内联成员函数说明为内联成员函数将非内联成员函数说明为内联成员函数 的方法的方法(1)在类中函数原型前加)在类中函数原型前加inline。(2)在类外函数定义前加在类外函数定义前加inline。(。(例见例见P236)3、内联函数一般用于那些访问私有数据成员内联函数一般用于那些访问私有数据成员 的简单的小函数。(例见的简单的小函数。(例见P237)第第10章章 类与对象类与对象四、四、const成员函数成员函数1、定义格式定义格式在函数定义的参数表后面加上在函数定义的参数表后面加上const。2、特征特征const成员函数中不能对数据成员进行修改。成员函数中不能对数据成员进行修改。3、两点注意、两点注意一个一个const成员函数不能调用一个非成员函数不能调用一个非const 成员函数。成员函数。若一个若一个const成员函数在类外定义,则定义成员函数在类外定义,则定义 时也需加时也需加const。第第10章章 类与对象类与对象10.4 类定义与头文件类定义与头文件用多文件结构定义和使用类(例见用多文件结构定义和使用类(例见P240)多文件结构一般由多文件结构一般由3个文件组成个文件组成1、存放类定义的头文件。存放类定义的头文件。2、存放类成员函数外部定义的源程序文件。、存放类成员函数外部定义的源程序文件。3、使用类的主程序文件。、使用类的主程序文件。第第10章章 类与对象类与对象10.5 对象的创建与使用对象的创建与使用一、对象的创建(例见一、对象的创建(例见P245)全局对象(在函数外定义)全局对象(在函数外定义)局部对象(在函数内定义)局部对象(在函数内定义)动态对象(动态申请)动态对象(动态申请)二、对象作为函数的参数与返回值二、对象作为函数的参数与返回值(例见(例见P246)第第10章章 类与对象类与对象10.6 this指针指针this:指向调用成员函数的类对象的指针。指向调用成员函数的类对象的指针。 (类中成员函数的默认指针参数)(类中成员函数的默认指针参数) this:调用成员函数的类对象调用成员函数的类对象(例见(例见P237,P247-248)第第10章章 类与对象类与对象10.7 类与结构的关系类与结构的关系一、类与结构一般情况下可以相互替代一、类与结构一般情况下可以相互替代(没有默认的访问权限时)(例见(没有默认的访问权限时)(例见P250)二、类与结构的唯一区别:二、类与结构的唯一区别:结构成员默认的访问权限为结构成员默认的访问权限为public。类成员默认的访问权限为类成员默认的访问权限为private。(例见例见P251)第第11章章 构造函数与析构函数构造函数与析构函数11.1 构造函数与析构函数的意义构造函数与析构函数的意义一、定义一、定义构造函数:对类中的数据成员进行初始化;构造函数:对类中的数据成员进行初始化;在对象被创建时由系统自动调用。在对象被创建时由系统自动调用。析构函数:释放对象空间;析构函数:释放对象空间; 在对象被释放时由系统自动调用。在对象被释放时由系统自动调用。第第11章章 构造函数与析构函数构造函数与析构函数二、特性二、特性1、构造函数与析构函数都是类的成员函数。、构造函数与析构函数都是类的成员函数。2、构造函数的名字和类名相同;、构造函数的名字和类名相同; 析构函数的名字则由类名前加上符号析构函数的名字则由类名前加上符号。3、构造函数与析构函数都没有返回值类型。、构造函数与析构函数都没有返回值类型。4、构造函数与析构函数一般定义为类的公、构造函数与析构函数一般定义为类的公 有成员。有成员。(例见(例见P268-270)第第11章章 构造函数与析构函数构造函数与析构函数11.2 构造函数构造函数一、重载构造函数一、重载构造函数例:例:class Namepublic:Name( );Name(char*first);Name(char*first,char*last);Name name1;Name name2(”Yun ”);Name name3(”Yun ”,” Zhao ”);第第11章章 构造函数与析构函数构造函数与析构函数二、构造函数的默认参数二、构造函数的默认参数如:如:Name (char*first= ” default ”, char*last= ” default ”);三、默认构造函数三、默认构造函数1、默认构造函数是参数表为空或者所有参、默认构造函数是参数表为空或者所有参 数都有默认值的构造函数。数都有默认值的构造函数。2、使用场合、使用场合直接定义一个对象而没有初始化值。直接定义一个对象而没有初始化值。用用new动态申请的对象而没有初始化值。动态申请的对象而没有初始化值。定义了一个对象数组。定义了一个对象数组。第第11章章 构造函数与析构函数构造函数与析构函数3、两点注意、两点注意如果一个类没有定义构造函数,则系统将为如果一个类没有定义构造函数,则系统将为类自动生成一个默认构造函数。类自动生成一个默认构造函数。如果一个类定义了构造函数,则系统将不再如果一个类定义了构造函数,则系统将不再生成默认构造函数。生成默认构造函数。四、拷贝构造函数四、拷贝构造函数1、拷贝构造函数的参数为同类型对象的引用。、拷贝构造函数的参数为同类型对象的引用。第第11章章 构造函数与析构函数构造函数与析构函数2、作用、作用定义一个与已有对象完全相同的对象。定义一个与已有对象完全相同的对象。例:例:Name (Name&nm)strcpy(firstname,nm.firstname); strcpy(lastname,nm.lastname);若有若有Name name2(name1);则定义的则定义的name2是与是与对象对象name1完全相同的对象。完全相同的对象。第第11章章 构造函数与析构函数构造函数与析构函数五、成员初始化参数表五、成员初始化参数表1、作用、作用对类中的数据成员进行初始化。对类中的数据成员进行初始化。2、位置、位置放在构造函数的参数表与函数体之间。放在构造函数的参数表与函数体之间。3、定义格式、定义格式: 成员名成员名(初始化值初始化值), 成员名成员名(初始化值初始化值)第第11章章 构造函数与析构函数构造函数与析构函数4、引用成员的初始化、引用成员的初始化类的引用成员必须在成员初始化参数表中类的引用成员必须在成员初始化参数表中进行初始化。进行初始化。 例:例:class Aprivate:int mem;int& rmem=mem;()public:A( );A( ):rmem(mem)mem=0;第第11章章 构造函数与析构函数构造函数与析构函数5、对象成员的初始化、对象成员的初始化类的对象成员必须在成员初始化参数表中类的对象成员必须在成员初始化参数表中进行初始化。进行初始化。 例:例:class Studentprivate:Name studentName;int studentID;public:Student(char*name,int id);Student Student(char*name,int id):studentName(name), studentID(id) 第第11章章 构造函数与析构函数构造函数与析构函数注:如果对象成员所属的类没有默认构造函注:如果对象成员所属的类没有默认构造函数,则这个对象成员所在类的所有构造函数,则这个对象成员所在类的所有构造函数都必须在成员初始化参数表中给这个对数都必须在成员初始化参数表中给这个对象进行初始化。例:象进行初始化。例:class Aint mem;public:A(int a)mem=a;class BA a;public:B( ):a(3) ;B(int a1):a(a1) ;第第11章章 构造函数与析构函数构造函数与析构函数11.3 析构函数析构函数一、定义一、定义在对象的生命期结束时由系统自动调用的函数。在对象的生命期结束时由系统自动调用的函数。二、特点(例见二、特点(例见P289-291)1、析构函数的参数表为空;析构函数的参数表为空;2、析构函数没有返回值;、析构函数没有返回值;3、析构函数的名字是类名前加、析构函数的名字是类名前加;4、析构函数一般为公有成员函数;、析构函数一般为公有成员函数;5、析构函数不能重载。、析构函数不能重载。第第12章章 静态成员、友元静态成员、友元12.1 静态成员静态成员一、作用一、作用 一个类的静态数据成员是用来表示类的属性,一个类的静态数据成员是用来表示类的属性,而不是表示对象的属性。而不是表示对象的属性。二、定义二、定义在成员定义前加上在成员定义前加上static。如:如:class File public: static int fileCount; ;第第12章章 静态成员、友元静态成员、友元三、访问三、访问类的静态成员必须通过类名来访问。类的静态成员必须通过类名来访问。格式为:格式为:类名类名 静态成员名静态成员名如:如:File file1;coutfile1. fileCount;()coutFile fileCount;()第第12章章 静态成员、友元静态成员、友元四、静态数据成员与静态函数成员四、静态数据成员与静态函数成员1、类的静态成员也有三种访问控制:、类的静态成员也有三种访问控制: private、protected、public2、不能通过类名来直接访问类的私有静态数不能通过类名来直接访问类的私有静态数 据成员。据成员。3、可以通过静态成员函数来访问类的私有静、可以通过静态成员函数来访问类的私有静 态数据成员。态数据成员。第第12章章 静态成员、友元静态成员、友元例:例:class File private:static int fileCount; public:static int GetFileCount( )return fileCount; ;则有:则有: cout File fileCount; () cout File GetFileCount( );()第第12章章 静态成员、友元静态成员、友元4、静态成员函数只能访问类的静态数据成、静态成员函数只能访问类的静态数据成 员,不能访问类的非静态数据成员。员,不能访问类的非静态数据成员。5、非静态成员函数既可以访问类的静态数据、非静态成员函数既可以访问类的静态数据 成员,也可以访问类的非静态数据成员。成员,也可以访问类的非静态数据成员。五、静态数据成员的初始化五、静态数据成员的初始化 在所有函数的外部进行初始化;且在数据类在所有函数的外部进行初始化;且在数据类型后面加上类域标志。型后面加上类域标志。如:如:int File fileCount=0; 第第12章章 静态成员、友元静态成员、友元12.2 友元友元一、定义一、定义1、友元函数、友元函数若要将函数若要将函数f声明为一个类的友元函数,则声明为一个类的友元函数,则在类中的声明格式为:在类中的声明格式为:friend 函数函数f的原型的原型2、友元类、友元类若要将类若要将类A声明为类声明为类B的友元函数,则类的友元函数,则类A在在类类B中的声明格式为:中的声明格式为:friend class A;第第12章章 静态成员、友元静态成员、友元二、作用(例见二、作用(例见P307-309P307-309)一个类的友元函数或友元类可以直接访问一个类的友元函数或友元类可以直接访问该类的任何成员,包括私有成员和保护成员。该类的任何成员,包括私有成员和保护成员。三、使用场合三、使用场合1 1、一个函数需要经常而且大量地访问一个类、一个函数需要经常而且大量地访问一个类 的数据成员。的数据成员。2 2、一个类从属于另一个类,而且一般不单独、一个类从属于另一个类,而且一般不单独 使用,而是通过另一个类的对象来发挥作用。使用,而是通过另一个类的对象来发挥作用。3 3、运算符重载、运算符重载第第12章章 静态成员、友元静态成员、友元四、注意事项四、注意事项1、 friend 不是双向的。不是双向的。2、友元不是类的成员。、友元不是类的成员。3、除了一般的函数可以是友元函数外,一、除了一般的函数可以是友元函数外,一 个类的成员函数也可以成为另一个类的个类的成员函数也可以成为另一个类的 友元函数,此时的友元说明需要加上类友元函数,此时的友元说明需要加上类 域限定。(例见域限定。(例见P311)第第13章章 运算符重载运算符重载13.1 可以重载的运算符可以重载的运算符一、运算符重载:一、运算符重载: 对已有的运算符重新进行定义,赋予其另一种功能,对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。以适应不同的数据类型。二、运算符重载通过运算符重载函数来实现。二、运算符重载通过运算符重载函数来实现。1、运算符重载函数的定义格式、运算符重载函数的定义格式(1)单目运算符)单目运算符类型类型 operator单目运算符(参数)函数体单目运算符(参数)函数体(2)双目运算符)双目运算符类型类型 operator双目运算符(参数双目运算符(参数1,参数,参数2)函数体)函数体如如:A operator+(A&x) . A operator+(A&x,A&y) .第第13章章 运算符重载运算符重载2、运算符重载函数的调用格式运算符重载函数的调用格式(1)单目运算符)单目运算符 operator单目运算符(实参)单目运算符(实参) 单目运算符单目运算符 实参实参如:如: operator+(x) 或或 +x(2)双目运算符双目运算符 operator双目运算符(实参双目运算符(实参1,实参,实参2) 实参实参1 双目运算符双目运算符 实参实参2如:如: operator+(x,y) 或或 x+y第第13章章 运算符重载运算符重载13.2 运算符重载的规则运算符重载的规则一、运算符重载函数既可以作为某个类的成一、运算符重载函数既可以作为某个类的成 员函数,也可以作为一个独立的函数。员函数,也可以作为一个独立的函数。二、类的成员函数有一个隐含的参数二、类的成员函数有一个隐含的参数 this指针。指针。三、两个特例(三、两个特例(P317)四、六条规则(四、六条规则(P317-318)第第13章章 运算符重载运算符重载13.3 常用运算符重载常用运算符重载一、函数调用运算符的重载一、函数调用运算符的重载(必须定义为类的成员函数)(必须定义为类的成员函数)如:如: Matrix m; m.GetAt(i,j)=3 m(i,j)=3;二、赋值运算符的重载二、赋值运算符的重载1、系统会为类自动提供一个默认的赋值运算符。、系统会为类自动提供一个默认的赋值运算符。2、当类具有指针类型的数据成员时,需重新定、当类具有指针类型的数据成员时,需重新定 义赋值运算符。义赋值运算符。3、重载赋值运算符必须定义为类的成员函数。、重载赋值运算符必须定义为类的成员函数。第第13章章 运算符重载运算符重载三、双目算术运算符的重载(例见三、双目算术运算符的重载(例见P326)1、作为成员函数(只需定义一个形参)作为成员函数(只需定义一个形参)2、作为非成员函数(需要定义两个形参)作为非成员函数(需要定义两个形参)四、单目算术运算符的重载(例见四、单目算术运算符的重载(例见P327)1、作为成员函数(不带形参)作为成员函数(不带形参)2、作为非成员函数(需要定义一个形参)作为非成员函数(需要定义一个形参)五、自增自减运算符的重载(例见五、自增自减运算符的重载(例见P328)后缀自增自减运算符定义时带有一个整形参数,后缀自增自减运算符定义时带有一个整形参数,而前缀自增自减运算符定义时不带参数。而前缀自增自减运算符定义时不带参数。第第13章章 运算符重载运算符重载13.4 插入和抽取运算符的重载插入和抽取运算符的重载一、一、I/O流库流库1、流:表示信息从源到目的端的流动。、流:表示信息从源到目的端的流动。输入流:从中读取信息的流。输入流:从中读取信息的流。输出流:向其输出信息的流。输出流:向其输出信息的流。2、流类、流类输入流类:输入流类:istream输出流类:输出流类: ostream第第13章章 运算符重载运算符重载二、插入运算符的重载(例见二、插入运算符的重载(例见P340)三、抽取运算符的重载(例见三、抽取运算符的重载(例见P343)13.5 类型转换函数类型转换函数一、类型转换函数是一种特殊类型的成员函数。一、类型转换函数是一种特殊类型的成员函数。 可以自行定义从一个类对象向其他数据类可以自行定义从一个类对象向其他数据类 型数据的转换方式。型数据的转换方式。二、类型转换函数在类定义体中定义,二、类型转换函数在类定义体中定义,格式为:格式为:operator type( )函数体函数体类型转换函数没有返回值类型,而且参数表类型转换函数没有返回值类型,而且参数表为空。为空。 type是要转化的数据类型。是要转化的数据类型。如:如:operator int( )return val;第第13章章 运算符重载运算符重载三、隐式类型转换三、隐式类型转换由系统自动进行的类型转换。由系统自动进行的类型转换。四、显式类型转换四、显式类型转换1、明确指出应该转换的数据类型。、明确指出应该转换的数据类型。2、两种形式、两种形式在要转换的数据前加上要转换成的数据类型。在要转换的数据前加上要转换成的数据类型。函数调用形式函数调用形式如:如:si2=si1+(SmallInt)56; si2=si1+SmallInt(56);第第14章章 继承继承一、定义一、定义继承:在一个类的基础上构造一个新类。继承:在一个类的基础上构造一个新类。基类、派生类:如果类基类、派生类:如果类B是在类是在类A的基础的基础上构造的,那么上构造的,那么类类A称为基类(称为基类(base class);类;类B称为派生类称为派生类(derived class)。二、分类二、分类单继承单继承多继承多继承第第14章章 继承继承14.1 单继承(一个类只从一个基类派生)单继承(一个类只从一个基类派生)一、派生类的定义格式一、派生类的定义格式class Derived:Base Derived的成员定义的成员定义;二、两点说明二、两点说明1、基类所有的数据成员和函数成员都自动成、基类所有的数据成员和函数成员都自动成 为派生类的数据成员和函数成员。为派生类的数据成员和函数成员。2、一个类既可以是基类,也可以是派生类。、一个类既可以是基类,也可以是派生类。第第14章章 继承继承class Baseprivate: int i,j;public: void SetIJ(int,int); void Getij(int&,int&);类类Derived中有三个数据成员和四个函数成员。中有三个数据成员和四个函数成员。class Derived:Baseprivate:int k;public:void SetK(int);int GetK( );第第14章章 继承继承三、基类成员对派生类的可见性三、基类成员对派生类的可见性1、派生类的成员函数可以直接访问基类的、派生类的成员函数可以直接访问基类的 公有和保护成员。公有和保护成员。2、派生类的成员函数不能直接访问基类的、派生类的成员函数不能直接访问基类的 私有成员。(只能通过基类的公有或保私有成员。(只能通过基类的公有或保 护成员函数来进行访问)(例见护成员函数来进行访问)(例见P355)第第14章章 继承继承四、继承方式四、继承方式1、公有继承、公有继承(1)定义格式)定义格式class Derived : public Base Derived的成员定义的成员定义;(2)特性)特性对于公有继承,基类的所有成员的访问控制将对于公有继承,基类的所有成员的访问控制将 在派生类中保持不变。在派生类中保持不变。可以通过派生类的对象来访问基类的公有成员。可以通过派生类的对象来访问基类的公有成员。不能访问派生类、基类的保护和私有成员。不能访问派生类、基类的保护和私有成员。第第14章章 继承继承2、保护继承、保护继承(1)定义格式)定义格式class Derived :protected Base Derived的成员定义的成员定义;(2)特性)特性对于保护继承,基类的公有和保护成员在派生对于保护继承,基类的公有和保护成员在派生类中成为保护成员,而私有成员在派生类中不类中成为保护成员,而私有成员在派生类中不可访问。可访问。不能通过派生类对象直接访问基类的任何成员。不能通过派生类对象直接访问基类的任何成员。第第14章章 继承继承3、私有继承、私有继承(1)定义格式)定义格式class Derived :private Base/或或class Derived : Base Derived的成员定义的成员定义;(2)特性)特性对于私有继承,基类的公有和保护成员在派生类对于私有继承,基类的公有和保护成员在派生类中都成为私有成员,而私有成员在派生类中中都成为私有成员,而私有成员在派生类中 不可访问。不可访问。不能通过派生类对象直接访问基类的任何成员。不能通过派生类对象直接访问基类的任何成员。第第14章章 继承继承五、派生类对象的构造五、派生类对象的构造1、基类成员的构造、基类成员的构造 利用派生类的构造函数的成员初始化参数表利用派生类的构造函数的成员初始化参数表来将初始化信息传递给基类的构造函数。来将初始化信息传递给基类的构造函数。如:如:Derived Derived(int m1 ,int m2,int m3):Base(m1,m2)mem3=m3;或:或:Derived Derived(int m1 ,int m2,int m3):Base(m1,m2),mem3(m3) 注:若基类有默认构造函数,则实现派生类的注:若基类有默认构造函数,则实现派生类的构造函数时,可以不传递参数给基类的构造构造函数时,可以不传递参数给基类的构造函数。函数。第第14章章 继承继承2、构造函数与析构函数的执行顺序、构造函数与析构函数的执行顺序构造函数的执行顺序:构造函数的执行顺序: 先调用基类的构造函数;先调用基类的构造函数; 再调用对象成员的构造函数;再调用对象成员的构造函数; 最后调用派生类本身的构造函数。最后调用派生类本身的构造函数。析构函数的执行顺序:析构函数的执行顺序: 先调用派生类本身的析构函数;先调用派生类本身的析构函数; 再调用对象成员的析构函数;再调用对象成员的析构函数; 最后调用基类的析构函数;最后调用基类的析构函数;第第14章章 继承继承14.2 多继承(一个类从多个基类派生)多继承(一个类从多个基类派生)一、定义格式一、定义格式class 派生类名:访问控制符派生类名:访问控制符 基类名基类名,访问控,访问控制符制符 基类名基类名 派生类成员定义派生类成员定义;如:如:class Derived:public Base1,private Base2 第第14章章 继承继承二、构造函数与析构函数二、构造函数与析构函数1、在多继承中,派生类构造函数的定义和单继、在多继承中,派生类构造函数的定义和单继承类似。(在构造函数中,用成员初始化参数承类似。(在构造函数中,用成员初始化参数表来将初始化信息传递给基类的构造函数参数)表来将初始化信息传递给基类的构造函数参数)(例见(例见P374)2、构造函数的执行顺序:构造函数的执行顺序: 先依次调用各基类的构造函数;先依次调用各基类的构造函数; 再调用对象成员的构造函数;再调用对象成员的构造函数; 最后调用派生类本身的构造函数。最后调用派生类本身的构造函数。3、析构函数的执行顺序(与构造函数相反)、析构函数的执行顺序(与构造函数相反)第第14章章 继承继承三、二义性三、二义性1、当派生类中有和基类同名的成员时,派生、当派生类中有和基类同名的成员时,派生 类中的同名成员将会覆盖基类的成员。类中的同名成员将会覆盖基类的成员。 (例见(例见P376-377)2、要访问基类被覆盖的成员,可以通过在所要访问基类被覆盖的成员,可以通过在所 访问的成员名前加上所属的类域标志。访问的成员名前加上所属的类域标志。 (例见(例见P377-378)3、对于间接基类,必须指定所要访问的成员对于间接基类,必须指定所要访问的成员 是从哪条路径继承而来的。(例见是从哪条路径继承而来的。(例见P378)第第14章章 继承继承四、虚基类四、虚基类1、作用、作用 当基类通过多条派生路径为派生类继承时,当基类通过多条派生路径为派生类继承时,派生类只继承该基类一次,即派生类对象只派生类只继承该基类一次,即派生类对象只保存一份该基类的数据成员的值。保存一份该基类的数据成员的值。2、定义形式、定义形式在基类的访问控制前加上在基类的访问控制前加上virtual。第第14章章 继承继承3、初始化、初始化 虚基类构造函数的参数必须由最新派生出虚基类构造函数的参数必须由最新派生出来的类负责初始化。(例见来的类负责初始化。(例见P380)对于非虚基类,不允许在派生类的构造函对于非虚基类,不允许在派生类的构造函数中初始化间接基类;而对于虚基类,则数中初始化间接基类;而对于虚基类,则必须在派生类中对虚基类初始化。必须在派生类中对虚基类初始化。为保证虚基类在派生类中只继承一次,必为保证虚基类在派生类中只继承一次,必须在该基类的所有直接派生类中声明为虚须在该基类的所有直接派生类中声明为虚基类。基类。第第14章章 继承继承14.3 继承与类库继承与类库一、应用程序的四个部分一、应用程序的四个部分用户接口用户接口问题领域问题领域系统交互系统交互数据访问数据访问二、二、MFC(Visual C+的类库的类库)
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号