《C程序设计实验指导与题解课件.ppt》由会员分享,可在线阅读,更多相关《C程序设计实验指导与题解课件.ppt(382页珍藏版)》请在三一办公上搜索。
1、C+程序设计北京理工大学计算机科学技术学院赵清杰,2008.7,C+程序设计 清华大学出版社,2008,主要内容,第1章 C+语言概述 第2章 C+编程基础 第3章 函数与函数模板 第4章 类与类模板 第5章 运算符重载 第6章 继承与派生 第7章 多态 第8章 异常处理 第9章 C+标准库,第1章 C+语言概述,第1章 C+语言概述,本章简单介绍C+语言的特点以及C+标准库的主要构成。 列举一个简单的C+程序。程序的编辑、编译、连接与运行,并介绍Visual C+ 6.0开发环境下建立标准C+控制台应用程序的步骤。,第1章 C+语言概述,1.1 C+语言的特点1.2 C+标准库简介1.3 简
2、单的C+程序1.4 程序的编辑、编译、连接与运行1.5 小结,1.1 C+语言的特点,支持过程式程序设计 procedural programming支持基于对象的程序设计 object-based programming支持面向对象的程序设计 object-oriented programming支持泛型程序设计 generic programming,C+是一门支持多种编程方法的程序设计语言:,1.1 C+语言的特点,过程式程序设计通过一组算法建立问题的模型,程序的构成就是“算法+数据”。C+能够兼容C语言,但做了很多改进,例如对类型要求更加严格,输入输出更方便,增加了新的运算符,允许函数
3、和运算符重载,增加了引用类型,提供inline、const等关键字。总之,在支持过程式程序设计方面,比C语言更安全、功能更强、使用更方便。基于对象程序设计,主要特征是抽象和封装。它允许将数据和操作封装在一起,形成抽象数据类型,如类。把占据一块内存的类的实例称为该类型的对象。基于对象的程序设计就是建立对象和通过公有接口与对象联系的过程。,1.1 C+语言的特点,抽象、封装、继承与多态是面向对象程序设计的主要特征。在类与对象的基础上,C+通过继承和动态绑定机制扩展了抽象数据类型。通过从基类派生出子类,使用户无需修改原有的程序就可以重用已有的资源,并能够进一步修改或增添功能。动态绑定机制通过定义虚函
4、数,使处于不同类层次的同名函数,在程序运行时才被决定应该调用哪一个。泛型程序设计,将算法从特定的数据类型中抽象出来,使算法通用于不同的数据类型。泛型程序在代码重用、组织性、可维护性以及效率等方面表现出很强的优势。C+的模板语法机制,为范型程序设计奠定了关键基础。,第1章 C+语言概述,1.1 C+语言的特点1.2 C+标准库简介1.3 简单的C+程序1.4 程序的编辑、编译、连接与运行1.5 小结,1.2 C+标准库简介,C+标准库(Standard Library)定义了一些可供直接使用的函数、类、对象等。这些定义分别放在不同的头文件中,我们使用时只要包含相应的头文件即可。以前的C头文件和C
5、+头文件名都是以“.h”做后缀的,如和。新的C+标准头文件名不带后缀。以字母c开头的标准头文件(如)等价于原来的C头文件。标准头文件中定义的标识符(如类名、函数名、对象名)都归属于名字空间std,使用时要加前缀“std:”进行限制,或者使用using声明或using指令。C+标准库主要包括流类、string、容器类、使用容器的泛型算法、数值运算、C标准库、语言支持功能等。,1.2 C+标准库简介,图1-1 C+标准库构成,1.2 C+标准库简介,C+(语言)与Visual C+(C+的开发环境)我们要学习的是C+这门计算机语言的语法知识、编程方法以及如何使用C+标准库。不同企业的开发环境一般也
6、为用户提供一个基础类库,如Microsoft Visual C+的MFC(Microsoft Foundation Class Library),Borland C+ Builder的VCL(Visual Component Library)等。软件开发人员也可以编写自己的类库。本书我们只涉及C+标准库,而对不同的开发环境及其类库不做具体介绍。,第1章 C+语言概述,1.1 C+语言的特点1.2 C+标准库简介1.3 简单的C+程序1.4 程序的编辑、编译、连接与运行1.5 小结,1.3 简单的C+程序,/*/例1-1. 计算圆面积的C+程序/数据描述:半径和面积均为实数/数据处理:(a)从键
7、盘输入半径r;/(b)计算面积=r2;(c)向屏幕输出半径和面积/*,1.3 简单的C+程序,1.3 简单的C+程序,上述程序运行后,屏幕上显示:Please input radius:如果我们从键盘输入:3屏幕上将显示:radius = 3area = 28.2743,1.3 简单的C+程序,例1-2. 数据的输出# include using namespace std;int main() cout a number in decimal: dec 15endl; cout in octal: oct 15 endl; cout in hex: hex 15 endl; cout a f
8、loating-point number: 3.14159endl; cout a char: A endl; return 0;,第1章 C+语言概述,1.1 C+语言的特点1.2 C+标准库简介1.3 简单的C+程序1.4 程序的编辑、编译、连接与运行1.5 小结,编辑:源文件的扩展名为.cpp编译预处理过程编译过程词法分析:单词语法分析:构造程序的格式符号表:程序中的各种符号及它们的属性错误处理程序:生成目标代码:目标文件的扩展名为.obj连接:可执行文件扩展名为.exe运行,1.4 程序的编辑、编译、连接与运行,源程序.cpp,目标文件.obj,可执行文件.exe,编译器,连接器,#i
9、nclude文件,C+库文件,1.4 程序的编辑、编译、连接与运行,1.4 程序的编辑、编译、连接与运行,C+编程环境:,Windows平台下C+的集成开发环境:Visual C+6.0Visual S Borland C+ BuilderLinux下可以采用命令行开发C+程序vi 编辑源文件gcc 编译源文件,1.4 程序的编辑、编译、连接与运行,启动Visual C+6.0开发环境;创建一个新项目;建立C+源程序文件;编辑C+源程序文件内容;编译,连接,调试,执行;关闭工作空间。,Visual C+ 6.0开发环境下,建立标准C+控制台应用程序的步骤:,第1章 C+语言概述,1.1 C+语
10、言的特点1.2 C+标准库简介1.3 简单的C+程序1.4 程序的编辑、编译、连接与运行1.5 小结,1.5 小结,C+是一门支持多种编程方法的程序设计语言,它不仅支持过程式程序设计,还支持基于对象的程序设计、面向对象的程序设计以及泛型程序设计。熟悉并学会使用C+标准库。至少熟悉一种C+开发环境。,第2章 C+编程基础,第2章 C+编程基础,介绍C+语言的基本概念和基本语法,内容包括C+的词法规则、数据类型、表达式及语句、预处理命令、名字空间等,并通过例子说明相应的语法知识,在此基础上使大家能够编写出简单的C+程序。,第2章 C+编程基础,2.1 C+的词法规则2.2 C+的数据类型2.3 表
11、达式与语句2.4 预处理命令2.5 名字空间2.6 小结,2.1.1 C+的字符集,大小写的英文字母:az,AZ 数字字符:09 特殊字符:,2.1 C+的词法规则,2.1.1 C+的字符集,基本ASCII码是美国标准信息交换码,把128个字符与7位二进制数码对应。C+把字符和它的码值同等看待,字符对应的数值就是该字符的ASCII码。 参见例2-1。,2.1 C+的词法规则,2.1.2 词汇,关键字是C+预定义的单词,表达特定的含义,不允许重定义。 C+关键字参见表2-2。,2.1 C+的词法规则,C+的词汇包括关键字、标识符、运算符、分隔符、文字等。,2.1.2 词汇,标识符是程序员声明的单
12、词,例如函数名、类名、对象名等。要求:1)以字母或者下划线开始;2)由字母、数字或者下划线组成。其中区分大/小写,且不能使用预定义的关键字。 如_mybook、MyBook、My_book2是合法的,而2a、x+y、new非法。,2.1 C+的词法规则,2.1.2 词汇,运算符是指实现各种运算的符号,如+、-、*、/等。 在C+中,运算符是预定义的函数的名字,这些函数对参与运算的数值进行规定的运算,得到一个结果值。,2.1 C+的词法规则,2.1.2 词汇,分隔符用于分割各个单词或者程序正文。如:空格、制表(Tab键产生的字符)、换行、逗号、冒号、分号、圆括号、花括号、注释符等。文字在程序中直
13、接表示常量值,包括数字、字符、字符串和布尔文字。,2.1 C+的词法规则,第2章 C+编程基础,2.1 C+的词法规则2.2 C+的数据类型2.3 表达式与语句2.4 预处理命令2.5 名字空间2.6 小结,基本数据类型是C+预定义的数据类型,或称为内置数据类型:布尔型(bool)、字符型(char)、整型(int)、浮点型(float, double)、空类型(void)。可用signed、unsigned修饰字符型和整型,long可用来修饰整型和双精度浮点型,short可以修饰整型。用户自定义数据类型:在基本数据类型或者已定义的数据类型基础上,用户根据自己的需要,构造出的新类型。如:枚举、
14、联合、结构、类等。将数据与操作数据的算法(函数)封装在一起所建立的类型,又被称作抽象数据类型,在C+中通常指类类型。在已定义的数据类型基础上,结合某些修饰符(如、*、&、())或者关键字(如const),可以得到扩展数据类型,如数组、指针、引用等。,2.2 C+的数据类型,布尔型(bool),或逻辑型,占用1个字节,其值只能是真(true)或假(false)两种情况,一般用“1”表示true,用“0”表示false。字符型(char),表示单个ASCII字符或者相应的整数值,占用1个字节。在内存中以ASCII码值的形式存储。整型(int),修饰符short、long、signed、unsign
15、ed。浮点型(float, double),即实数,单精度、双精度和长双精度。空类型(void),表示函数无返回值、或者指针所指对象的类型不明确。,2.2.1 基本数据类型,基本数据类型所占用的内存情况参见表2-3。可以通过运算符sizeof,测试在自己的机器环境下某种数据类型或对象所占用的内存大小。如 sizeof(float); 参见例2-2。,2.2.1 基本数据类型,常量:在程序运行过程中,其值不可改变。包括:文字常量、宏定义的符号常量、const常量等。变量:在程序运行过程中,其值可以改变。,2.2.2 常量与变量,布尔文字,true,false整型文字,例如,-1000L表示长整数
16、,1000UL表示无符号长整数,U和L不分前后。八进制表示0767L ,十六进制表示0 x76fL等。浮点型文字,12.5,.65F, 2.5E-3,1e+5F,.28E12L 字符文字,(1)A,4;(2)用八进制或十六进制的ASCII码值表示:如A又可以表示为101,或者x41;(3)如n表示换行符,参见表2-4。字符串文字,a,book ,以字符 0结尾。因此,字符 a 占一个字节,而字符串a占两个字节。,1. 文字常量,2.2.2 常量与变量,变量(或对象)一般具有名称(通过new创建的对象没有名称)、类型、数值、地址这四个要素。定义变量时,系统会在内存中为该变量分配一块连续区域,变量
17、的地址就是该区域的首地址。C语言中习惯使用“变量”这个术语。C+中的对象,强调的是分配好的、具体的一块内存区域,并且具有唯一的地址。每个对象都与一个特定的数据类型相关联,这个类型决定了相关内存的大小、布局、能够存储在该区域的值的范围以及可以对该区域进行哪些操作等。数据类型不仅包括基本数据类型,更重要的是抽象数据类型。,2. 变量与对象,2.2.2 常量与变量,C+规定,标识符(如对象名、类名、函数名等)在使用之前要先进行声明或定义。声明是告诉编译器“这个标识符在某处进行了定义”。定义是说“在这里建立对象、函数等”,并分配相应的存储空间。大多数情况下对象声明也就是定义,只有对全局对象进行exte
18、rn声明时例外。 float f1, f2, f3, f4; float f = 2.5; 或者 float f(2.5); 类对象通过调用构造函数进行初始化。,2. 变量与对象对象的声明和定义,2.2.2 常量与变量,作用域指标识符在程序正文中的有效范围,例如函数域、类域、名字空间域、文件域(编译单元内有效,一个包含内嵌头文件内容的完整.cpp文件就是一个编译单元)等。一对花括号之间的代码构成一个程序块,在程序块内定义的对象是局部对象,局部对象的作用域从对象的定义点开始,到程序块结束为止。函数(包括主函数)内部定义的对象都是局部对象。可见性讨论的是标识符能否被使用。在具有包含关系的局部作用域
19、中,同名的内层对象将屏蔽外层对象。这时外层对象的标识符是不可见的。在同一作用域中不能对同一个标识符多次定义。,2. 变量与对象标识符的作用域和可见性,2.2.2 常量与变量,2. 变量与对象标识符的作用域和可见性,2.2.2 常量与变量,在函数、类等之外定义的对象,默认情况下的作用范围具有全局性,即在整个程序运行期间起作用,所以称之为全局对象。在局部作用域内,同名的局部对象将屏蔽全局对象。如果想在局部作用域内使用全局对象,则应利用作用域运算符“:” 。参见例2-4 。如果一个程序包含多个编译单元,那么在一个编译单元中定义的全局对象,不仅在该编译单元可用,在其他编译单元也可以使用,但要先进行ex
20、tern声明。参见例2-5 。对于包含多个编译单元的程序,如果想使全局对象只在定义它的编译单元中起作用,则可以在定义时声明它为static。参见例2-6 。,2. 变量与对象标识符的作用域和可见性,2.2.2 常量与变量,程序中的对象,一般在需要时被创建,不需要时则从内存中删除。在创建和删除之间所经历的时间称为对象的生存期。一般,局部对象的生存期与它的作用域同在,全局对象的生存期与程序的整个执行过程同在。如果想使一个对象在整个程序执行过程中都存在,同时又不希望像全局对象那样存在安全隐患,这时可声明static局部对象。声明静态局部对象时,一般要进行初始化。参见例2-7 。,2. 变量与对象对象
21、的生存期,2.2.2 常量与变量,一般局部对象的作用域从对象的定义点开始,到它所在的程序块结束为止;生存期与作用域同在。静态局部对象的作用域与一般局部对象相同;生存期与整个程序同在。一般全局对象在程序的任意地方都可以使用;生存期与整个程序同在。静态全局对象具有文件作用域;生存期与整个程序同在。用new建立的堆对象,其作用域和生存期由用户确定。,关于作用作用域与生存期的总结:,2.2.2 常量与变量,定义对象时,auto、register、static、extern是影响对象存储类型的几个关键字。存储区域类型:(1) 静态存储区,全局对象、静态对象和函数一般存储于该区域,存储区在程序开始执行之前
22、分配,在程序的整个运行期间都存在。(2) 栈区(stack),程序执行期间进行内存分配。一般局部变量存于栈区。(3) 堆区(heap),也称为动态存储区。程序运行时用new申请内存,由程序员负责何时用delete释放内存。不同存储类型的对象,被分配在不同的内存区域参见例2-8 。,2. 变量与对象对象的存储,2.2.2 常量与变量,在C+标准化之前,当需要用符号表示常量时,常用#define宏命令来定义,例如: #define PI 3.14159标准C+中用const定义常量,与定义变量的语法类似,只是在前面多了一个关键字const。 const double pi = 3.14159;常量
23、必须进行初始化,而且常量的值不能改变。全局const量,默认具有文件作用域,这一点与一般全局对象不同。如果想使一个const在整个程序可用,那么定义时就要带extern声明。,3. 常量,2.2.2 常量与变量,volatile的语法与const类似。关键字const告诉编译器“不要改变我”,而关键字volatile则告诉编译器“我可能会改变”。当编译器不进行优化时,volatile不起作用;但当优化代码时,用该关键字则可以防止出现错误。,4. volatile,2.2.2 常量与变量,在基本数据类型基础上,用户可以根据需要构造出新的数据类型,如枚举、联合、结构、类等,这些都可以称为自定义数据
24、类型。一旦定义了一种新的数据类型,我们就可以使用这种新类型。,2.2.3 自定义数据类型,枚举类型是若干个有名字的整型常量的集合,如: enum Shape CIRCLE=10, SQUARE=0, RECTANGLE=10;花括号内的标识符是枚举常量,多个枚举常量之间用逗号分隔;枚举常量的类型为Shape,具有整数值,可用来初始化或更新Shape类型的对象。如: Shape sh = SQUARE; /对象sh初值为SQUARE sh = RECTANGLE; /sh值改为RECTANGLE,2.2.3 自定义数据类型,1. 枚举,枚举常量的值,最前边的一个默认为为0,其后的值依次加1;枚举
25、常量的值也可显式定义,未显式定义的则在前一个值的基础上加1,如下面BLACK值为0,GREEN值为1,RED值为5,YELLOW值为6: enum Color BLACK, GREEN, BLUE = 4, RED, YELLOW,2.2.3 自定义数据类型,1. 枚举,2.2.3 自定义数据类型,2. 联合,联合类型对象的每个成员都存储在同一位置,最大存储空间的需要量由需要存储空间最大的成员决定。,sizeof (A. a) = 4 sizeof (A. b) = 8 sizeof (A) = 8,union UnionX int a;double b; ;UnionX A; /A为对象,2
26、.2.3 自定义数据类型,3. 结构,结构类型由其他类型的数据成员组成,如可以把学生的学号、姓名、年龄、成绩等放在一起,定义一种结构类型。,sizeof (A. a) = 4 sizeof (A. b) = 8 sizeof (A) = 12,struct StructX int a;double b; ;StructX A; /A为对象,2.2.3 自定义数据类型,4. 类,在上面的结构类型中,我们把不同类型的数据封装在一起。那么对于使用这些数据的算法(一般通过函数实现),我们是否也能封装到一起?通过关键字class,可以定义一种新的数据类型,即类,例如:,2.2.3 自定义数据类型,4.
27、类,class ClassX/定义ClassX类类型public:/下面的成员是公有的/成员函数SetData()void SetData(int r1, int r2) a=r1; b=r2; private:/下面的成员是私有的int a, b;/声明int型数据成员a和b;/注意分号不能少! ClassX A; /声明一个对象,2.2.3 自定义数据类型,4. 类,struct类型中也可以封装成员函数。在C+中,struct类型与class类型的区别是:默认情况下class中的成员具有private访问属性,而struct中的成员具有public访问属性。可以把枚举enum、联合unio
28、n和结构struct看作是类class的特殊情况。,2.2.3 自定义数据类型,5. 类模板,为了减少程序员的重复劳动,对于功能相同而成员类型不同的类,C+允许声明一个通用的类模板。通过类模板可以生成不同的类。第4章介绍类模板的定义与使用。C+标准库为我们定义了很多可供直接使用的类(模板),如string、pair、complex、valarray、流类、容器类、迭代器等,使用时只要包含相应的头文件即可。,在基本数据类型或者自定义数据类型基础上,结合运用修饰符(如、*、&、())或者关键字(如const),可以得到扩展数据类型,如数组、指针、引用等。,2.2.4 扩展数据类型,2.2.4 扩展
29、数据类型,1. 数组,数组是数目固定、类型相同的若干个对象的有序集合,这些对象称为数组的元素。数组定义形式: 类型 数组名维1维2 = 初值表,初值表; int a5 = 2, 1, 3, 5, 6; int b23 = 1, 0, 2, 3, 6, 5 ; ClassX obj223;,2.2.4 扩展数据类型,1. 数组,数组元素的各维下标都从0开始;数组名对应数组的起始地址,是常量;而数组元素一般是变量;各元素在内存中按下标的升序连续存放,如: int a3; /a0, a1, a2 int b22; /b00,b01,b10,b11 b0表示含2个元素b00、b01的一维数组,b1表示
30、含2个元素b10、b11的一维数组数组a的元素个数:sizeof(a) / sizeof(a0),2.2.4 扩展数据类型,1. 数组,使用数组时,不能对数组名进行直接拷贝和比较。如果想把一个数组拷贝到另一个中去,可以采用拷贝每个元素的方法。参见例2-11。C+没有提供对数组元素下标进行范围检查的手段。采用C+标准库中的容器vector,可以生成类似数组的对象,且能够进行拷贝、自动调整大小等。参见例2-12。,2.2.4 扩展数据类型,2. 指针,指针是指能够存放对象地址的对象。一个类型为T*的指针能够保存T类型对象的地址。指针本身也是一个对象,占据一定的内存空间,具有自己的名字、值和地址。不
31、同的是,指针的值是所指对象的地址,因此我们常说某指针“指向”某个对象。,例如:int a=102;int* pa=,内存,1000H,102,.,a,1000H,2000H,pa,2.2.4 扩展数据类型,2. 指针,可以通过指针修改它所指向的对象的值。如: *pa = 100; /通过pa修改a的值也可以定义指向类对象的指针,例如: ClassX obj; ClassX* p = 虽然在声明指针时可以不进行初始化,但这样的指针是悬空的,使用时容易出现错误。因此应该养成定义时进行初始化的习惯。,2.2.4 扩展数据类型,指针与数组,在C+程序中,数组名对应数组的起始地址,数组名和指针名经常可以
32、互换使用。参见例2-13。 但是,数组和指针是不同的。数组名所指内存区的地址和容量在数组生命期内是不变的。可用sizeof(数组名)算出数组所占的字节数。而指针一般是变量,可以指向类型匹配的任意对象(即不同的内存区)。我们无法知道指针所指内存区的大小。如用sizeof(指针名),得到的是指针本身所占的字节数,而不是所指内存的字节数。也可以定义元素为指针的数组,称为指针数组: double f1 = 1.8, f2 = 2.8; double* p2 = ,2.2.4 扩展数据类型,指向常量的指针与常量型指针,定义指针时,如用关键字const修饰所指对象的数据类型,这时的指针就称为指向常量的指针
33、。指向常量的指针可以保存变量或者常量的地址,并且限制指针的访问方式为“只读”,即不能通过指针修改所指对象的值。int v1 = 3; /变量v1const int max = 100;/常量max,初始化!const int* p1 = /错误!,2.2.4 扩展数据类型,指向常量的指针与常量型指针,定义指针时,如果在指针名前加关键字const修饰,则该指针是常量型指针。常量型指针必须进行初始化,然后指针的值不再改变,即指针的指向不变。但如果常量型指针所指的是变量,则可以通过该指针修改所指变量的值。int v1=10, v2=20; /两变量const int max = 100;/常量max
34、int* const pv1 = /错误!,2.2.4 扩展数据类型,指向常量的指针与常量型指针,定义指针时,如果对数据类型和指针名都用了关键字const修饰,则这样的指针称为指向常量的常量型指针。这意味着定义之后,指针的值和所指对象的值都不能改变。int v1=10, v2=20; /两个变量const int max = 100;/常量maxconst int* const pv1 = /错误!,2.2.4 扩展数据类型,3. 引用,引用可以理解为对象的别名,其声明形式如下:数据类型声明引用时必须进行初始化,初值一般必须是对象名; const引用也可用常量或表达式的值初始化。引用一旦被初始
35、化,就不能再指代其他对象。不过一个对象可以有多个引用。,2.2.4 扩展数据类型,引用和指针的区别,指针用来保存对象的地址,引用相当于对象的别名;声明指针时要分配内存(引用型除外),而声明引用时不分配内存;声明引用时必须初始化,声明指针时可以不初始化;指针可作数组元素,引用不能作数组元素;可以有指向void型的指针,而没有void型引用;可以声明指针的引用,而没有指向引用的指针。int m1=0, m2=5;int* p1 = /错误!,2.2.4 扩展数据类型,4. 字符串,字符串是若干有效字符的序列。字符串常量由双引号括起来,如 x+y=10。字符串可以放在一个字符数组中,结束位置用符号
36、0 表示。定义字符数组时,可以逐个字符初始化,也可以用一个字符串常量初始化。例如:char str1 = x, +, y, =, 1, 0, 0;char str2 = x+y=10;/数组含7个元素,2.2.4 扩展数据类型,4. 字符串,可以通过指向字符的指针管理字符串,例如: char str1 = x, +, y, =, 1, 0, 0; char* cp = str1; /cp保存字符串str1的起始地址对字符指针可以用字符串常量初始化,但不能以数组元素形式初始化,因为cp只存放一个地址值。例如: char* cp1 = x+y=10;/cp1保存串的起始地址 char* cp2 =
37、 x, +, y, =, 1, 0, 0; /错误!定义字符串时,最好使用标准库中的类string,该类封装了字符串的基本特性和各种典型操作,如赋值、连接、比较、查找等。参见例2-14 。,2.2.5 类型转换,在程序编译或者程序运行时,有时需要将一种数据类型转换成另一种类型。类型转换可分为隐式转换和显式转换两大类。其中隐式转换由编译器自动完成,无需编程者介入。一般在运算、函数参数传递及函数值返回时,如果出现数据类型不一致并可以进行自动类型转换时,就会发生隐式转换。显式转换一般要通过类型转换运算符强制实现类型转换,因此也称为强制转换。,2.2.5 类型转换,隐式转换由编译器自动完成,运算规则是
38、从低类型向高类型提升。从高类型向低类型转换会给出警告。int a = 3.541 + 3; /结果a的值为6C+可以将某种指针类型(指向非const型)自动转换成void*型,反过来则不行。int a=0;int* p1 = /错误!const int* 不能隐式转换成 void*,1. 隐式转换,2.2.5 类型转换,可以通过强制类型转换运算符实现类型的显式转换: int a = 1; double b = 3.1415; a = (int)b; /C风格的显式转换 a = int(b); /早期C+风格的显式转换 标准C+显式转换方式: static_cast(Expr) const_ca
39、st(Expr) dynamic_cast(Expr) reinterpret_cast(Expr),2. 显式转换,2.2.5 类型转换,转换构造函数可以将某种类型的对象转换成当前类类型。 类型转换函数可以将当前类型的对象转换成指定的类型。,用户定义的转换,2.2.6 typedef与typeid,typedef可以为某种数据类型声明一个新名字。使用运算符typeid可以得到一个对象的数据类型。参见例2-15,第2章 C+编程基础,2.1 C+的词法规则2.2 C+的数据类型2.3 表达式与语句2.4 预处理命令2.5 名字空间2.6 小结,2.3 表达式与语句,表达式由运算符和操作数组成,
40、按一定求值规则我们可以求出表达式的值;其中操作数可以是常量、变量或另一个表达式。C+简单语句:表达式;程序由语句组成。,2.3 表达式与语句,2.3.1 运算符与表达式算术运算符与表达式关系运算符与表达式逻辑运算符与表达式位运算符与表达式三元条件运算符与表达式逗号运算符与表达式动态内存分配与释放运算符2.3.2 语句简单语句,复合语句,控制语句(选择语句、循环语句、跳转语句),判断表达式的使用,2.3.1 运算符与表达式,根据功能,运算符可分为算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符及特殊运算符。根据所需操作数的个数,运算符可分为一元运算符、二元运算符和三元运算符。一元运算符只
41、需要一个操作数,二元运算符需要两个操作数,三元运算符则需要三个操作数,C+只有一个三元运算符即“?:”。一个表达式可以包含多个运算符,运算顺序由各运算符的优先级和结合性决定。C+运算符的功能和优先级参见表2-5。,2.3.1 运算符与表达式,算术表达式由算术运算符和操作数组成,结果是算术值,值的类型与操作数的类型有关。普通算术运算符:一元算术运算符:-(取负)、+(取正);二元算术运算符:+、-、*、/、%(int型);一元运算符优先级高于二元运算符;+和减-运算符一元运算符,操作数必须是变量,分前缀和后缀;优先级较高,结合性自右向左。,1. 算术运算符与表达式,2.3.1 运算符与表达式,前
42、缀“+”可以理解为“先增1后使用”,而前缀“”可以理解为“先减1后使用”。后缀“+”可以理解为“先使用后增1”,后缀“”可以理解为“先使用后减1”。 int a1=1, c1=0; c1 = +a1;/a1=a1+1; c1=a1; int a2=1, c2=0; c2 = a2+;/c2=a2; a2=a2+1;,前缀方式与后缀方式的区别:,2.3.1 运算符与表达式,关系表达式由关系运算符和操作数组成,用来对两个操作数进行比较,结果为bool类型的值。如果关系为真,则结果为true;如果关系为假,则结果为false。关系运算符包括:等于(=),不等于(!=),小于(),大于等于(=)。后四
43、种的优先级高于前两种。例如:设a=1, b=2,则表达式(ab)的值为false,表达式(a2)的值为true。,2. 关系运算符与表达式,2.3.1 运算符与表达式,逻辑表达式由逻辑运算符和操作数组成,结果为bool类型的值。逻辑运算符包括:逻辑或(|)、逻辑与(&)和逻辑非(!)。“逻辑或”表示当两个操作数只要其中一个为真,结果就为true;“逻辑与”表示当两个操作数都为真时,结果才为true;“逻辑非”表示取操作数的逻辑相反值。参见表2-6。,3. 逻辑运算符与表达式,2.3.1 运算符与表达式,位运算表达式由位运算符和操作数组成,可以对整型数按二进制位进行操作。位运算符包括:按位或(|
44、),按位异或(),按位与( /b=00010000,4. 位运算符与表达式,2.3.1 运算符与表达式,赋值表达式由赋值运算符与操作数组成,作用是将等号右边表达式的值赋给等号左边的对象,表达式值的类型与左边对象的类型一致。是二元运算符,结合性自右至左,优先级仅高于逗号运算符。简单赋值(=),复合赋值(+=、-=、*=、/=、%=、 /等价于a=a+3,5. 赋值运算符与表达式,2.3.1 运算符与表达式,C+唯一的一个三元运算符是“?:”,具有简单的选择功能,其格式为: a1 ? a2 : a3其中a1具有bool类型,a2和a3可以是任何类型,表达式的类型取决于a2和a3中类型高的一个。上式
45、的运算过程是,若a1为true则表达式值为a2的值,否则表达式值为a3的值。例如求a和b中较大的值,并将该值赋给c,结果c的值为5: int a=3, b=5, c=0; c = ( ab ) ? a : b;,6. 三元条件运算符与表达式,2.3.1 运算符与表达式,逗号也是一个运算符,作用是将多个表达式连成一个表达式。计算时从左至右计算每一个表达式的值,逗号表达式的值与最后一个表达式的值相同。例如: a = 2*3, a*5; /表达式相当于(a = 2*3), a*5上述表达式中,逗号前面赋值表达式的值为6,a*5的值为30,则逗号表达式的值为30。逗号运算符的优先级最低,使用较少。,7
46、. 逗号运算符与表达式,2.3.1 运算符与表达式,new运算符建立动态对象,并分配内存空间;delete运算符删除动态对象,即释放内存空间。 new和delete必须配对使用。由new创建的堆对象没有名字,只能通过地址进行访问,这一点与普通对象不同。例如: int* p1 = new int; int* p2 = new int(10); int* p3 = new int10;delete p1;delete p2;delete p3;,8. 动态内存分配与释放运算符,2.3.2 语句,简单语句:空语句,定义语句,表达式语句复合语句:多个简单语句用一对花括号括住。控制语句:可以改变程序的流
47、程。包括选择语句(if-else,switch)循环语句(while,do-while,for)跳转语句(break,continue,goto),2.3.2 语句,常用选择语句包括if-else 语句和switch语句。if-else 语句的两种形式(应用参见例2-16):,1. 选择语句,2.3.2 语句,if-else语句嵌套使用可以实现多路分支,但比较繁琐,而用switch语句比较简单。语法:,1. 选择语句,switch (表达式)case常量表达式1: 语句1; break; case常量表达式2: 语句2; break;case常量表达式n: 语句n; break;default
48、: 语句n+1; ,2.3.2 语句,C+中可使用三种循环语句:while循环、do-while循环和for循环。while循环:while (表达式)循环体参见例2-17,2. 循环语句,2.3.2 语句,do-while循环:do循环体while (表达式);,2. 循环语句,2.3.2 语句,for循环: for ( 表达式1; 表达式2; 表达式3 )循环体参见例2-18。,2. 循环语句,2.3.2 语句,跳转语句包括break语句、continue语句和goto语句。由于goto语句存在较大的安全隐患,尽量不用。break语句可用于switch和循环结构中,作用是退出switch或
49、循环体。continue语句一般只能用于循环结构中,作用是结束本次循环,进入下一次循环。参见例2-19。,3. 跳转语句,2.3.2 语句,在C+中,当表达式值为非0,被认为是true;只有当表达式的值等于0时,才认为是false。利用C+表达式的灵活性,可以简化代码。如果表达式expr的值为布尔型、整型、指针值等,与0比较时都可以采用下列方式:expr 相当于expression != 0 !expr相当于expression = 0if( a-b ) 相当于 if( (a-b) != 0 )while( p & !q ) 相当于 while( p != 0 & q = 0 ),4. 判断表
50、达式的使用,2.3.2 语句,实数在计算和存储时会有微小的误差,因此一般不能用“=”或“!=”进行判断。应设法转化为“=”和“= - ) & ( x = ),4. 判断表达式的使用,第2章 C+编程基础,2.1 C+的词法规则2.2 C+的数据类型2.3 表达式与语句2.4 预处理命令2.5 名字空间2.6 小结,2.4 预处理命令,使用预处理命令的目的是为了改善程序的组织和管理。预处理命令以字符“#”开头,它不是语句,后面不带分号。下面介绍常用的预处理命令:宏定义命令文件包含命令条件编译命令,2.4.1 宏定义命令,最简单的宏定义命令是用一个标识符代替另一种符号表示,例如: #define