用面向对象方法与C描述

PPT
  • 阅读 53 次
  • 下载 0 次
  • 页数 107 页
  • 大小 411.448 KB
  • 2023-08-11 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档22.00 元 加入VIP免费下载
此文档由【精品优选】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
用面向对象方法与C描述
可在后台配置第一页与第二页中间广告代码
用面向对象方法与C描述
可在后台配置第二页与第三页中间广告代码
用面向对象方法与C描述
可在后台配置第三页与第四页中间广告代码
用面向对象方法与C描述
用面向对象方法与C描述
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 107
  • 收藏
  • 违规举报
  • © 版权认领
下载文档22.00 元 加入VIP免费下载
文本内容

【文档说明】用面向对象方法与C描述.pptx,共(107)页,411.448 KB,由精品优选上传

转载请保留链接:https://www.ichengzhen.cn/view-324675.html

以下为本文档部分文字说明:

清华大学计算机系列教材殷人昆陶永雷谢若阳盛绚华编著数据结构(用面向对象方法与C++描述)1◼C++语言的概要◼类、对象、构造函数与析构函数◼输入/输出◼函数、参数传递与函数返回值◼函数名重载与操作符重载◼动态存储分配◼友元函数与内联函数◼结构、联合与类编程简介C++2C++语言概要◼C++

源于C语言。◼1970年,两位程序员BrianKernighan和DennisRitchie首创了一种新的程序设计语言,取名为C语言。◼设计C语言的最初目的是编写操作系统。由于其简单、灵活的特点,C语言很快就被用于编写各种不同类型的程序,从而成为世界上最

流行的语言之一。3◼C语言是一个面向过程的语言。随着软件开发技术的进步,程序员们最终发现,把数据和施加在其上的操作结合起来,会得到更易于理解的程序,由此产生了面向对象的程序设计思想。◼1980年代初,美国AT&T贝尔实验室的BjarneStroustrup设计并实现了C语

言的扩充、改进版本,C++语言诞生了!◼C++改进了C的不足之处,增加了对面向对象的程序设计的支持,在改进的同时,保持了C的简洁性和高效性。4//一个简单的C++程序/*一个简单的C++程序,该程序在标准输出设备上输出一句问候语“hello”*/#include

<iostream.h>intmain(){cout<<"hello!";return0;//正常返回}这是一个只包含一个函数的程序,程序的基本元素是数据说明、函数和注释。5注释◼C++的第一次注释格式源于C语言。注释开始于“/*”,结束于“*/”,在两者之间的任何内容,包括换行符都

被编译器忽略。◼注意注释符对不可以嵌套。◼第一种注释符以“//”开头,它是单行注释符,在它同一行右侧的任何信息都将被认为是注释而由编译器略去。◼注意:上面两种注释符的两个标志符/和*,/和/之间不可以分开。6#include语句◼C++将一些标准函数和变量说明

放在头文件中。头文件中保存所有与标准函数或变量相关的信息,为了使用头文件中定义的变量和函数,必须将相应的头文件include进主程序,作为程序的一部分进行编译。◼用户也可以定义自己的头文件,把一些相关的函数和变量组织在一个文件中,当另外的程序要用到这些函数和变量时,可以将该文件作为头文件

include进来。7◼#include指令有两种格式:#include<头文件名>#include“头文件名”◼第一种文件名在<>中指定,表示该文件存放于系统设定的子目录中,这类文件一般是由系统给出的,并已经过编译。◼第二种文件名在“”中给出,表示该文件存放在当前目录中,这些头文件通常由用

户自己给出。◼头文件中可包含其它头文件,即#include可以直接嵌套。8◼C++源程序中还可包括各种编译命令,这些命令被称为预处理指令,常用的除#include外,还有条件预处理指令#if、#ifndef和#endif等和宏替换指令#define。◼预处理命令对编译器起作用,它指示编译器

在正式编译前做一些预先处理。#include命令将指示编译器将其后所跟的文件内容插入到当前文件中;#define定义一个常量或替换宏,它指示编译器在使用该常量或宏的地方替换为其实际内容;#if、#ifndef和#endif指示编译器做条件编译。9◼#define用来定义一个常量或替换宏,

如:#definesize20//定义一个常量size,其值永远为20#defineMAX(x,y)((x<y)?y:x)//求x,y中的最大值◼经过预编译后,程序中所有出现size和MAX(x,y)之处都会被20和((

x<y)?y:x)代替,如:intarray[size];inti=MAX(4,55);◼经预编译后会变为intarray[20];inti=((4<55)?55:4);10函数原型◼下面的程序给出了典型的C程序结构,它是“Hello,world”程序的变型。◼这个程序由三个文件组

成:/*File:hello.h*/char*hello();/*File:hello.c*/#include<stdio.h>/*包括sprintf()的原型*/#include<stdlib.h>/

*包括malloc()的原型*/#include<string.h>/*包括strlen()的原型*/#include"hello.h"/*包括hello()的原型*/11char*hello(name)char*nam

