c++语言程序设计教学课件作者赵海廷第13章

上传人:E**** 文档编号:102542976 上传时间:2019-10-03 格式:PPT 页数:38 大小:257.50KB
返回 下载 相关 举报
c++语言程序设计教学课件作者赵海廷第13章_第1页
第1页 / 共38页
c++语言程序设计教学课件作者赵海廷第13章_第2页
第2页 / 共38页
c++语言程序设计教学课件作者赵海廷第13章_第3页
第3页 / 共38页
c++语言程序设计教学课件作者赵海廷第13章_第4页
第4页 / 共38页
c++语言程序设计教学课件作者赵海廷第13章_第5页
第5页 / 共38页
点击查看更多>>
资源描述

《c++语言程序设计教学课件作者赵海廷第13章》由会员分享,可在线阅读,更多相关《c++语言程序设计教学课件作者赵海廷第13章(38页珍藏版)》请在金锄头文库上搜索。

1、第13章 预处理和异常处理,13.1 C+的预处理 13.2 C+多文件程序结构 13.3 异常处理的基本概念 13.4 C+异常处理的实现 13.5 异常处理中的构造函数和析构函数,13.1C+的预处理,使用编辑软件建立最初的源代码文件,这个程序在真正执行之前一般经历5个不同的处理阶段: 编辑:输入源代码,包括C+源程序和可能有的预处理控制行。 预处理:对带有宏调用等预处理控制行进行预处理。 编译:将带有宏扩展等内容的源代码文件编译成汇编语言的源代码。 汇编:将汇编语言的源代码文件汇编成可重定位目标代码。 连接:将可重定位目标代码模块连接成可执行代码可执行文件。,返回,下一页,13.1C+的

2、预处理,从语法上讲,预处理程序控制行与语言的其他成分无关,它们可以出现在程序代码的任何地方,但宏替换和文件包含一般应出现在文件的开头。预处理程序控制行的作用域仅限于说明它们的那个文件,出了那个文件它们就失去了作用。 准确地使用C+语言的预处理功能可以编写出易读、易改、便于移植和调试的C+程序,有利于软件工程的模块化设计。,返回,下一页,上一页,13.1C+的预处理,13.1.1宏定义 用#define作为标志的预处理控制行可用来定义简单的宏(也称为符号常量)和带参数的宏。 1.简单的宏 简单宏定义的一般格式为: #define标识符字符串 其中,#define是预处理宏替换命令,标识符又称为符

3、号常量,一般由大写字母构成,以便与程序中变量名或函数名相区别,看上去也更加醒目。字符串是由字符集中的字符组成的字符序列,其外面不允许带双引号,以与字符串常量相区别。#define、标识符、字符串各部分之间用空格分隔。其末尾不得加分号,以换行符结束。每个行只能定义一个宏。,返回,下一页,上一页,13.1C+的预处理,在包含这个控制行的文件中,凡是以XYZ作为标记的地方在预处理过程中都用500替换。在符号常量定义中,对于一些常量有一定的习惯约定。 符号常量也可定义具有一定精度的float和double类型的数值,以便于程序中对它们作安全的替换。 利用宏替换可以增加程序的移植性。假设编写了一个从磁带

4、机的磁带上读取数据的C+程序,要求当读磁带遇到规定的符号时,读带过程应停下来。,返回,下一页,上一页,13.1C+的预处理,2.带参数的宏定义及宏调用 带参数宏定义的一般格式为: #define宏标识符(参数表)表达式 其中,宏标识符就是带参数的宏名字,参数表中的参数类似于函数中的“形式参数”,表达式是要被替换的实体,也称宏体。要求宏标识符与左圆括号之间不得有空格。 宏调用的一般格式是: 宏标识符(参数表) 此处的宏标识符就是已被定义的宏标识符;参数表中的参数类似于函数调用中的“实在参数”。,返回,下一页,上一页,13.1C+的预处理,对带参数宏的调用类似于函数的调用。 带参数的宏和函数之间的

