




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
清华大学C语言教学课件(共16个PPT)第15个一、程序设计方法概述2程序设计方法早期的程序设计方法结构化程序设计方法面向对象程序设计方法3 早期的程序设计方法追求程序的高效率,编程过份依赖技巧,而不注重所编写程序的结构,也就是没有固定程序设计方法的时期。程序的可读性、可重用性都很差。其中一个典型问题是频繁使用goto语句。 虽然这种方法存在很多问题,但对于单人完成较为简单的任务,事实上还是经常被采用的。早期的程序设计方法4 结构化方法出现在70年代中期,我们可以这样理解它: 结构化程序设计方法是从程序要实现的功能的角度出发的。一般按照自顶向下、逐步求精的方式,将程序要完成的功能逐级划分成许多小的功能模块,象搭积木一样搭起来。这些小的功能模块最终都可以转化成三种基本控制结构的组合。 所谓的功能可以理解为对数据的操作。在程序实现中,特定的功能或功能模块一般用函数来实现,它们要对特定的数据进行操作。结构化程序设计方法5结构化设计方法的特点结构化程序设计方法的主要技术是自顶向下、逐步求精,采用单入口、单出口的控制结构自顶向下是一种分解问题的技术,逐步求精指结构化程序的连续分解,最终成为下面三种基本控制结构的组合三种基本控制结构:顺序、分支、循环6分支结构语句1语句2语句3条件语句2语句1语句1语句2顺序结构循环结构7例: 从键盘输入一个学生的信息(包括姓名、年龄、性别、学号等)和一个老师的信息(包括姓名、年龄、性别、是否授课等),然后将信息输出到屏幕。一个简单的例子8分析: 根据需求(题目要求),我们可以把问题划分为两个功能模块,一个是输入模块,一个是输出模块,做完了输入模块,再做输出模块。再具体考虑每个模块如何实现(逐步求精)。 我们用C语言来写,参看下面的代码:9//……voidmain() //主函数开始{ //声明用于存储学生信息的变量
charstrStudentName[20]; //学生姓名 intnStudentAge; //学生年龄 charcStudentSex; //学生性别 intnStudentNumber; //学生学号 //声明用于存储老师信息的变量
charstrTeacherName[20]; //老师姓名 intnTeacherAge; //老师年龄 charcTeacherSex; //老师性别 intnIsTeaching; //是否授课
//输入模块
GetStudentInfo(…); //输入学生信息 GetTeacherInfo(…); //输入老师信息 //输出模块 PrintStudentInfo(…); //输出学生信息 PrintStudentInfo(…); //输出老师信息}描述学生的数据描述老师的数据函数函数10 上面的例子中,我们可以进一步将属于学生和老师的变量放入结构中。这样可以在一定程度上完成对数据的封装。但在结构化程序设计中,数据与对其进行操作的函数仍是分离的。//声明学生结构StudentstructStudent{
charstrStudentName[20]; //学生姓名 intnStudentAge; //学生年龄 charcStudentSex; //学生性别 intnStudentNumber; //学生学号};//声明老师结构TeacherstructTeacher{
charstrTeacherName[20]; //老师姓名 intnTeacherAge; //老师年龄 charcTeacherSex; //老师性别 intnIsTeaching; //是否教书};1112问题: 函数用于完成一定的功能,它们都是针对特定的数据进行操作的。那么我们能不能以特定的数据为中心,将数据与对其进行操作的函数封装起来呢?13面向对象程序设计方法面向对象程序设计出现在80年代中后期面向对象程序设计是建立在结构化程序设计基础上的,但它不再是从功能入手,而是从对象(人、地方、事情等)入手面向对象程序设计以类作为构造程序的基本单位,它具有封装、数据抽象、继承、多态等特点14 简单地说,对象就是现实世界中的各种实体,包括人、地点和事物等。例如,桌子、椅子、教室、学生、老师、电话、汽车等等。一般都要从属性和行为两个方面来对它们加以描述。在这里,我们认为对象和对象的实例是同一个概念。什么是对象?15
对象具有的一些特征称为属性,以一个人为例,他的姓名、年龄、身高、体重等可以作为他的属性。这些属性会有其对应的值,一般至少会有一项区别于其它对象,它们在程序设计中对应的是一定的数据。 为了达到目的,对象必须提供的功能(或必须提供的服务)称为对象的行为,在程序设计中对应一定的方法(函数)。属性和行为16
类描述了一组具有相同属性(数据元素)和相同行为(函数)的对象。 类的数据成员是对对象属性的抽象,类的函数成员是对对象行为的抽象,而类本身就是对对象的抽象。什么是类?17classStudent //Student类的声明{public: //公有成员 Student(); //构造函数
~Student(); //析构函数 char* GetName(); //查询姓名 int GetAge(); //查询年龄
char GetSex(); //查询姓名
int GetNumber(); //查询学号 bool SetName(char*n); //设置姓名 bool SetAge(intage); //设置年龄
bool SetSex(char*s); //设置性别
bool SetNumber(intnum);//设置学号protected: //保护成员
char m_strName[20]; //姓名,字符串数组 int m_nAge; //年龄,整型 char m_cSex; //性别,字符型
int m_nNumber; //学号,整型};例:C++中类的声明——Student类成员函数成员函数成员变量18……StudentA; //声明Student的对象AA.SetName(“张三”); //设置A的名字A.SetAge(20); //设置A的年龄……例:C++中类使用1920总的来说,结构化程序设计方法是一种模块化程序设计方法,它在解决问题时是以功能为中心的,一定的功能模块虽然也作用于特定的数据,但它们并没有被封装在一起。面向对象程序设计方法则是以对象为中心来解决问题的。属于同种对象的属性(数据)和服务(功能)被抽象出来封装到一起。21二、面向对象程序设计方法22数据抽象封装继承多态动态绑定面向对象方法的主要特点23数据抽象 类是一组相似对象的抽象描述,它抽取了这些对象的共性组成了一个共同的概念。抽象数据类型(AbstractDataType,ADT)是一组相似的类的抽象,而一个类又是ADT的具体实现。24 封装是指软件的组成部分(模块、子程序、方法等)应该互相独立,或者隐藏设计的细节。在传统的方法中,封装通常局限于将功能和数据分开封装;而在面向对象方法中,封装将功能和数据同时装入对象中。
参看Student类的例子封装25classStudent //Student类的声明{public: //公有成员 Student(); //构造函数
~Student(); //析构函数 char* GetName(); //查询姓名 int GetAge(); //查询年龄
char GetSex(); //查询姓名
int GetNumber(); //查询学号 bool SetName(char*n); //设置姓名 bool SetAge(intage); //设置年龄
bool SetSex(char*s); //设置性别
bool SetNumber(intnum);//设置学号protected: //保护成员
char m_strName[20]; //姓名,字符串数组 int m_nAge; //年龄,整型 char m_cSex; //性别,字符型
int m_nNumber; //学号,整型};例:C++中类的声明——Student类26 如果类与类之间有is-a(是一种)的关系,那么可以采用继承机制来表示。子类可以自动继承父类中的一些属性和行为,而不必再进行定义,从而实现了代码的复用。同时,继承也是产生新类的方法之一。继承27 从上图可以看出,学生和教师都是人的一种,所以,学生类和教师类可以从人类继承而来,从而实现了代码的共享。28classPeople //People类的声明{public: //公有成员 People(); //构造函数
~People(); //析构函数 char*GetName(); //查询姓名 int GetAge(); //查询年龄 …… bool SetName(char*n); //设置姓名 bool SetAge(intage); //设置年龄 ……private: //私有成员protected: //保护成员
char m_strName[20]; //姓名,字符串数组 int m_nAge; //年龄,整型 char m_cSex; //性别,字符型 …… };类的声明举例——People类29classTeacher:publicPeople //Teacher类的声明{public: //公有成员 Teacher(); //构造函数
~Teacher(); //析构函数
boolIsTeaching(); //查询是否授课 …… private: //私有成员 …… protected: //保护成员
bool m_bIsTeaching //是否授课 …… };类的声明举例——Teacher类30classStudent:publicPeople{public:
Student(); //构造函数
~Student(); //析构函数
intGetNumber(); //查询学号
boolSetNumber(intn); //设置学号 …… private:
…… protected:
int m_nNumber; //学号 …… };类的声明举例——Student类31 在程序中同一符号或名字在不同情况下具有不同解释的现象称为多态性(Polymorphism)。在面向对象程序设计语言中,由程序员设计的多态性由两种基本形式:编译时多态性和运行时多态性。许多程序设计语言都或多或少地支持多态性,但运行时多态性是面向对象程序设计语言的一大特点。多态32 编译时多态性是指在程序编译阶段即可确定下来的多态性,主要通过使用重载(Overloading)机制获得,重载机制包括函数重载和运算符重载两大类。 举一个C++中的例子: intAbs(intx);
doubleAbs(doublex); cout<<Abs(-4)<<endl;//调用intAbs…
cout<<Abs(3.2)<<endl;//调用doubleAbs…33 运行时多态性是指必须等到程序动态运行时才可确定的多态性,主要通过继承结合动态绑定获得。
动态绑定也称晚绑定,它也是面向对象的重要特点之一。动态绑定的使用可以提高程序的可用性和可扩展性。34 八十年代末以来,由Booch,Coad,Yourdon,OMT,Jacobson等人提出的多种面向对象方法在已经得到了广泛的应用。面向对象方法中的三种基本活动就是:
(1)识别对象和类
(2)描述对象和类之间的关系
(3)通过描述类的功能定义对象的行为面向对象方法35科德将对象模型分为下面四个部件,也就是将对象分为了四组:(1)问题域PD(problemdomain)(2)人机交互HI(humaninteraction)(3)数据管理DM(datamanagement)(2)系统交互SI(systeminteraction)科德(Coad)方法36问题域问题(PD)通常最先考虑,因为用户往往最关心为自己的商业问题建模。问题域部件包含与需要建模的问题直接有关的对象。问题域部件的对象技术上呈现中型,它们几乎不了解或完全不了解人机交互、数据管理和系统交互部件的对象。人机交互部件(HI)包含为问题域对象和人们之间提供界面的对象。在对象模型中,人机交互部件的对象通常对应具体的窗口和报表。37数据管理部件(DM)包含为问题域对象和数据库系统或文件管理系统之间提供界面的对象。在对象模型中,数据管理部件的对象通常对应某些需要保存及搜索的问题域对象。系统交互部件(SI)包含为问题域对象和其它系统或设备提供界面的对象。系统交互对象封装了通信协议,使得问题域对象不需要了解底层的实现细节。38科德的面向对象方法包括一下四个活动:(1)确定系统的目标和特点(2)确定四种模型部件的对象和模式(3)建立对象责任(2)定义服务场景以完成特定服务责任39三、C++语言C与C++的比较C++中的数据类型C++程序框架类和对象类的声明、实现、继承、多态性举例40C语言C语言的优点:与硬件无关,可移植性强语言简洁,使用方便丰富的运算符和数据类型可直接访问内存地址能进行位操作目标代码质量高,运行效率高41C语言的弱点:检查机制弱,编译时不能发现编程错误面向过程的语言,没有支持代码复用的机制很难控制大规模程序的复杂性42C++语言是C的超集,保持了与C的兼容性继承了C语言高效性、灵活性的特点扩充了对面向对象程序设计和高层次问题抽象方法的支持,是面向对象程序设计语言之一完善了C语言的类型检查、代码重用、数据抽象机制,便于大规模软件开发既反映了结构化程序设计方法,又反映了面向对象程序设计方法43#include<iostream.h> //预编译命令voidmain() //主函数开始{ cout<<“Hellotheworld!”<<endl;} //主函数结束一个简单的C++程序的例子 C++中提供的iostream库可以完成对输入输出流的操作,“流”(stream)就是简单的字符序列。在C++中用cin,cout和cerr来定义键盘输入类、屏幕输出类和错误信息输出类。endl用于换行并清空流。如:cin>>a;cout<<“输入的数据为”<<a<<endl;44基本数据类型构造数据类型整型(int)实数型字符型(char)空类型(void)布尔型(bool)引申数据类型结构化数据类型指针(*)引用(&)数组([])结构(struct)联合(union)枚举(enum)类(class)浮点型(float)双精度型(double)C++中的数据类型45引用&一般用于参数传递。&可以认为是取地址。引用类型的变量并不真正创建新的对象,而是作为另一个对象的别名。例如voidswap(int&a,int&b) //用于交换a,b
{
inttemp;
temp=a;a=b;b=temp;
}对形参a,b的操作等价与对实参的操作。46C++程序结构 C++源代码一般都由若干类或函数组成。为了便于管理,一般把不同的类放在不同的文件中,对于类的声明和实现也分别放在对应的.h(或.hpp)和.cpp文件中。 由于文件较多,所以为了便于管理,一般的集成开发工具都会提供工程(Project)管理功能来管理这些文件,对源文件进行编译和链接。4748 为防止重复包含(多次包含同一头文件,造成重复定义)和嵌套包含(互相包含)造成的错误,应该在头文件里加上如下预编译命令。例如,对于test1.h #ifndef__INCLUDE_TEST1_H__
#define__INCLUDE_TEST1_H__
//…
//test1.h的内容
……
#endif说明49class
类名{public:
公有数据和函数protected:
受保护数据和函数private:
私有数据和函数};类的声明注意要有分号50classPeople //People类的声明{public: //公有成员 People(); //构造函数
People(char*name,intage,charsex);
~People(); //析构函数 char* GetName(); //查询姓名 int GetAge(); //查询年龄 char GetSex(); //查询性别 bool SetName(char*n); //设置姓名 bool SetAge(intage); //设置年龄
bool SetSex(charsex); //设置性别private: //私有成员protected: //保护成员
char m_strName[20]; //姓名,字符串数组 int m_nAge; //年龄,整型 char m_cSex; //性别,字符型};类的声明举例——People类51类名是有效的标识符,不能是关键字(保留字)数据成员在声明时不能进行初始化数据成员不能是正在声明的类,但可以用指针
访问控制public,private,protected可以以任意次序出现,并可重复多次有关类的声明52类的成员函数中有两个函数是特殊的,就是构造函数和析构函数,它们没有返回值,且一般不直接调用这些函数,而是在对象建立和撤销时分别被隐式调用的。构造函数的函数名要与类名相同,在创建对象时被调用。可以不定义构造函数,编译程序会自动生成一个缺省的构造函数。析构函数的函数名是在类名前加上一个“~”。同上,也可以不定义析构函数,编译程序会自动生成一个缺省的析构函数。构造函数和析构函数53在类的构造函数中,一般要完成一些初始化的任务。例如将一些指针赋值为NULL,给一些变量赋初值,或者为一些指针分配空间等。还可以利用函数的重载,声明并实现多种构造函数,以完成不同的初始化任务。(参见People类)在类的析构函数中,一般要进行一些收尾工作,如空间的释放。如对于为指针分配的空间,要加以释放,等。构造函数和析构函数54public:
公有成员,可以被任何函数访问(即可以从类的外部进行访问)。private:
私有成员,只有类成员函数和友员类可以访问。protected:
保护成员,只有类成员函数、派生类、友员类可以访问。缺省方式为private
类成员访问控制55People::People() //构造函数{ //函数体开始 //初始化名字为空串 memset(m_strName,0,sizeof(m_strName)); //初始化年龄为0 m_nAge=0; //初始化性别为’0’ m_cSex='0';} //函数体结束People::~People(){} //析构函数类的实现——People类56People::People(char*name,intage=0,charsex=‘0’)//构造函数{ //函数体开始 if(name!=NULL) //初始化m_strname strcpy(m_strName,name); else //如果name为空,则初始化m_strname为空 memset(m_strName,0,sizeof(m_strName)); if((age>=0)&&(age<=200)) //初始化年龄m_nAge { m_nAge=age; } else m_nAge=0; //age不合法,则将m_nAge初始化为0 switch(sex) //初始化性别m_cSex { case‘M’:m_cSex=‘M’;break; //‘M’表示男 case‘F’:m_cSex=‘F’;break; //‘F’表示女 default:m_cSex=‘0’; //‘0’表示未赋值 }}57//查询姓名的成员函数char*People::GetName(){ returnm_strName; //返回姓名}//查询年龄的成员函数intPeople::GetAge(){ returnm_nAge; //返回年龄}//查询性别的成员函数charPeople::GetSex(){ returnm_cSex; //返回性别}//用于设置的成员函数的实现不在此列出//……58voidmain() //主函数{ PeopleA;
//声明类People的对象A PeopleB("LiSi");//声明类People的对象B,参数"LiSi"
//声明类People指针,并构造实例 People*C=newPeople("ZhangSan",20,'M'); A.SetName(“WangWu”);//对对象A设置名字 cout<<“A‘sname:”<<A.GetName()<<endl;//输出A的信息 cout<<"A'sage:"<<A.GetAge()<<endl; cout<<"A'ssex:"<<A.GetSex()<<endl<<endl; cout<<“B‘sname:”<<B.GetName()<<endl;//输出B的信息 cout<<"B'sage:"<<B.GetAge()<<endl; cout<<“B‘ssex:”<<B.GetSex()<<endl<<endl; cout<<“C‘sname:”<<C->GetName()<<endl;//输出C的信息 cout<<"C'sage:"<<C->GetAge()<<endl; cout<<"C'ssex:"<<C->GetSex()<<endl<<endl; deleteC; //释放指针C所指的空间}59A'sname:WangWuA'sage:0A'ssex:0B'sname:LiSiB'sage:0B'ssex:0C'sname:ZhangSanC'sage:20C'ssex:M程序运行结果60//声明类People的对象A,调用没有参数的构造函数PeopleA;//声明类People的对象B,参数"LiSi"PeopleB("LiSi");//声明类People指针,并动态构造实例People*C=newPeople("ZhangSan",20,'M');或: People*C;
C=newPeople("ZhangSan",20,'M');类对象的声明61PeopleA(“ZhangSan”),B; //声明People的对象A和BB=A; //用A初始化对象B对象的复制说明: 这种对象复制可以将A的所有数据成员的值赋给B,如果对象的数据成员中不存在指针,则没有问题,但如果其中含有指针,则这种方式只是简单地把指针所指向的内容的地址复制过来,并没有复制其所指的内容。这可能并不是用户所期望的。这要通过自定义的复制策略来实现:拷贝构造函数和重载运算符“=”。62继承 继承是面向对象程序设计的重要特点之一。它描述了类之间的is-a的关系。如果类B继承类A,则称类A是类B的基类(或父类),类B是类A的派生类(或子类)。63classStudent:publicPeople{public:
Student(); //构造函数
~Student(); //析构函数
intGetNumber(); //查询学号
boolSetNumber(intn); //设置学号private:
protected:
int m_nNumber; //学号};举例——Student类 类声明第一行后面的“:publicPeople”指明了Student类继承自People类。public是继承访问控制,用于指明继承成员在子类中的访问控制。这样,类People中的一些成员就会被Student类自动继承了。64继承成员的访问控制父类访问控制继承访问控制子类访问控制public
protected
privatepublicpublic
protected
不可访问public
protected
privateprotectedprotected
protected
不可访问public
protected
privateprivateprivate
private
不可访问65继承成员的访问控制父类中的私有成员不能继承
继承访问控制为public时,继承父类的访问控制继承访问控制不是public时,子类中继承成员的访问控制与继承访问控制相同66类型兼容性 C++语言中,允许且仅允许公有派生类兼容基类。这就是说,子类的对象可以赋值给父类的对象,指向父类的指针可以指向子类。反之则不正确。例:classChild:publicFather
Father*father; //声明Father对象指针
Child*child; //声明Child对象指针
//动态创建对象
//…
father=child; //正确
child=father; //错误67多态性 如前所述,在程序中同一符号或名字在不同情况下具有不同解释的现象称为多态性。在面向对象程序设计语言中,由程序员设计的多态性由两种基本形式:编译时多态性和运行时多态性。运行时多态性是面向对象程序设计语言的一大特点。68编译时多态性 编译时多态性是指在程序编译阶段即可确定下来的多态性,主要通过使用重载机制获得,重载机制包括函数重载和运算符重载两大类。 在声明函数原型时只要形式参数的个数或类型不同,就可以使用相同的函数名。只有返回值的不同同名函数,并不认为是不同的函数。运算符重载允许程序员重新定义C++语言已有的运算符。69函数重载intAdd(inta,intb); //整数加法floatAdd(floata,floatb); //单精度加法doubleAdd(doublea,doubleb);//双精度加法intAbs(inta); //整数的绝对值floatAbs(floata); //单精度数的绝对值doubleAbs(doublea); //双精度数的绝对值 对于普通函数和类成员函数都可以进行函数的重载,构造函数也可以重载。70运算符重载 运算符可以理解为函数,一元、二元运算符分别认为是具有一个、两个参数的函数。那么,对一个n维矢量类,我们可以重载“+”,“-”运算符,以实现矢量的加减运算。例classVector:Vectoroperator+(constVector&Vec);//加法Vectoroperator-(constVector&Vec);//减法Vectoroperator-(); //求反Vectoroperator=(constVector&Vec);//赋值71 运行时多态性是指必须等到程序动态运行时才可确定的多态性,主要通过继承结合动态绑定获得。这与类的继承密切相关。因为存在类型的兼容性,所以有些函数只有在运行时才能确定是调用父类的还是子类的函数。在C++中,使用虚函数(VirtualFunctions)来实现。运行时多态性72 虚成员函数主要用于要在子类(派生类)中重新定义此函数。virtual只需要在父类中定义,子类中对应的函数会默认为虚函数。子类中重新定义的函数必须与父类中的函数参数和返回值相同。不过,只有返回值不同,不会被认为与原函数不同。虚成员函数virtual73classA //声明类A{public: //公有成员
virtualShowData(); //虚函数,显示数据protected: //保护成员 intm_nData; //数据成员};classB:publicA //声明类B,继承A{public: //公有成员
virtualShowData(); //虚函数,显示数据};74voidmain(){ A*a=newA(),*c;//声明A类指针a,c,并创建a对象 B*b=newB(); //声明B类指针b,并创建对象 c=a;
c->ShowData(); //调用A类的函数
c=b; c->ShowData(); //调用B类的函数} 如果ShowData()不是虚函数,则不管c指向父类还是子类的对象,所调用的都是父类的函数。751虚函数仅适用于有继承关系的类对象,所以只有类的成员函数才能说明为虚函数。2静态成员函数不能是虚函数3内联(inline)函数不能是虚函数4构造函数不能是虚函数5析构函数可以是虚函数虚函数的限制76【1】《面向对象系统分析与设计》RonaldJ.Norman著,周之英等译,2000【2】《面向对象程序设计基础》,李师贤,李文军,周晓聪编著,高等教育出版社,1998【3】
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 智障老人安全管理制度
- 化验员培训基地管理制度
- 加油站安全隐患管理制度
- 公司手机费使用管理制度
- 培训场地规范化管理制度
- pvc型材车间管理制度
- 学校+司机班+管理制度
- 学校体训室设备管理制度
- 吴川市农村财务管理制度
- 培训班教室安全管理制度
- 2024年东南亚家用跑步机市场深度研究及预测报告
- 幼儿园小班语言课件:《池塘夏夜》
- HG/T 6281-2024 丙烯氧化制丙烯醛催化剂活性试验方法(正式版)
- DLT 265-2012 变压器有载分接开关现场试验导则
- 虹吸式雨水排水系统施工方案
- 北京草场改造规划方案
- 动火证申请表模版
- 水利施工安全培训课件
- 老物业接管方案
- 绞窄性肠梗阻汇报演示课件
- 联合排水试验报告
评论
0/150
提交评论