e;{char*value;/*返回串"Hello,name.".*/value=(char*)(malloc(9+strlen(name));sprintf(value,"Hello,%s.",name);returnvalue;}/*File:main.c*/#incl

ude<stdio.h>/*包括printf()的原型*/#include"hello.h"/*包括hello()的原型*/12main(argc,argv)intargc;char*argv[];{printf("%s",hello("world"));}◼头文

件名字的后缀用“.h”表示,程序文件名字的后缀用“.c”表示。◼hello.h:包含hello函数的原型。main函数可通过“#include”定向到该原型的定义文件,取得对原型的访问性。13◼hello.c:这是hello函数的定义文件。它通过一个string类型的形式参数接受

需要打印的串,返回一个string类型的值作为打印串。返回类型必须与在#include定向的“.h”文件中所给出的原型的类型匹配。◼main.c:这是打印“Hello,world”的主程序,它构造和返回一个欢迎词字符串,其结果通过函数printf打印出

来。◼C把函数和数据定义放在后缀为“.c”的代码文件中。在各代码文件中使用后缀为“.h”的include文件,定义对其他各模块的调用接口。14C++的函数特征◼特征是函数参数表的描述。◼利用特征信息可进行严格的类型检查。它允许编译器检验实际参数的数目

是否正确,对应的形参和实参是否相容,函数返回的类型与函数调用的环境是否相容。◼它克服了在许多C程序的开发中,由于在C原型中没有定义参数的类型和数量,而造成的实参和形参之间不匹配,函数返回类型与使用之间不匹配等许多缺陷。15◼现用C++语句改写前面的C程序。◼C++程序在“.h”文件中对hello(

)使用了函数特征。对于hello()的原型:◆不要求形式参数的名字出现在特征中◆参数的数目和类型,以及返回类型,都完整地在函数说明中定义◼C++允许在函数说明时,在括号内直接声明形式参数的类型。16/*File:hello.h*/char*hello(char*);/*File:h

ello.cpp*/#include<stdio.h>//包含函数sprintf()的原型#include<string.h>//包含函数strlen()的原型#include“hello.h”//包含函数

hello()的原型char*hello(char*name){char*value=newchar[9+strlen(name)];sprintf(value,"Hello,%s.",name);returnvalue;}17/*

File:main.cpp*/#include<iostream.h>//说明输出流对象cout#include"hello.h"//包含函数hello()的原型main(intargc,char*argv[]){cout<<hello("

world");}18C++的数据声明◼C++的数据声明将数据名与数据类型联系起来。其主要形式有:◆常数值:如25,13.4,“valueis”,它们的内容保持不变。◆常量:数据声明时在变量名前冠以保留字const,如constintM

AX=500,可定义一个常量。其内容在声明时给定,在声明它的程序运行时内容再赋值无效。◆变量:数据类型的实例,在程序执行时可以改变其内容。19◼C++提供两大类数据类型:基本数据类型和复合数据类型。◼基本数据类型有5种:整型(int)、浮点型(float)、字符型(char)、双精度浮点型(do

uble)和无值(void)。◼复合数据类型包括结构(struct)、联合(union)、位域、枚举(enum)、类(class)和用户自定义类型。◼此外还有由基本数据类型和复合数据类型引申而来的数据类型,包括数组、指针、引用等。

20◆枚举:是声明一个整型常数序列的方式。例如,在程序开头做如下声明enumBoolean{FALSE,TRUE}则建立一个Boolean类型。FALSE,TRUE都是Boolean类型整型常数,默认值0和1。◆指针:存放对象的存储地址

,例如inti=5;int*np;//np为一个指向整型量的指针np=&i;//把整型变量i的地址赋给它//np成为指向整型变量i的指针intk=*np;//k中存入np所指地址i的内容21◆引用:它用来给一个对象提供一个替代的名字。例如inti=5;int&j=i;i=7

;printf(“i=%d,j=%d”,i,j);此时,j是一个引用类型,它代表i的一个替代名。当i的值改变时,j的值也跟着改变。当printf语句执行后,打印出的i和j的值都是7。22C++的作用域◼在C++中,每个变量都有一个作用域。区分一个变量时要同时考虑变量名及

其作用域。◼在函数定义中声明的变量,仅能在该函数内部有效使用◼在类定义中声明的变量,仅能在该类内部有效使用◼在一个段中声明的名字,也仅能在该段及其子段中有效使用。23◼在整个程序各处都能访问的变量叫做全局变量。如果一个全局变量在文件1中声明,在文

件2中使用,那么在文件2中必须使用保留字extern对该变量进行声明。◼如果在构成一个程序的两个文件中分别声明了两个同名的全局变量,这两个变量分别代表两个不同实体,此时需在两个文件中分别使用保留字static对变量进行声明。◼如果一个段中的局部变量与一个全局变量同名,且还要在此段中使用该

全局变量,此时需利用域操作符::访问该全局变量。24表达式与操作符◼表达式是用来说明简单计算的。◼C++中的表达式由操作数和操作符组成,它将操作符施加于操作数,最终得到一个结果。结果的数据类型由参加运算

的数据类型决定。aa+b*c+2002**R(x+y)/(a–b)◼其中操作符执行的先后顺序由它们的优先级和结合性决定。25◼C++提供了很多预定义的操作符,程序员也可以重新定义这些操作符。◼算术操作符:+、-、*、/、%。其中*、/

、%优先于+、-。括号用来改变计算顺序。计算时,先计算括号内表达式的值,再将计算结果与括号外的数一起计算,如:4*(1+2)=4*3=12◼取模操作符(%)用于计算两整数相除后得到的余数,如:22%7=1。◼注意,%只能用于

整数相除,不能对浮点数操作。26◼赋值操作符“=”将其右侧的表达式求出结果,赋给其左侧的变量。例如:intValue;Value=(2+3)*4;◼赋值表达式运算的结果是右运算元的值,而结果类型是左运算元的数据类型,例如:Value=2.8*4//结果为11,而不

是11.2◼可以连续赋值,但必须保证各运算元的类型相同。它的处理结果是每个运算元的对象值都为最右侧的运算元值,例如:inti,j;i=j=0;//i,j都赋为027◼复合操作符:◼加a+=b等价于a=a+b◼减a-=b等价于a=a-b◼乘a*=b等价于a=a*b◼除a/=b等价于a=a/b

◼取模a%=b等价于a=a%b◼左移一位a<<=b等价于a=a<<b◼右移一位a>>=b等价于a=a>>b◼按位与a&=b等价于a=a&b◼按位异或a^=b等价于a=a^b◼按位或a|=b等价于a=a|b28自增,自减操作符◼自增(++),自减(--):a++等价

于a=a+1a--等价于a=a-1◼自增、自减符号既可位于变量的前面,也可位于变量的后面。前缀++表示先将其后的变量值增1,然后将增1后的变量参与表达式运算;而后缀++表示将其前面的变量先参与表达式运算,然后变量本身增1。◼在单独作为一个表达式时,++a和a++效果

一样,都是将变量a自增1。◼自减操作符含义类似。29◼若自增(++),自减(--)符作为一个复杂表达式的一部分时,如:(a++)+b和(++a)+b效果就不一样:在a、b初值均为1的条件下结果不同。运算前表达式运算后运算结果ab

ab11(++a)+b21311(a++)+b21230条件操作符◼条件操作符是C++中惟一的具有三个运算元的操作符,其形式为:表达式1?表达式2:表达式3◼它的运算方式为:先计算表达式1的值,如果其值为非零(true),则表达式2的值就是整个表达式的最

终结果,否则表达式3的值就是整个表达式的值。常见的一个例子为:#defineMIN(x,y)((x<y)?x:y)◼上例定义了一个求两个数x和y中的最小值的宏,其中决定哪一个是最小值用了条件操作符。31

语句◼语句是C++程序中最小的可执行单元。一条语句由一个分号结束。◼语句可以是简单语句,也可以是复杂语句。intradius;是声明语句;circum=2*PI*radius;是表达式语句;它由一个表达式后接一个分号形成。cout<<"hello,world";cin>>Valu

e;等都是简单语句。这些语句告知计算机该如何定义变量以及如何执行程序。32◼除简单语句外,C++还定义了一些可以控制程序执行流程的语句,这些语句提供对控制流的分支和循环功能。◼C++中,语句缺省都是顺序执行,如果碰到分支或循环语句,顺序执行的规则就要改变。此外,C

++中还有一些跳转语句。◼有时还有一些语句需要合在一起作为语法结构中的一条语句,这时需要将这些语句用大括号括起来,形成一个复合语句,复合语句不需要以分号终结。33if语句(二分支选择型)◼if语句的一般格

式为:if(条件表达式)语句;◼如果条件表达式的结果为true(非零值),则执行语句语句,否则跳过这段语句。◼语句可以有多条,这时需用大括号{}将这些语句括起来,形成一条复合语句。if(条件表达式){语句1;语句2;……}

34◼如果希望在条件满足和不满足时分别执行不同语句,则用else引入条件不满足时的语句:if(条件表达式)语句1;else语句2;◼语句1,语句2也可以是复合语句,不过这时的语句不需以分号结尾。◼语句1、语句2中又可以出现if语句,所以if语句可以嵌套,不过这时容易带来语

义的歧义性。35例if(ch>='0')if(ch<='9')cout<<“这是一个数字!”;elsecout<<“这不是一个数字!”;◼这时else与哪个if匹配呢?为解决语义上的这种歧义性,C++中规定,else总是与最后一个出现的还没有else与之

匹配的if匹配,所以上面一句的else与第二个if匹配,如果程序员想让它与第一个if匹配,可以用大括号将不与else匹配的if语句括起来,使之成为复合语句。36if(ch>='0'){if(ch<='9')cout<<“这是一个数字!”;}elsecout<<“这不是一个数字!”;

◼条件表达式用于程序有分支语义的场合。◼下例判断两个数是否从小到大排列,如果不是,则交换两个数:voidswap(intx1,intx2){if(x1>x2){inttemp=x1;x1=x2;x2=temp;}}37Switch语句(多分支选择

型)◼switch语句用于有多重选择的场合,形式为switch(表达式){case值1:语句组;break;//break可没有case值2:语句组;break;//break可没有……case值n:语句组;break;//break可没有def

ault:语句组;};◼注意case后的数值必须是一个整型的常量表达式,且任意两个选择项不能相等。38◼当switch语句执行时,先计算其后的表达式值,将表达式的值与后面各case关键字后所跟选择常量依次比较。◼如果与某

一选择常量相等,则执行其冒号后跟的语句。如果和任何选择常量都不等,则执行default子句后的语句(如果default子句存在)或什么也不做(如果default子句不存在)。◼每个case子句都以break语句结束。break子句的作用是终止当前switch语句的执

行。39◼例:统计文章中各字母出现的次数。程序每读入一个字符ch,根据它的值,将相应的计数值增1,假定英文大小写不区分。intaCnt=0,bCnt=0,…,zCnt=0;switch(ch){case'a':case'A':aCnt++;break;case'b

':case’B':bCnt++;break;//case'z':case’Z':zCnt++;break;}40循环语句◼循环语句提供重复处理的能力,当某一特定条件为true时,循环语句就重复执行,并且每循

环一次,就会测试一下循环条件,如果为false,则循环结束,否则继续循环。◼C++支持三种格式的循环语句:while、do和for语句。三者可以完成类似的功能,不同的是它们控制循环的方式。41While语句(先判断循环)◼while语句的一般形式为:while(条件表达式)循环体语句◼while

循环先计算条件表达式,当条件表达式的运算结果为true时,就执行循环体语句。执行一次循环体语句后,就会重新计算条件表达式,当表达式的值为false时,循环结束。◼while循环可能一次也不执行。42◼下列程序计算输入文件的字符数,并在标准输出上输出文件内容:#include<iostream.h>

#include<fstream.h>main(){charch;intcount=0;//字符数计数器ifstreaminfile("data.in",ios::in);while(infile&&infile.get(ch)){cout<<ch;co

unt++;}cout<<"count:"<<count;return(0);}43do语句(后判断循环)◼do语句的一般形式为:do循环体语句while(条件表达式);◼do语句先执行循环体语句,然后计算条件表达式是否为true,如果是,则继续执行循环,否则结束循环。◼与while