5、确有一定的类似之处,在调用函数时是函数名后括号内写入实在参数,要求实在参数与形式参数的数目相等顺序对应。但带参数的宏并不是函数,它们有 如下不同: (1)函数调用时,先求出实在参数表达式的值,然后传值给形式参数,而带参数的宏只进行简单的字符替换。 (2)函数调用是在程序被执行时,分配临时的内存单元,而宏扩展则是在程序的编译前一阶段进行,扩展时不分配存储单元,不进行值的传递,也不存在返值。,返回,下一页,上一页,13.1C+的预处理,(3)函数中的形式参数、实在参数都要定义数据类型,两者要求类型匹配,而宏不存在类型问题。宏名字无类型,其参数也没有类型,只是一个符号,在扩展时代入指定字符序列即可。

6、 (4)多次使用同一个宏时,宏扩展后源程序变长,因为每次宏扩展都是在对应部位增加对应的宏体,而函数调用不会使程序变长。 (5)宏替换不占用运行时间,只占用编译时间,而函数调用则要多占用运行时间。一个宏一旦被定义,在其所在的文件中均是存在的和可见的。这一点类似于外部变量。如要对某一个宏定义撤销,可用命令: #undef宏标识符 一个宏标识符一旦撤消了原来的定义,便可以被重新定义其他不同的宏。,返回,上一页,下一页,13.1C+的预处理,13.1.2文件包含 “包含文件”是指一个源文件可以将另外一个源文件或“头文件”的全部内容包含进来,即将另外的文件包含到本文件之中,C+语言提供#include命

7、令用来实现文件包含操作。 其一般形式是: #include 图131表示文件包含的含意。图131(a)为文件file1.cpp,它有一个文件包含命令,返回,下一页,上一页,13.1C+的预处理,#include,还有其他的内容A。图13.1(b)为另一个文件file2.cpp,文件内容为B。在编译预处理时,要对#include命令进行文件包含处理,将文件file2.cpp的全部内容插入到#include命令行处,即file2.cpp文件被包含到file1.cpp中,如图131(c)所示,在接下来进行的编译中,将包含file2.cpp文件以后的file1.cpp文件作为一个源文件进行编译。,返回

8、,下一页,上一页,13.1C+的预处理,这种常用的被包含文件称为“标题文件”或“头文件”,常以“.h”为后缀,如“print_format.h”文件。当然也可以不用“.h”为后缀,用“h”作为后缀更能表示此头文件的性质。头文件除了可以包括宏定义外,也可以包括结构体类型定义,全局变量的定义等。 使用文件包含应注意: (1)一个#include命令只能指定一个被包含的文件,如果要包含N个文件,就要用N 个#include命令,其后不得加分号。 (2)如果文件1包含文件2,而文件2中又要用到文件3的内容,则可在文件1中用两个#include命令分别包括文件2和文件3,而且文件3应出现在文件2之前,即

9、在,返回,下一页,上一页,13.1C+的预处理,文件file1.cpp 中为: #include“file3.cpp“ #include“file2.cpp“ 这样,file1.cpp和file2.cpp都可以用file3.cpp的内容。在file2.cpp中就可以不必再用 #include。,返回,下一页,上一页,13.1C+的预处理,(3)一个被包含文件中又可以包含另一个被包含文件,即包含文件是可以嵌套的。 (4)在#include命令中,文件名可以用双引号或尖括号括起来,例如,可以在file1.cpp中用: #include“file2.cpp“或#include都是合法的。两者的区别是

10、:用双引号的文件包含情况,系统先在引用被包含文件的源文件所在的文件目录中寻找要包含的文件,若找不到,再按系统指定的标准方式搜索文件目录。一般来讲,用双引号比较保险。如果已经确知被包含的文件在系统规定的子目录里,可以用 #includeB A B A尖括号形式。,返回,下一页,上一页,13.1C+的预处理,(5)被包含文件如file2.cpp所在的文件(包含#include命令的file1.cpp源文件),在预处理后已成为同一个文件。因此在被包含文件(file2.cpp)中有全局变量,它在文件(file1.cpp)中也是可见的,不必使用extern说明。,返回,下一页,上一页,13.1C+的预处

