已阅读5页,还剩150页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2020 3 26 1 CPP教材 第二版 四 李龙澍著 C语言与程序设计大学教程 2020 3 26 2 第10章输入 输出流第11章模板和异常处理第12章综合应用实例 李龙澍著 2020 3 26 3 第10章输入 输出流 本章要点 输入 输出流文件的操作 2020 3 26 4 第10章输入 输出流 10 1输入 输出流的概念10 2输出流10 3输入流10 4文件10 5例题分析与小结 2020 3 26 5 第10章输入 输出流 本章主要学习C 的输入输出机制 输入流和输出流 包括介绍C 的标准流库iostream及其结构 分类说明输入输出的操作和格式控制以及如何将流模型扩充到磁盘文件上 最后 本章提供了一些实际应用的具体事例 2020 3 26 6 10 1输入 输出流的概念 10 1 1基本概念在C 中 不仅可以继续使用C语言中以printf scanf为代表的库函数实现输入输出 更引入了 流 stream 的概念来丰富输入输出的操作方式 流 就是数据流 即字符序列在主机与外部介质之间的流动 可以理解为由一连串的字节所组成的字节流 2020 3 26 7 10 1 1基本概念 在输入操作中 字节流从输入设备 例如键盘 磁盘等 流到内存 在输出操作中 字节流从内存流到输出设备 例如显示器 打印机 磁盘等 该字节流中的内容不一定是字符 也可能是整数 音频数据 视频数据等 流在C 中被定义成类 在此之前经常使用的cout与cin就是iostream类库中用于完成输入输出操作的类对象 2020 3 26 8 10 1 1基本概念 下面用一个事例进行简单说明 例10 1 从键盘上得到一个数字 随即将其在屏幕上显示出来 includeintmain cout s1 cout Thenumberis s1 endl return0 2020 3 26 9 10 1 1基本概念 程序的第一行是预处理程序指令 include它告诉编译器希望使用iostream类库 尖括号内的内容是对应头文件 header 的名称 每个使用该类库的程序都必须包含这个头文件 第四行语句是要输出提示信息 cout Enteranumber endl 起到换行的作用 另外一个目的是刷新输出缓冲区 可以确保用户立即看到输出信息 2020 3 26 10 10 1 1基本概念 在这个表达式中 cout是标准的输出流对象 本来是被定义为左位移运算符的 由于在iostream类库中对其进行了重载 使它作为输出运算符 需要输出的标准数据可直接放在运算符 的右边 endl是endline的缩写 表示行结束 输出endl有两个目的 一个是可以 2020 3 26 11 10 1 1基本概念 第六行语句用来读入一个数字 cin s1 跟cout类似 cin是标准的输入流对象 本来是被定义为右位移运算符的 在iostream类库中同样进行了重载 使它作为输入运算符 输入的数据被存储到运算符 右边的变量s1中 2020 3 26 12 10 1 1基本概念 值得注意的是重载的 都可以在一条语句中连续使用 例如第七行语句 cout Thenumberis s1 endl 等同于下面的多条语句 cout Thenumberis cout s1cout endl 2020 3 26 13 10 1 2输入输出类库 1 iostream类库的组成对于iostream这个名称 i表示input 输入 o表示output 输出 合起来的意思就是输入输出流 类istream和类ostream都是通过单一继承从基类ios派生而来的 iostream类是由istream类和ostream类联合派生出来的 由于istream类主要支持输入操作 ostream类主要支持输出操作 所以iostream类同时支持输入输出操作 2020 3 26 14 10 1 2输入输出类库 其继承方式由图10 1所示 图10 1iostream类的继承关系 2020 3 26 15 10 1 2输入输出类库 2 iostream类中定义的标准流对象Cin 是类istream的对象 方便从标准输入设备 键盘 上读入数据 Cout 是类ostream的对象 方便在标准输出设备 显示器 上显示数据或是向内存缓冲区中写入数据 cerr 是类ostream的对象 方便把程序的出错消息迅速的在屏幕上显示出来 3 文件的输入输出类在fstream h头文件中主要定义了三个类来完成对文件的各种输入输出操作 它们分别是ifstream ofstream fstream 他们之间的继承关系由图10 2所示 2020 3 26 16 10 1 2输入输出类库 图10 2文件输入输出类的继承关系 2020 3 26 17 10 2输出流 输出流是由程序中输出到外部设备的数据流 主要由ostream类具体实现 其标志输出对象为cout cerr 使用它们基本上就可以完成大部分的输出操作 在一些特殊的情况下 还可以使用一些特殊的输出函数 如put write 等 2020 3 26 18 10 2 1基本输出操作 1 cout流对象cout是consoleoutput的缩写 意思是从控制台 即显示器上面显示数据 当使用coutvoidmain inta 100 整型doubleb 99 99 双精度浮点型charc W 字符型chard hello 字符串cout a a b b c c d d endl 2020 3 26 19 10 2 1基本输出操作 运行结果为 a 100 b 99 99 c W d hello 例10 3 直接输出表达式的计算结果 includevoidmain cout 1 2 1 2 endl 运行结果为 1 2 3 2020 3 26 20 10 2 1基本输出操作 2 cout的成员函数put和write成员函数put 和write 的作用是向输出流中插入字符或字符串 作用与插入运算符voidmain cout put a 向输出流中插入字符acout put b 向输出流中插入字符bcout flush 刷新输出流中的数据 使其立刻在屏幕上显示出来 2020 3 26 21 10 2 1基本输出操作 运行结果为 ab函数write 用于向流中插入一个字符串 该字符串由第一个参数指定 插入字符串的长度由第二个参数指定 例10 5 输出显示指定长度的字符串 includevoidmain char str HelloWorld cout write str 5 向输出流中插入字符串Hellocout flush 刷新输出流 运行结果为 HelloWorld 2020 3 26 22 10 2 1基本输出操作 3 cerr流对象cerr流对象是标准的显示错误流 它与标准输出流cout的用法差不多 只有一点不同 cerr只能在显示器上显示输出数据 而cout还可以将数据输出到磁盘文件上 通常在调试程序的时候 如果需要及时的在屏幕上显示出错信息 则需要使用cerr cerr流中的信息是用户根据自己的需要指定的 例10 6 解一元二次方程ax2 bx c 0 其中一般解为 如果a 0或b2 4ac 0时 用该公式就会出错 编写程序实现从键盘输入a b c的值 求x1和x2 2020 3 26 23 10 2 1基本输出操作 include includeintmain floata b c disc cout a b c if a 0 cerr aisequaltozero error endl elseif disc b b 4 a c 0 cerr disc b b 4 a c 0 endl else cout x1 b sqrt disc 2 a endl cout x2 b sqrt disc 2 a endl return0 2020 3 26 24 10 2 2按指定格式输出数据 C 标准的输入 输出流提供了两种格式控制方式 一种是使用ios类中的相关的成员函数 如setfI width precision 和fill 等 另一种是直接使用格式控制符 如oct hex和dec 每种控制符表示一种输出格式 通常是将它们与运算符 配合使用 虽然这两种方式用法不同 但功能相同 可根据不同的情况选用不同的方式 2020 3 26 25 10 2 2按指定格式输出数据 1 设置输出进制在屏幕上输出一个整数时 默认情况下是以十进制方式进行显示的 如果想以其它的进制显示数据 如八进制和十六进制 就需要调用成员函数setf或直接利用操作符oct hex和dec来实现 例10 7 按不同进制进行数据输出 includevoidmain inta 100 cout setf ios oct 设置输出方式为8进制cout a a endl cout setf ios hex 设置输出方式为16进制cout a a endl 2020 3 26 26 10 2 2按指定格式输出数据 cout setf ios dec ios basefield 将输出方式设置回为10进制cout a a endl intb 200 直接利用格式控制符进行不同进制的输出cout b oct b endl 8进制cout b hex b endl 16进制cout b dec b endl 10进制 2020 3 26 27 10 2 2按指定格式输出数据 运行结果为 a 144a 64a 100b 310b c8b 200需要注意的是在使用函数setf 后 会改变系统默认的输出格式 而直接在插入运算符 后面使用格式控制符则不会改变系统默认的输出格式 只对当前的输出流起作用 2020 3 26 28 10 2 2按指定格式输出数据 2 设置浮点数精度在系统默认的情况下 每个浮点数的输出精度是6位 要想改变输出精度 可以通过成员函数precision int 来实现 而不带参数的precision 会返回当前的精度值 例10 8 改变输出精度 include includevoidmain 程序的主函数 doublef sqrt 5 0 定义一个双精度型变量f 并为其赋初值cout f endl 按默认精度 6位 输出fcout precision 10 将当前精度改为10cout f endl 按新的精度重新输出f 2020 3 26 29 10 2 2按指定格式输出数据 运行结果为 2 236072 2360679773 设置输出宽度使用成员函数width int 可调整输出数据的宽度 在下面的事例中设置显示数据的宽度为10个字符 默认是右对齐方式 域宽设置仅对下一行的流插入有效 在一次操作完成之后 域宽又被置回0 例10 9 设置输出宽度 includeintmain 程序的主函数 2020 3 26 30 10 2 2按指定格式输出数据 intvalue 1 for inti 0 i 5 i cout width 10 cout value endl value 10 return0 运行结果为 2020 3 26 31 10 2 2按指定格式输出数据 110100100010000注意 当输出的数据不能达到指定的输出宽度时 默认使用空格填充剩余的部分 如果超出了指定的输出宽度 width函数也不会截断数值 会将其全部显示出来 2020 3 26 32 10 2 2按指定格式输出数据 4 设置填充字符使用成员函数fill int 设置填充的字符 其参数为需要填充的字符 例10 9 设置填充字符 includeintmain 程序的主函数 intvalue 1 cout fill for inti 0 i 5 i cout width 10 cout value endl value 10 2020 3 26 33 10 2 2按指定格式输出数据 return0 运行结果为 1 10 100 1000 100005 设置对齐方式调用成员函数setf Flags 如果Flags为right标志可以使输出域右对齐并把填充字符放在输出数据的左边 left标志可以使输出域左对齐并把填充字符放在输出数据的右边 2020 3 26 34 10 2 2按指定格式输出数据 例10 10 设置左对齐方式 includeintmain 程序的主函数 intvalue 1 cout setf ios left cout fill for inti 0 i 5 i cout width 10 cout value endl value 10 return0 2020 3 26 35 10 2 2按指定格式输出数据 运行结果为 1 10 100 1000 10000 2020 3 26 36 10 2 2按指定格式输出数据 6 浮点数按科学记数法显示调用成员函数setf 设置scientific标志使输出的浮点数按照科学计数法的形式进行显示 设置fixed标志使输出的浮点数按照定点的方式进行显示 如果不进行设置 则由浮点数的数值自动决定输出格式 例10 11 浮点数和科学记数法 include includeintmain 2020 3 26 37 10 2 2按指定格式输出数据 doublex 0 00123456 y 1 245e9 cout displayedindefaultformat n x t y n cout setf ios scientific ios floatfield cout displayedinscientificformat n x t y n cout unsetf ios scientific cout displayedindefaultformatafterunsetf n x t y n cout setf ios fixed ios floatfield cout displayedinfixedformat n x t y endl return0 2020 3 26 38 10 2 2按指定格式输出数据 运行结果为 displayedindefaultformat 0 001234561 245e 009displayedinscientificformat 1 234560e 0031 245000e 009displayedindefaultformatafterunsetf 0 001234561 245e 009displayedinfixedformat 0 0012351245000000 000000 2020 3 26 39 10 2 2按指定格式输出数据 在上述的两个例子中 均使用了成员函数setf longFlags 其中Flags取不同的标志意味着设定的不同输出格式 这些标志如下表所示 而且不同标志之间可以用OR 进行组合设置 如果需要取消某个格式设置 可以使用成员函数unsetf longFlags 表10 1格式状态标志 2020 3 26 40 10 2 2按指定格式输出数据 2020 3 26 41 10 3输入流 与输出流相对应 输入流是从外部设备上接收数据到程序中 它由istream类具体实现 其标志输入对象为cin 输入流中还包括一些特殊的输入函数 如get 和getline 2020 3 26 42 10 3输入流 1 cin流对象一般情况下 使用标准输入对象cin和运算符 实现输入操作 若键盘输入空格或回车表示一次输入的结束 当遇到输入流中的文件结束时 流读取运算符返回0 例10 12 一个简单的输入程序 include includeintmain 2020 3 26 43 10 3输入流 intx y cout x y cout x x y y x y x y endl return0 运行结果为 输入两个整数值 58x 5y 8x y 13利用cin还可以直接输入一个字符串 2020 3 26 44 10 3输入流 charbuf 30 定义一个存放29个字符的字符串cin buf 输入不多于29个字符的字符串2 cin的成员函数get 和getline cin的成员函数get 和getline 这两个函数都有三个参数 指向目标缓冲区的指针 缓冲区的大小 不能溢出 和终止符 终止符的缺省值是 n charbuf 30 cin get buf 30 n 这个调用将输入数据放在字符数组buf中 30是数组的大小 n 是终止符 由于 n 是缺省值 因此一般情况下 调用cin get buf 30 效果相同 2020 3 26 45 10 3输入流 例10 14 字符串输入程序 includevoidmain cout 请输入字符串 endl charbuf 30 cin get buf 30 接受输入 最多29个字符 每个汉字是2个字符cout buf endl 输出cin get buf 30 第二次接受输入没有执行cout buf endl 2020 3 26 46 10 3输入流 输入 Thisisadog 回车 输出 Thisisadog 很高兴buf接收了整行语句 但是 又会发现程序根本没给出第二次输入的机会 这是因为get 遇到输入流的终止符时就会停止 它并不会从输入流中提取终止符 如果此时再调用一次get 那么它第一眼看到的又是终止符 n 于是什么都没接收到就退出了 要解决这个问题 就需要使用成员函数getline 2020 3 26 47 10 3输入流 3 不同进制下的输入利用格式操作符oct hex和dec可以得到不同进制下的输入 其使用方法与cout非常类似 注意 一旦使用cin oct将当前输入进制设置为八进制 则下面的所有输入全部按照八进制进行读入数据 直到使用cin dec将当前输入进制设置回十进制 2020 3 26 48 10 4文件 10 4 1文件的打开和关闭在C 中使用输入输出流对文件进行操作 要打开一个文件 首先要做的就是创建一个文件流对象 并与指定的磁盘文件建立关联 C 中的文件流分为输入 输出和输入 输出三类 分别对应ifstream ofstream和fstream三个文件流类 要创建文件流 必须包含头文件fstream h 用对应的文件流类声明实例对象 再执行相关的读写操作 2020 3 26 49 10 4 1文件的打开和关闭 ifstreamifile 创建输入流对象ifile ofstreamofile 创建输出流对象ofile fstreamiofile 创建输入 输出流对象iofile 在C 中 流是一种逻辑机制 文件是实际存在于磁盘上的数据集合 简单地说 打开文件就是把流与文件相连接 关闭文件就是切断这一连接 打开文件时 还要指定文件是与哪种文件流相连接 输入流 输出流或是输入 输出流 一般情况下 可以使用两种方式打开文件 2020 3 26 50 10 4 1文件的打开和关闭 1 创建文件流对象创建文件流对象的格式如下 文件流可以是ofstream ifstream或fstream 文件对象是创建的文件流对象名 文件名是磁盘上的文件名称 包含文件路径 路径应使用双斜杠 存取模式是文件操作模式的标志 一般常用的操作模式有 ios in 只读文件模式ios out 只写文件模式ios app 追加文件模式 2020 3 26 51 10 4 1文件的打开和关闭 这些标志可以使用 符号相连接 表示同时设置几种模式 对已打开的文件的读写完成后 应关闭此文件 关闭文件用成员函数close close 是一个没有参数且无须指定返回值的函数 2 使用文件流成员函数open 可以使用open 函数来打开一个文件 其调用形式如下 open fstreamfile object file object open file name access mode 各个参数的含义与创建文件流方式时相同 可以用下面格式打开使用infile txt文件 ifstreamifile ifile open infile txt ios in 除了ios in外还有其它的存取方式标志位如表10 2所示 2020 3 26 52 10 4 1文件的打开和关闭 表10 2存取方式标志位 2020 3 26 53 10 4 2文件的读写 一个文件被打开以后 就与对应的文件流连接起来 这时对文件的读操作 就是从流中提取元素 对文件的写操作就是向流中插入元素 文件的打开模式分为文本模式和二进制模式 1 文本模式以文本模式打开文件 操作其对应的文件流的方式与操作一般输入输出流相类似 例10 18 简单的写文本文件程序 include include 2020 3 26 54 10 4 2文件的读写 voidmain ofstreamofile c temp file txt 以文本方式打开文件file txtif ofile cerr 打开文件错误 endl else 开始写入操作ofile 姓名 t 年龄 t 性别 t endl ofile 赵易 t 21 t 男 endl ofile 钱耳 t 25 t 女 endl ofile 孙伞 t 26 t 男 endl ofile 李思 t 22 t 女 endl 2020 3 26 55 10 4 2文件的读写 这是一个档案记录程序 它建立档案文件file txt 并将姓名 年龄 性别依次填入 文件内容如下 姓名年龄性别赵易21男钱耳25女孙伞26男李思22女2 二进制模式以二进制方式打开的文件 对它的读写操作与文本文件有所不同 程序必须按照数据在内存或磁盘中的存放格式一个字节一个字节的读取或写入 这需要使用read 函数和write 函数 2020 3 26 56 10 4 2文件的读写 例10 20 以二进制方式将员工的工资信息写入文件 include include 定义一个结构 存储员工姓名和工资structperson charname 20 doublesalary voidmain personemp1 李思 1200 personemp2 王强 1000 2020 3 26 57 10 4 2文件的读写 ofstreamofile c temp date txt ios binary 以二进制方式打开文件if ofile 如果打开文件出现错误 则退出程序 cerr 打开文件错误 endl return ofile write char 2020 3 26 58 10 4 2文件的读写 由于write函数只能写字符串 所以 对于其它类型的数据 必须先以 char 数据地址 的形式将它们转变为字符串类型 通过sizeof 函数可以得到数据的长度 2020 3 26 59 10 4 3文件的随机读写 在一般情况下 以读方式打开文件时 文件指针总是指向文件的开头 以写方式打开文件时 文件指针总是指向文件的结尾 当读文件时 每读一个字节 文件指针就向后移动一个字符的位置 写文件时每写一个字符后 文件指针就移动到文件的尾部 这种文件指针的移动方式显得非常被动 为了增加对文件访问的灵活性 C 的istream类和ostream类中定义了一些在输入输出流中操作文件指针的成员函数 让编程者可以方便的操纵文件指针 一个文件实际上有两个指针 一个用于读 一个用于写 因此 函数分为对应于istream类和ostream类的两套版本 2020 3 26 60 10 4 3文件的随机读写 这些操纵指针的函数可以分为以下三类 文件指针相对移动函数文件指针定位函数文件指针绝对移动函数下面分别介绍这些函数 2020 3 26 61 10 4 3文件的随机读写 1 文件指针相对移动函数在istream类和ostream类中分别定义了不同的相对指针移动函数seekg 和seekp 来执行 它们的定义如下 istream参数dir是文件指针相对移动的参照位置 如表10 3所列 共有三种情况 在ios中被定义为一个枚举类型seek dir 2020 3 26 62 10 4 3文件的随机读写 表10 3dir标志位含义 参数off是相对于参照位置的偏移量 为正就是往文件尾部移动 为负就是往文件头部移动 off被定义为streamoff类型 实际上就是long类型 infile seekg 2 ios cur 文件指针从当前位置向文件尾部移动2个字节nfile seekg 3 ios end 文件指针从文件尾部向文件头部移动3个字节outfile seekp 0 ios beg 文件指针移到文件头部 2020 3 26 63 10 4 3文件的随机读写 例10 25 从文件的相对位置读取字符 include includeusingnamespacestd voidmain charstrBuffer Iamstudent ofstreamofile c temp goal txt 建立一个文本文件ofile strBuffer 向文件中写入字符串ofile close 关闭文件charch ifstreamifile c temp goal txt 打开文件 默认读取方式ifile seekg 3 ios end 文件指针从文件尾部向文件头部移动3个字节ifile get ch cout ch endl 2020 3 26 64 10 4 3文件的随机读写 ifile seekg 2 ios beg 文件指针从文件头开始 后移2个字符ifile get ch cout ch endl ifile seekg 2 ios cur 文件指针从当前位置开始 后移2个字符ifile get ch cout ch endl 运行结果为 nas 2020 3 26 65 10 4 3文件的随机读写 2 文件指针定位函数对应于istream类和ostream类的指针定位函数分别是tellg 和tellp 其定义如下 streamposistream tellg streamposostream tellp 它们返回文件指针的当前位置 返回类型为streampos 等同于long类型 streamposinpos outpos inpos infile tellg 返回文件infile的当前文件指针位置outpos outfile tellp 返回文件outfile的当前文件指针位置 2020 3 26 66 10 4 3文件的随机读写 3 文件指针绝对移动函数文件指针的绝对移动函数可以将指针移动到指定的绝对地址上 对应于istream类和ostream类的成员函数是seekg 和seekp 函数原型如下 istream 2020 3 26 67 10 5例题分析与小结 10 5 1例题 例10 26 编写一个程序在磁盘上产生一个档案文件 文件名由用户指定 用户按照 姓名 年龄 工资 的顺序输入三条记录 然后程序在记录前加记录号 数字和一个空格 将内容写入文件backup txt 最后显示backup txt文件的内容 首先定义一个存放记录的结构体 结构体包括显示函数 然后定义写入文件和从文件读出函数 最后编写主程序 2020 3 26 68 10 5 1例题 include includestructRecord 定义结构 用以存放一条记录 charname 30 charage 30 charsalary 30 voidDisplay cout data name data age data salary voidmain 2020 3 26 69 10 5 1例题 inti id char file name c temp data txt Recorddata ofstreamxfile file name ios out 用户创建文件并写入数据 if xfile 打开文件错误 cerr data name cout data age cout data salary WriteFile xfile data 2020 3 26 70 10 5 1例题 xfile close ifstreaminfile file name ios in 备份文件 if infile cout 不能打开文件 endl return ofstreamoutfile c temp backup txt ios out if outfile 创建备份文件错误 cout 不能建立backup txt文件 endl return id 1 2020 3 26 71 10 5 1例题 while infile eof 所有记录加标号后写入备份文件 ReadFile infile data if infile eof break outfile id 读标号ReadFile ifile data if ifile eof break cout id t 输出标号data Display ifile close 2020 3 26 72 10 5 2解题分析 按照题目要求首先定义一个存放记录的结构体 结构体也是类 它的默认属性是公有的 这个结构体只包括一个显示函数 为了分步处理 首先定义写入文件和从文件读出函数 最后编写主程序 这是一个数据文件管理程序 首先 在磁盘上产生一个文件data txt 要实现在每一行前面加行号的功能 先获取一行数据 再将其加行号后写入新的文件backup txt 最后在屏幕上显示修改过的文件的内容 目的是学会正确地使用文件 2020 3 26 73 10 5 3小结 本章首先介绍了输入 输出流的概念 流库的层次结构和使用规则 然后分类介绍了输入流和输出流的基本使用方法和各种控制函数 最后 详细介绍了文件的打开 输入输出和随机读写的方法 流可以看做数据的流动 它负责数据从产生者到使用者间的传递过程 一个输出流对象是信息流动的目标 标准输出流对象由ostream类构造 输入流对象是信息流动的源头 标准输入流对象由istream类构造 它们的格式可以通过格式操作符或ios函数控制 文件流对象由fstream类 包括ifstream类和ofstream类 构造 可以以文本模式或二进制模式以及多种操作方式打开文件 文件中的内容可以通过移动文件指针进行随机读写 通过本章的学习可以掌握基本的输入输出技巧 掌握文件的基本存取方法 编写存取数据的实用程序 2020 3 26 74 第11章模板和异常处理 本章要点 模板异常处理 2020 3 26 75 第11章模板和异常处理 11 1模板11 2异常处理11 3例题分析和小结实训 2020 3 26 76 11 1模板 模板给C 增加了对通用对象和函数的支持 这是传统语言所缺少的面向对象的特点 函数模板给C 语言添加了许多灵活性 而类模板扩展了C 类的灵活性 2020 3 26 77 11 1 1模板的定义 模板也叫做参数化的数据类型 模板有两种类型 函数模板和类模板 函数模板的声明语法为 template 模板参数表由若干个 class模板参数 组成 例11 1 同类型加法函数模板 templateTsum Ta Tb returna b 2020 3 26 78 11 1 1模板的定义 此函数的两个参数以及返回值类型均未指明 只是以变量T表示 T标识符用来表示模板定义中参数化的类型 也可以用其他合法的C 标识符来表示 不过一般习惯用T来表示 在这个例子中函数sum的两个参数是同一种类型 当所定义的函数参数不是同一种类型时 只要修改相应的模板参数表即可 例11 2 不同类型的加法函数模板 templateT1sum T1a T2b returna b 类模板的声明语法为 template 2020 3 26 79 11 1 1模板的定义 例11 3 一个简单的类模板 templateclassA T1x T2y Public A T1a T2b x a y b voiddisplay cout x y endl 2020 3 26 80 11 1 1模板的定义 利用模板 程序员可以构造相关函数或类的系列 大大缩短了程序的长度 在某种程度上也增加了程序的灵活性 在使用模板时程序员不必关心所使用的每个对象的类型 而只要集中精力到程序的算法上面 模板是C 最新的扩展 也是C 中的一项有争议的技术 虽然模板有着强大的功能 但是想要用好它也需要有丰富的编程经验 否则将会对程序的结构和执行效率带来负面的影响 2020 3 26 81 11 1 2模板的使用 1 函数模板在一个程序中所调用的函数模板可能使用不同的参数列表 这就使得程序能够用不同类型的参数调用相同的函数 对于例11 1 可以这样调用 intiSum sum 2 3 doubledSum sum 2 0 3 0 例11 4 设计一个求两个数之和的函数模板 使用函数模板求两个整数之和 求两个实数之和 设计一个求两个整数之和的函数isum 设计一个求两个实数之和的函数fsum 编写程序检验结果 2020 3 26 82 11 1 2模板的使用 templateTsum Ta Tb returna b 加法模板 intisum inta intb returna b 整数加法 floatfsum floata floatb returna b 实数加法 voidmain cout isum 2 3 isum 2 3 endl cout fsum 3 5 4 6 fsum 3 5 4 6 endl cout sum 2 3 sum 2 3 endl cout sum 3 5 4 6 sum 3 5 4 6 endl 2020 3 26 83 11 1 2模板的使用 运行结果为 isum 2 3 5fsum 3 5 4 6 8 1sum 2 3 5sum 3 5 4 6 8 1在本例中 可以看到sum其实相当于若干个函数的组合 对应于不同的参数类型 sum可以返回不同的结果 2 类模板同样 在一个程序中可能要声明类模板的多个对象 对于例11 3 可以这样声明类模板A的多个不同类型的对象 AintA AfloatA AdoubleA 2020 3 26 84 11 1 2模板的使用 例11 5 设计一个关于复数的类模板FS 使其可以声明实部 虚部均是整数或者均是实数的对象类 包含数据成员a和b表示复数的实部与虚部 成员函数disp 用来显示复数 templateclassFS Ta Tb public FS Tx Ty 2020 3 26 85 11 1 2模板的使用 a x b y voiddisp coutf1 2 3 FSf2 4 3 5 2 f1 disp f2 disp 程序的运行结果为 2 3i4 3 5 2i 2020 3 26 86 11 2异常处理 异常处理是C 的一个特点 它能够在检测到程序的运行错误后 终止程序 并按事先指定的方法对错误进行处理 当异常被处理完毕后 程序会被重新激活 并在异常处理点继续执行下去 选择异常处理的策略通常和实际的应用联系在一起 有些时候 程序给出错误信息 有时要求用户重新输入和选择 2020 3 26 87 11 2 1异常处理的语法结构 一般而言 C 的异常处理可以分为两大部分 一是异常的识别与发出 二是异常的捕捉与处理 异常处理的语法结构如下 class try throw 抛出异常 catch 捕捉异常 处理异常 2020 3 26 88 11 2 1异常处理的语法结构 如果在try 程序块内发现异常 则由throw 异常 语句抛出异常 catch 异常 语句负责捕捉异常 当异常被捕获之后 catch 程序块内的程序则进行异常的处理 在这里throw 异常 语句所抛出的异常其实是某种对象 是用来识别异常的 2020 3 26 89 11 2 2异常处理的应用 下面通过一个简单的例子来说明异常处理的使用 例11 6 要求一个函数表达式f x a b c的值 很显然c是不能为0的 编写捕捉c为0时的异常 并且提醒用户除数为0 classYC voidmain doublea b c cout a cin b cin c try if c 0 throwYC 2020 3 26 90 11 2 2异常处理的应用 cout endl a b c a b c endl catch YC cout endl 除数不可以为0 endl 运行结果为 请输入a b和c 460除数不可以为0 其中 下划线部分是用户输入的 2020 3 26 91 11 2 2异常处理的应用 在本例中 YC类是用来表示异常的类 当程序发现除数为0的情况时 由throw YC 抛出一个YC的对象 由catch 异常 语句来捕捉异常 抛出异常的throw 异常 语句既可以在try 程序块中 也可以位于其中所调用的函数中 在try 程序块中可能根据不同的错误情况抛出不同的异常 当需要处理多种异常的时候 只要增加相应的catch 程序块即可 2020 3 26 92 11 2 2异常处理的应用 例11 7 用户输入矩形的长与宽 计算矩形的面积 当矩形的面积小于10时抛出异常S 当矩形的面积大于100时抛出异常L classS classL voidmain inta b cout a cin b try if a b100 throwL 2020 3 26 93 11 2 2异常处理的应用 elsecout endl 长为 a 宽为 b 的矩形面积为 a b catch S cout endl 矩形的面积不能小于10 endl catch L cout endl 矩形的面积不能大于100 endl 运行结果为 请输入矩形的长与宽 32矩形的面积不能小于10 请输入矩形的长与宽 2030矩形的面积不能大于100 2020 3 26 94 11 3例题分析和小结 11 3 1例题 例11 8 设计一个求两个整数中的大数的函数max2 重载函数max2使其可以求两个实数中的大数 设计一个模板函数max1求两个数中的大数 2020 3 26 95 11 3 1例题 首先定义求两个整数中的大数的函数max2 int int 其两个参数的数据类型为int intmax2 inta intb if a b returna elsereturnb 重载函数max2 使其可以比较两个实数 doublemax2 doublea doubleb if a b returna elsereturnb 2020 3 26 96 11 3 1例题 定义函数模板max1 templateTmax1 Ta Tb if a b returna elsereturnb voidmain cout max2 12 35 max2 12 35 endl cout max2 3 5 4 6 max2 3 5 4 6 endl cout max1 12 35 max1 12 35 endl cout max1 3 5 4 6 max1 3 5 4 6 endl 2020 3 26 97 11 3 1例题 运行结果为 max2 12 35 35max2 3 5 4 6 4 6max1 12 35 35max1 3 5 4 6 4 6比较max1 与max2 的执行情况 可以看出他们的运行效果是一样的 模板函数max1 一个程序相当于重载的两个max2函数 2020 3 26 98 11 3 1例题 例11 9 求函数表达式f x a b c的值 处理除数为0的异常 要求在try 程序块中调用一个可以抛出异常的函数 首先 定义一个识别异常的类YC classYC 定义可以抛出异常的函数fe voidfe doublex if x 0 throwYC 2020 3 26 99 11 3 1例题 定义异常处理函数fd voidfd doublea doubleb doublec try fe c cout a b c a b c endl catch YC cout 除数不可以为0 endl 设计主程序 voidmain doublea b c a 4 b 6 c 0 除数不可以为0 a 3 b 5 c 4 3 5 4 2 2020 3 26 100 11 3 2解题分析 在例11 8中重载max2 时 应该注意重载函数的参数类型不能和原函数的参数类型完全相同 在这里max2 int int 被重载为max2 double double 例11 8的程序执行结果表明模板函数max1 的作用相当于被重载的函数max2 但是编写程序的工作量却比后者要小 例11 9表明了处理例外的方法 在程序设计时 要充分考虑例外的发生 做出相应的处理 处理例外可以分为4步 定义识别异常的类 定义抛出异常的函数 定义异常处理函数 编写主程序 2020 3 26 101 11 3 3小结 模板也叫做参数化的数据类型 有函数模板和类模板 函数模板的使用 使得程序能够用不同类型的参数调用相同的函数 类模板的使用 使得程序可以声明模板的多个不同类型的对象 这大大缩短了程序的长度 在某种程度上也增加了程序的灵活性 在使用模板时程序员不必关心所使用的每个对象的类型 而只要集中精力到程序的算法上面 虽然模板有着强大的功能 但是想要用好它也需要有丰富的编程经验 否则将会对程序的结构和执行效率带来负面的影响 异常处理是C 的一个特点 它可以分为两大部分 一是异常的识别与抛出 二是异常的捕捉与处理 在程序中增加异常处理部分有利于程序的有效运行 2020 3 26 102 实训11建造数组模板和异常处理 1 实训题目 1 用模板定义一个类 数据成员为一个组数以及数据的个数 成员函数包括求解该组数据的和 显示最大值与最小值 求解平均值等 2 编写函数f doublea doubleb doublec 求函数表达式的值 2 实训要求 1 实现模板类的属性函数 2 正确处理各种异常 2020 3 26 103 第12章综合应用实例 本章要点 商场员工信息登记系统实例小结 2020 3 26 104 在软件的整体设计思想上 面向对象与传统的结构化方法有着本质区别 大量的实例证明 采用面向对象的思想设计的程序在维护性和重用性方面明显优于采用结构化思想设计的程序 因此 采用面向对象的思维方式去分析问题 解决问题 面向对象分析问题的方法大致分为以下几个步骤 第12章综合应用实例 2020 3 26 105 1 根据用户需求进行具体分析 2 建立对象模型 确定其属性和功能 3 将公共部分抽取出来 形成类 4 寻找类与类之间的联结 下面以一个商场的员工信息登记系统为例来说明如何用面向对象方法分析问题 学会怎样使用C 语言编写实际程序 第12章综合应用实例 2020 3 26 106 12 1 1问题的描述12 1 2类设计12 1 3源代码 12 1商场员工信息登记系统 2020 3 26 107 登记某个商场内所有员工的个人信息 计算每个员工的月薪 将结果存入纪录文件 商场中主要有三类人员 经理 仓库管理员 简称库管 和售货员 需要记录的个人信息有姓名 内部编号和家庭住址 每类员工计算月薪的方式如下 售货员的工资由两部分构成 固定工资加提成 经理的工资是也由固
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 枣庄市滕州市2025-2026学年第二学期六年级语文第五单元测试卷部编版含答案
- 巴彦淖尔盟乌拉特后旗2025-2026学年第二学期四年级语文第五单元测试卷(部编版含答案)
- 阳泉市城区2025-2026学年第二学期六年级语文第五单元测试卷部编版含答案
- 纪委两项制度工作制度
- 继续医学教育工作制度
- 综合平安创建工作制度
- 综治成员单位工作制度
- 人工智能项目管理关键要点梳理
- 凌源市中等职业技术专业学校招聘真题
- 精准营销策略在私行应用
- JTGT B06-02-2007 公路工程预算定额
- 工程经济学概论(第4版)课件 邵颖红 第9-11章 投资风险分析、资产更新分析、价值工程
- 开封大学单招职业技能测试参考试题库(含答案)
- 关于汉字字谜研究报告
- 采购管理制度及流程采购管理制度及流程
- 水工隧洞的维护-水工隧洞的检查与养护
- 惠州市惠城区2022-2023学年数学六年级第二学期期末综合测试试题含解析
- 2023年江苏对口单招财会高考试卷
- 实验动物课件 实验动物的营养控制-研究生2018
- YY/T 1778.1-2021医疗应用中呼吸气体通路生物相容性评价第1部分:风险管理过程中的评价与试验
- GB/T 23901.1-2019无损检测射线照相检测图像质量第1部分:丝型像质计像质值的测定
评论
0/150
提交评论