语句不同的是,do循环中的循环体语句至少执行一次,而while语句当条件第一次不满足时循环体语句一次也不执行。44◼对字符计数的程序也可以用do语句实现。#include<iostream.h>#include<fstream.h>intmain(){c

harch;intcount=0;//字符个数计数器ifstreaminfile("data.in",ios::in);if(infile&&infile.get(ch)){do{cout<<ch;count++;}while(infile&&infil

e.get(ch));cout<<"count:"<<count;}return(0);}45for语句◼for语句用于预先知道循环次数的情况,其一般形式为:for(初始化语句;表达式1;表达式2)循环体语句;◼其中初始化

语句可以是一条声明或表达式,用于对循环控制变量进行初始化或赋值。◼表达式1用于控制循环结束,当它的值为true时,继续循环,为false时终止循环。◼表达式2在每次循环执行后改变循环控制变量的值。46◼具体来说,for循环的执行过程为:执行初始化语句;计算表达式1

的值;如果表达式1的值为true:▪先执行循环体语句;▪再执行表达式2;▪然后转向步骤;如果表达式1的值为false,则结束循环。47◼例:数组初始化for(inti=0;i<size;i++)array[i]=0;array[i]=0i++i<

sizei=0TrueFalse48跳转语句◼除了顺序执行和分支、循环外,有时需要中断一段程序的执行,跳转到其它地方继续执行,这时需用到跳转语句。◼跳转语句包括break、continue和goto语句。break语句◼break语句将使程序从当前的循环语句(do,while,for)内跳转出