11、理,13.1.3条件编译 一般情况下,源程序中所有的行都参加编译,但有时希望对其中一部分内容在满足一定条件时才进行编译,这就需要条件编译。 1.#ifdef标识符 程序段1 #else 程序段2 #endif 它的作用是当标识符已经被定义过,则对程序段1进行编译,否则编译程序段2。,返回,下一页,上一页,13.1C+的预处理,和if else语句一样,#else部分可以缺省,即为: #ifdef标识符 程序段1 #endif 程序段可以是语句组,也可以是命令行。条件编译对于提高C+源程序的通用性很有好 处。例如:一个C+源程序在不同的计算机系统上运行,有的机器上以16位(2字节)存放 一个整型

12、数,而另一种机器上可能以32位存放一个整型数,这样需要对源程序作必要的修改。,返回,下一页,上一页,13.1C+的预处理,可以用以下的条件编译: #ifdefIBM-PC #defineINTEGER-SIZE16 #else #defineINTEGER-SIZE32 #endif 如果IBM-PC在前面已被定义过,则编译命令行#defineINTEGERSIZE16,否则,编 译命令行#defineINTEGERSIZE32 这样,源程序可以不必作任何修改就可以用于不同类型的计算机系统。,返回,下一页,上一页,13.1C+的预处理,2.#ifndef标识符 程序段1 #else 程序段2

13、#endif 其作用是标识符未被定义则编译程序段1,否则编译程序段2,这种形式与第一种形式的作用刚好相反。,返回,下一页,上一页,13.1C+的预处理,3.#if表达式 程序段1 #else 程序段2 #endif 其作用是在指定的表达式为真时就编译程序段1,否则就编译程序段2。这样可以事先给定条件,使程序在不同的条件下执行不同的功能。,返回,上一页,13.2C+多文件程序结构,C+的源程序一般由三个部分构成:类的说明、类成员的实现和主函数。也就是类的定义文件(*.h文件)、类的实现文件(*.cpp文件)和类的使用文件(*.cpp主函数文件)。 C+程序的一般结构举例。 /文件1,类的定义,L

14、ocation.h #include classLocation/类的定义 public:/外部接口 Location(intxx=0,intyy=0)X=xx;Y=yy;countP+;,返回,下一页,13.2C+多文件程序结构,Location(Location,返回,下一页,上一页,13.2C+多文件程序结构,/文件2,类的实现,Location.cpp #include“Location.h“ Location:Location(Location/使用类名初始化静态数据成员 voidmain(),返回,上一页,13.2C+多文件程序结构, LocationA(4,5); cout“C+

15、程序一般结构举例n“; cout“LocationA(“A.GetX()“,“A.GetY()“)“; A.GetC();/使用对象名调用静态函数成员 LocationB(A); cout“LocationB(“B.GetX()“,“B.GetY()“)“; Location:GetC();/使用类名调用静态函数成员 ,返回,下一页,上一页,13.2C+多文件程序结构,程序的运行结果为: C+程序一般结构举例 LocationA(4,5)Objectid=1 LocationB(4,5)Objectid=2,返回,上一页,13.3异常处理的基本概念,13.3.1异常处理的基本思想 异常发生有三

16、种原因:其一是C+/VC+系统检测到了非正常的执行状态,这些状态可能由三种因素引起:表达式的计算违背了C+/VC+语言的语义,例如被0除;在连接C+/VC+程序时出现错误;超出了系统的资源限制,例如使用了太多的内存这些无法预知的异常。其二是C+/VC+程序代码中的throw语句被执行。其三是发生异步异常,其可能的原因有线程终止函数被调用,系统内部发生错误。,返回,下一页,13.3异常处理的基本概念,运行系统中出现异常时,发生异常的相关程序段要抛出异常,而运行系统负责寻找一段代码来处理异常。在C+/VC+语言中,创建一个异常对象并将它交给运行系统,这称为抛出一个异常,又称为异常抛出。系统抛出异常后,系统开始寻找相关的代码来处理该异常。运行系统在调用栈中,从发生错误的过程开始逆向搜寻,直到找到一个包含合适的异常处理过程为止。当异常的类型和异常处理过程的异常类型相符合时,异常就从调用栈中“冒”出来,到达这个

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号