来,接着执行循环语句后面的语句。Switch语句中也用到了break语句,这时它表示终止当前switch语句的执行,接着运行switch后的语句。49continue语句◼continue语句也用于循环语句,它不是结

束循环,而是结束循环语句的当前一次循环,接着执行下一次循环。在while和do循环中,执行控制权转至对条件表达式的判断,在for循环中,转去执行表达式2。goto语句◼goto语句无条件转移程序的执行

控制,它总是与一标号(label)相匹配,其形式为:goto标号;50◼标号是一个用户自定义的标识符,它可以处于goto语句的前面,也可以处于其后面,但是标号必须与goto语句处于同一个函数中。◼标号定义时,由一个标

识符后面跟一冒号组成,如:gotonext;……next:语句//标号51◼下面程序要从键盘读入用户输入的数,对其求和,当用户输入数0时,表示输入结束。#include<iostream.h>intmain(){intsum=0;intiVal

;while(1){//永远循环cout<<“请输入一个整数或0:”;cin>>iVal;if(iVal==0)break;//循环出口sum+=iVal;}cout<<”Thesum:”<<sum<<‘\n’;return0;}52◼下面程序对用户输入的所有正数求和,如果输入的是负

数,则忽略该数。intsum=0;intiVal=1;while(iVal!=0){cout<<"请输入一个整数或0:";cin>>iVal;if(iVal<0)continue;sum+=iVal;}cout<<“Thesum:”<<

sum<<‘\n’;53C++的类◼C++的核心部分是类的定义。类定义体现了抽象数据类型的思想。为达到信息隐蔽的原则。规定对类的成员有三级存取:◆共有(public)◆私有(private)◆保护(protected)

◼在public域中声明的数据成员和函数成员(成员函数),程序中其它类的对象或操作都能请求该类的对象执行它们,因此这些数据成员和成员函数构成类的界面部分。54◼在private域和protected域中声明的数据成员和成员函数构成类的私有部分,只能由该类

的对象和成员函数,以及声明为友元(friend)的函数或类的对象才能访问它们。◼在protected域中声明的数据成员和成员函数,还允许该类的派生类访问它们;◼在private域中声明的数据成员和成员函数,

则不允许该类的派生类访问它们。◼下面给出一个point类的声明。Point类中点的表示由两个整数变量x,y组成。类的用户不能直接访问它们。55#ifndefPOINT_H#definePOINT_H//Intheheaderfilepoint.hclassPoi

nt{//类定义private://私有域intx;//数据成员:点坐标inty;public://共有域Point(int,int);//构造函数Point(Point&);//复制构造函数~Point();

//析构函数intget_x();//取x坐标intget_y();//取y坐标56Pointoperator+(point);//点加点Pointoperator/(int);//点除整数Pointoperator*(int);//点乘整数intoperator>(Point);//点比较i

ntoperator<(Point);//点比较intoperator==(Point&);//点比较friendistream&operator>>(istream&,Point&);//输入友元函数friendo

stream&operator<<(ostream&,Point&);//输出友元函数};#endif57◼为了存取一个点的x,y分量,类提供了两个函数get_x,get_y。这样可用private域来保护数据的表示,防止类的用户直接使用数据的内部表示来编写代码,通过使用存取函数来

操作数据来维持类的抽象性。◼private是声明默认的存取级别。◼系统开发时,把类的声明放在头文件中,成员函数的实现放在源程序文件中。在源程序文件中函数的实现通过作用域设定命令“::”而被归属到某一个类。58例,对于Point类的输出友元函数的实现可以在源程序文件中给出,形为:o

stream&operator<<(ostream&strm,Pointp){returnstrm<<"("<<p.get_x()<<","<<p.get_y()<<")";}这个函数把点p的值以“x,y”的格式送到strm指明的输出流中去。59C++

中的对象◼建立类的对象(亦称为实例化)时采用的方式类似于定义C变量的方式,可以自动地,或静态地,或通过动态分配来建立。建立一个Point类实例的语句是:◆Pointp(6,3);自动地◆Pointq;自动地◆staticPoints(3,4);静态地◆Point*t=newPoint(1,1

);通过动态分配◼对象p、q和s都是Point类的对象。60构造函数◼当遇到以上的每一个语句时,将隐式地调用一个构造(constructor)函数,这个构造函数属于一个与它同名的类。◼在Point类的定义中声明了两个构造函数,构造函数的参数用于初始

化表达式的值。◼例如,当使用声明Pointp(6,3)建立Point类的对象p时,调用了构造函数Point(int,int);通过以下函数定义,将其x,y分量设定为6,3:Point::Point(inta,intb){x=a;y=b;}Point::Point(inta,in

tb):x(a),y(b){}61◼构造函数可以定义默认值。例如Point::Point(inta=0,intb=0):x(a),y(b){}◼当定义实例时给定初始值,则该实例以给定初始值来初始化其数据成员。Pointp(6,3);则有x=a=6,y=b=3◼当

定义实例时未给出初始值。则该实例以默认值来初始化其数据成员。Pointq;则有x=a=0,y=b=062析构函数◼当要放弃对象时,需隐式地调用另一个函数,叫做析构(destructor)函数,它属于名字相同

的类,但在名字前面加上了一个“~”。例如~Point。◼为一个类可定义几个构造函数,但只能定义一个析构函数。当控制要退出自动变量的作用域时,或当通过delete命令释放一个动态分配的变量时,就要调用析构函数。当main函数执行结束时,将释放

静态声明的变量。◼一个析构函数用于在删除一个类的对象时做清除工作。63C++的输入/输出◼在C++中执行输入/输出操作,需用#include预处理指令包括一个<iostream.h>头文件。用它可支持C++的流(stream)操作

。◼“流”是个简单的字符序列。在C++中有两个预定义的类istream和ostream,它们定义了输入流和输出流。◼基本输入/输出方式:◆键盘屏幕输入/输出;◆文件输入/输出。64键盘屏幕输入/输出◼在C中有用于定向到键盘输入设备、屏幕输出设备和错误文

件的命令stdin、stdout和stderr。◼在C++中用cin,cout和cerr来定义键盘输入类、屏幕输出类和错误信息输出类。◼操作符<<用于写出类ostream的一个对象,对于一系列输出对象,可用<<分开。◼操作符>>用于读入类istream的一个对象。65◼在下面程序中使用

了流cin>>,相继从标准输入设备上输入两个整型变量a和b,并将它们打印到标准输出设备上。◼在输出语句中最后输出的endl是C++的I/O操作符,它的用途是输出一个换行符并清空流。#include<iostream.

h>voidmain(){inta,b;cin>>a>>b;cout<<”a:"<<n<<"f:"<<f<<endl;}66◼C++中的输入/输出可以是自由格式,程序员不需要使用格式化符号来指定输入/输出项的类型和顺序。◼与其它C++操作符一样,输入/输出操作符能够被重载。67文件输

入/输出◼C++中的文件输入/输出方式如下所示。◼在程序开头必须用预处理指令#include包含头文件<fstream.h>,它定义了类ifstream、ofstream和fstream。◼要创建一个输入流,必须声明它为ifstream类的实例。◼要创建一个输出流,

必须声明它为ofstream类的实例。◼执行输入和输出操作的流必须声明它为fstream类的实例。68#include<fstream.h>#include<iostream.h>#include<stdlib.h>voidmain(){ifstre

aminFile;//inFile为输入流对象ofstreamoutFile;//outFile为输出流对象outFile.open("my.dat",ios::out);//建立输出文件my.datcharuniv[]=Tsinghua,name[10];intcourse

=2401,number;outFile<<univ<<endl;//输出到my.datoutFile<<course<<endl;69inFile.open("my.dat",ios::in|ios::nocreate)

;//打开输入文件my.datif(!inFile){cerr<<“不能打开my.dat”<<endl;exit(1);}charc;inFile>>name>>c>>number;outFile<<"name:"<<name<<endl;outFile

<<"number:"<<number<<endl;}70◼ifstream类、ofstream类和fstream类都是从istream类和ostream类派生出来的,而类istream和ostream又是从类ios派生出来的,因此这

些类都可使用类ios的所有运算。◼在调用打开文件函数open()时,函数参数表包括实际文件名和数据流动的方向,函数返回文件的开始地址。系统在存储文件时,在其末尾添加有文件结束标记。◼如果文件未被打开,则outFile=0;如果文件被成功地打开

,则它将代替cout,将输出引导到文件my.dat中。71◼在文件打开的操作中,指定的文件模式有以下几种:◆iso::app:把所有对文件的输出添加在文件尾。它只用于输出文件。◆iso::binary:文件以二进制方式打开。此项缺省时文件以文本方式打开。◆iso::nocreate

:若文件不存在则将导致打开操作失败。◆iso::out:表明该文件用于输出。此项可缺省。◆iso::in:表明该文件用于输入。此项可缺省。72C++中的函数◼在C++中有两种函数:常规函数和成员函数。◼不论哪种函数,其定义都包括4个部分:函数名、形式参数表、返回类型和

函数体。◼函数的使用者通过函数名来调用该函数;调用时把实际参数传送给形式参数表作为数据的输入;通过函数体中的处理程序实现该函数的功能;最后得到返回值作为输出。73◼下面给出一个函数的例子。max是函数名

,inta和intb是形式参数表,函数名前面的int是返回类型,在花括号内括起来的是函数体,它给出了函数操作的实现。intmax(inta,intb){//函数返回a与b中的大值if(a>b)returna;elsereturnb;}◼在C++中所有函数都有一个返回值,或者返回计算结果,

或者返回执行状态。74◼如果函数不需要返回值,可使用void来表示它的返回类型。函数的返回值通过函数体中的return语句返回。◼return的作用是返回一个与返回类型相同类型的值,并中止函数的执行。◼函数返回时可以通过引用方式,参看下面程序,此时在函数

类型后面加上一个“&”。#include<iostream.h>char&replace(intm);chars[80]=“HelloThere”;75main(){replace(5)=‘x’;cout<<s;//用x

代替Hello后面的空格}char&replace(intm){returns[m];}◼函数replace()的返回类型说明为返回一个字符的引用类型,在函数执行时返回参数m指定的s数组元素的值。main()执行时把字符

“x”送给s[5]。76C++中的参数传递◼函数调用时传送给形参表的实参必须与形参在类型、个数、顺序上保持一致。◼参数传递有两种方式。一种是传值,这是缺省的参数传递方式;一种是引用类型。◼使用传值方式时,把实参的值传送给函数局部工作区相应的副本中,函数使用这个副本执行必要的功能。这样

,函数修改的是副本的值,实参的值不变。77◼使用引用类型方式传递时,需将形参声明为引用类型,即在参数名前加一个“&”。参看下面的程序示例。◼当一个实参与一个引用型形参结合时,被传递的不是实参的值,而是实

参的地址,函数通过地址存取被引用的实参。函数执行后实参的值将发生改变。◼当一个函数的返回值多于一个时,其中一个可由return语句返回,其它返回值可使用引用型参数返回。#include<iostream.h>voidswap(int&i,int&j);78main(){inta=1,b=2;

cout<<"aandb:"<<a<<""<<b<<"\n";swap(a,b);//调用时实际参数不需要加&cout<<"aandb:"<<a<<""<<b<<"\n";}voidswap(int&i,int&j){//对换i与j的内容intt=j;j=i;i=t;//不需要加*}79◼一种特

殊的引用调用方式叫做常值引用,其格式为constType&a,其中Type为参数的数据类型。在函数体中不能修改常值参数。◼一种特殊情况是数组参数的传递。数组作为形参可按传值方式声明,但实际采用引用方式传递,传递的是数组第一个元素的地址。在函数体内对形参的数

组所做的任何改变都将反映到作为实参的数组中。◼此外,在参数表中一般按形如intR[]的形式声明,因此需要显式地声明数组的大小。80◼若传送的值参是一个对象(作为类的实例)时,在函数中就创建了该对象的一个副本。在创建这

个副本时不调用该对象的构造函数,但在函数结束前要调用该副本的析构函数撤消这个副本。◼若采用引用方式传递对象,在函数中不创建该对象的副本,也不存在最后撤消副本的问题。但是,通过引用传递的是对象时,函数对

对象的改变将影响调用的对象。81成员函数的返回值◼当成员函数的返回值为传值方式时,允许改变该对象的私有数据成员。◼当成员函数的返回值为常值传值方式时,需加const标识,该对象的私有成员不能改变。◼当成员函数的返回值为引用方式时,该成员函数的返回值应是

一个已存在变量(或对象)的别名。当该成员函数被重新赋值时,其对应变量(或对象)的值将改变。◼当成员函数的返回值为常值引用方式时,其返回值与引用方式的成员函数返回值类同。但该成员函数不能改变该对象的私有成员。82◼当成员函数返回值为常值传值方式或常值引

用方式时,const标识符一般放在最后。#include<iostream.h>classTemperature{private:floathighTemp,lowTemp;//数据成员public:Temperat

ure(inthi,intlo)//构造函数{highTemp=hi;lowTemp=lo;}voidUpdateTemp(floattemp);//传值返回floatGetHighTemp()const;//常值返回83floatGetLowTemp()con

st;//常值传值返回};voidTemperature::UpdateTemp(floattemp){if(temp>highTemp)highTemp=temp;if(temp<LowTemp)LowTemp=temp;}floatTemperature::GetH

ighTemp()const{returnhighTemp;}floatTemperature::GetHighTemp()const{returnhighTemp;}84C++中的函数名重载◼函数名重载允许C++程序中多个函数取相同的函数名,但其形参或返回类型可以不同。◼例如,C标准函数库

中有3个标准函数abs()、labs()和fabs(),分别计算整型数、长整型数和双精度型数的绝对值。在C中因处理的数据类型不同,必须取不同的函数名。在C++中,可以把这3个函数都命名为abs():intabs

(int);longabs(long);doubleabs(double);85C++的操作符重载◼C++提供了一种能力,可用同一个名字定义多个函数,这种能力叫做操作符重载。◼例如,可以命名一个函数:clear(*int),它将一个整数清零。还可以再命名另

一个函数clear(int[]),它把一个整数数组清零。◼编译器能够比较具有同名的函数的特征,通过识别实参的数目和每个实参的类型,来标识使用于一个特定调用的是哪一个版本的abs()。86◼在C中,必须使用名字clearIntArray()和clearInt()来区分这

两个函数。在C++中,编译器能够比较同名函数的特征,通过识别实参的数目和每个实参的类型,来标识一个特定调用中用的是哪一个版本的clear。◼为了支持面向对象,C++提供了双目重载操作符(如‘+’和‘<’)。这种操作可使得程序更可读、写得更自然。◼例如,可定义“点(Point)”的

运算,像◆p1+p2:把两个点(x1,y1)和(x2,y2)相加成一个点(x1+x2,y1+y2)。87◆p1<p2:两个点p1和p2的“小于”关系,表示p1比p2更靠近原点(0,0)。◆p1/i:一个点p=(x,y)

除以一个整数i的除法(x/i,y/i)。◼可以按以下方式使用重载操作:Pointoperator+(Pointp);Pointoperator/(inti);intoperator<(Pointp);◼使用这些新的操作的表达式如:PointmidPoint=(point1+point2)/

2;或if(midPoint<referencePoint)...88◼注意:每一个这样的操作符在调用时可看成是该操作符左边对象的成员函数。◼例如,(point1+point2)实际上是一个消息。由类Poi

nt的实例point1调用成员函数“+”,该对象的属性确定第一个操作数的值。◼函数参数表中指定的Point的实例point2的属性确定第二操作数的值。◼这种重载能力允许像使用内建类型(如int,float)那样来使用用户自定义类型

。与在不允许重载操作的语言中相同的语句比,这样可以改善程序的可读性。89C++的动态存储分配◼在C程序中,使用一个函数malloc,为程序分配它所需要的空间,一旦程序执行结束需要返回到它的调用者时,必须释放这个空间。◼C++为动态存储分配提供了两个新的命令:new和delete。它们可用于取代C

中的库函数malloc和free。◼在C++中没有无用单元收集,使用new分配的存储必须显式地使用delete释放。90◼操作new要求以被建立对象的类型做为参数,并返回一个指向新分配空间的指针。◼作为对比,在C中,函数malloc要求它的调用者提供所需存储空间的数量。◼例如,为动态分配一个整

数或一个点,可编写如下语句:int*ip=newint;或Point*p=newPoint;◼它们组成了指针变量的声明(如*name)和动态存储分配(new类型)。91◼Delete命令必须能够知道new分配了多少存储。当要释放动态分配的数组时,必须告

诉delete该数组中包含的元素个数。◼例如,如果已建立下列有100个点的数组:Point*p=newPoint[100];◼则通过以下命令释放该存储:delete[100]p;◼若遗漏了“[100]”,则将只释放p所指示的第一个元素,将“失去”其它99个点所

占据空间,以致不能再复用它们。若使用时元素下标超出100,程序将会出错且结果不可预测。92友元(friend)函数•在类的声明中可使用保留字friend定义友元函数。•友元函数实际上并不是这个类的成员函数,它可以是一个常规函数,也可以是另一个类的成员函数。如果想通

过这种函数存取类的私有成员和保护成员,则必须在类的声明中给出函数的原型,并在该函数原型前面加上一个friend。•参看Point类的声明,有两个重载操作符<<与>>,它们都被声明为友元函数。93内联(inline)函数◼在函数定义前加上一个inline前缀就成为内联函数。编译程

序在编译时将会把这个函数语句直接插入到普通代码中,因而减少了与函数调用和参数传递有关的系统开销。◼直接插入代码所需要的空间比不直接插入的调用方式所需要的空间要多,这取决于函数定义的大小。◼除了加上inline保留字外,内联函数的定义与其它任何函数定义的

方式一样。inlinePointoperator+(Pointp);94结构(struct)与类◼C++扩充了C中结构(struct)型的功用,加进成员函数以说明一个类(class)。在C++中struct与c

lass的区别在于:◼在struct中,默认的访问级别是public。若在struct内部自始至终缺省访问级别,则所有的成员都是共有的。◼在class中,缺省的访问级别是private。◼除此之外,struct与class是等价的。例如,下面给出定义矩形类

的三种等价的类声明。95classRectangle{intx1,y1,h,w;public:Rectangle();~Rectangle();intGetX();intGetY();voidSetX(intx)

;voidSetY(inty);intGetHeight();intGetWidth();…………}96structRectangle{Rectangle();~Rectangle();intGetX();intGetY();voidSetX(intx);v

oidSetY(inty);intGetHeight();intGetWidth();…………private:intx1,y1,h,w;}97联合(Union)与类◼与结构一样,用Union也可以定义类。◼在C++中,Union可包含函

数和变量,还可包含构造函数和析构函数。◼C++的Union保留了所有C的特性,主要是让所有的数据成员共享相同的存储地址。◼与class和struct相比,Union可节省存储。与结构相似,Union中默认存取级别是public。98模板(template)定义适合多

种数据类型的类定义或算法,在特定环境下通过简单地代换,变成针对具体某种数据类型的类定义或算法。99用模板定义用于排序的数据表类#include<iostream.h>template<classType>classdataList{private:Type*Element;intArraySize

;voidSwap(intm1,intm2);intMaxKey(intlow,inthigh);100public:dataList(intsize=10):ArraySize(size),Element(newType[Size]){}~dataList

(){delete[]Element;}voidSort();friendostream&operator<<(ostream&outStream,datalist<Type>&outList);friendistream&operator>>(istream&inStream,

datalist<Type>&inList);}101类中所有操作作为模板函数的实现#include“datalist.h”template<classType>voiddataList<Type>::Swap(

intm1,intm2){//交换由m1,m2为下标的数组元素的值Typetemp=Element[m1];Element[m1]=Element[m2];Element[m2]=temp;}102template<classType>intdataList<Type>::M

axKey(intlow,inthigh){//查找数组Element[low]到Element[high]//中的最大值,函数返回其位置intmax=low;for(intk=low+1,k<=high,k++)if(Element[

max]<Element[k])max=k;returnmax;}103template<classType>ostream&operator<<(ostream&OutStream,dataList<Type>OutList){OutStrea

m<<“数组内容:\n”;for(inti=0;i<OutList.ArraySize;i++)OutStream<<OutList.Element[i]<<‘’;OutStream<<endl;OuStream<<“数组当前大小:”<<OutList.ArraySize<<endl;retur

nOutStream;}104template<classType>istream&operator>>(istream&InStream,dataList<Type>InList){cout<<“录入数组当前

大小:”;Instream>>InList.ArraySize;cout<<“录入数组元素值:\n”;for(inti=0;i<InList.ArraySize;i++){cout<<“元素”<<i<<“:”;InStream>>InLis

t.Element[i];}returnInStream;}105template<classType>voiddataList<Type>::Sort(){//按非递减顺序对ArraySize个关键码//Element[0]到Element[ArraySi

ze-1]排序for(inti=ArraySize-1;i>0;i--){intj=MaxKey(0,i);if(j!=i)swap(j,i);}}106使用模板的选择排序算法的主函数#include“selecttm.h”

constintSIZE=10;intmain(){dataList<int>TestList(SIZE);cin>>TestList;cout<<TestList<<endl;TestList.Sort();cout<<TestList<<endl;return0;}1

07

精品优选
精品优选
该用户很懒,什么也没有留下。
  • 文档 34925
  • 被下载 0
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?