1、面向对象程序设计面向对象程序设计教师:刘声田教师:刘声田内容:内容:13 章章 课程计划进度课程计划进度 语言基础 C+程序结构 数据类型 流程控制教学要求教学要求 了解计算机语言发展史,理解面向对象编程特点及优点。掌握C+语法、程序结构。掌握变量、常量、表达式、语句以及操作符的含义。掌握数据类型:整型、字符型、浮点型、双精度型、数组、枚举型。教学目标教学目标 使学生能读懂简单的C+程序。使学生能用Visual C+集成环境编写简单的C+程序。一一 如何学习如何学习C+多做练习 读程序上机运行程序 启动Visual C+的方法(见课件)二 基本的C+程序结构字符字符单词单词语句语句语言语言字符
2、 26个大写英文字母AZ 26个小写英文字母az 10个阿拉伯数字09 其他字符:+-*%=“()#?&.:;,(空格)单词 保留字:系统定义的单词,不允许用户重新定义其含义。if case char int const do goto include main continue break while for class structure public private 等 用户自定义标识符:用户定义的单词,仅为当前程序所识别。用户自定义标识符 不能含有空格等特殊字符 不能与系统保留字同名 最好不要超过32个字符 最好做到“见名知意”大小写有区别 以字母、下划线开头的字母、下划线或数字的序列
3、。表达式 表达式是操作符和操作数按照一定的语法规则组成的符号序列。分类 简单表达式:3;var;fun();数值表达式:a+b*3 赋值表达式:简单赋值、复合赋值 关系表达式:逻辑表达式三 通过一个简单的程序了解C+/程序2.1/*一个简单的C+程序,*该程序在显示器上输出一句问候语“hello!”*/#include Int main()cout“hello!”;return 0;/正常返回说明 注释 编译预处理 主函数 终端输出 练习:写一个程序,屏幕上输出你的姓名和生日。稍微复杂一些的程序#include void main()const float Pi=3.14;float radi
4、um=4.15;float circus;circum=2*Pi*radius;cout“radius is:”radiusendl;cout“circumference is:”circumendl;说明 主函数与返回值 常数和常量 变量 数据类型作业 课堂上布置。论坛上有一部分。面向对象程序设计11月7日课程课程计划进度 C+流程控制 函数 简单程序设计教学要求 熟练掌握并能灵活运用3种基本控制结构解决简单的编程问题,掌握break continue语句与分支、循环语句配合使用的方法。掌握函数的定义和调用;掌握参数传递的原理、函数和变量的作用域;掌握设计函数模板的方法。了解C+程序的整体结
5、构。第四章 程序流程控制 复合语句和空语句 顺序结构 分支流程 循环结构 其他控制语句复合语句和空语句 空语句:什么也不做的语句。格式:单独一个分号 ;复合语句:多个语句组合在一起的语句块。格式:顺序结构 程序中语句按照从前到后的顺序依次执行的结构,称为顺序结构。语句的排列顺序决定了程序的流程。例题:课本51页分支结构 由特定的条件来决定执行哪条语句。可以进一步把分支结构分为单分支和多分支分支结构单分支 格式:if(条件)语句1;else 语句2;例题 if(ab)couta;else cout=90)cout=80)cout=60)cout“Pass!”;else cout“Fail!”;分
6、支结构多分支 格式:格式:switch(表达式)表达式)case 值值1:语句:语句1;case 值值2:语句;:语句;case 值值n:语句:语句n;default:语句语句n+1;分支结构多分支switch int(grade/10)case 0:case 1:case 2:case 3:case 4:case 5:cout“Fail!”endl;break;分支结构多分支 case 6:case 7:cout“Pass!”endl;break;case 8:cout“Good!”endl;break;case 9:case 10:cout“Excellent!”endl;break;de
7、fault:cout“Error!”;循环结构 在条件满足的情况下,重复执行某些语句。for循环 while 循环 do-while循环for循环 格式:for(初始化表达式;条件表达式;调整表达式)执行过程:(1)计算初始化表达式(2)计算条件表达式的值(3)如果条件表达式的值为T,执行循环体语句和调整表达式,然后转(2);否则结束循环 例题:课本65页while循环 格式:while(条件表达式)语句组;执行过程:(1)计算条件表达式的值(2)如果为真,循环体被执行,然后转(1),否则结束循环。例题:课本58do-while循环 格式:do 循环体while(条件表达式)执行过程:(1)执
8、行循环体(2)计算条件表达式的值,如果为真,转(1)否则结束 例题:课本63页其他控制语句 break语句:强制退出循环 continue语句:结束本轮循环,进行下一轮 例题:允许反复输入半径,计算并显示圆的面积。输入0时终止运行程序;对输入的半径进行检查,若发现是负数将提示操作者重新输入。#include#define Pi 3.1416void main()double radius,area;while(1)coutendlradius;if(radius=0)break;if(radius=0)coutendl“输入错误!输入错误!”;continue;area=Pi*radius*r
9、adius;coutendl“圆的面积圆的面积”area;第五章 函数 C+程序采用函数机制。采用函数机制的好处是:管理方便 纠错快速 可读性强 减少重复编码函数的定义 格式:类型修饰符 函数名(形式参数表)函数体 说明:课本79页 函数例题:课本81页函数的调用 暂时中断现有程序的运行,转去执行被调用的函数。当被调用的函数执行结束后,再返回中断处继续执行。课本82页例题。程序运行时的内存分布根据存放内容的不同,内存可划分为4个区域:程序代码区:存放程序编译成的二进制代码 全局数据区:存放全局变量和静态变量 堆:由程序来支配的空间 栈:由系统使用的空间函数调用实现的机制 先进后出机制 例如主函
10、数main调用函数A和B,而A又要调用A1和A2。(过程见演示)函数的递归调用:函数直接或间接的调用自身(必须有终结机制)函数调用中的参数传递 共有3种传递方式:按值传递:把实参的值传递给被调用函数的形参 按地址传递:把实参的地址传递给被调用的函数对应的形参 按引用来传递:函数的形参是实参的别名按值传递int Double(int n)n*=2;return n;void main()int m=7;coutmendl;cout Double(m)endl;coutm;void swap(int x,int y)int temp=x;x=y;y=temp;void main()int a=10
11、,b=20;couta“”bendl;swap(a,b);couta“bendl;按地址传递void swap(int*x,int*y)int temp=*x;*x=*y;*y=temp;void main()int a=10,b=20;couta“”bendl;swap(&a,&b);couta“bendl;按引用传递void swap(int&x,int&y)int temp=x;x=y;y=temp;void main()int a=10,b=20;couta“”bendl;swap(a,b);couta“bendl;主函数的参数作用域 局部作用域 文件作用域 作用域覆盖函数原型特殊函数
12、 内联函数:不需要栈,直接在使用之处展开。因而节省了系统开销,提高了执行效率。函数重载:几个功能相似,但是操作类型不同的函数可以使用相同的函数名,使得调用方便,可读性强。函数的默认参数 形式参数表中的最后的若干个参数设定为默认值,使其成为可选参数。在调用这个函数时候,如果没有对应于可选参数的实参,系统就自动的以设计的默认值作为实参传递给函数。例如:函数原型 int f(int a,char b,char c=Z,char*s=“Ready”);下面的函数调用存在等价关系:f(3,a,b)等价于f(3,a,b,”Ready”)f(3,a)等价于f(3,a,Z,”Ready”)面向对象程序设计教师
13、:刘声田内容:78章教学要求 掌握定义数组的方法以及定义时设定初始值的方法 掌握数组的操作方法,能用数组来解决实际问题 掌握数组的典型用法字符串处理 掌握定义各种指针的方法 掌握指针的基本操作 掌握指针与数组之间的关系 掌握动态空间的申请和释放的方法第七章 数组与结构 数组:数组是可以通过下标访问的同类型的数据元素的集合。数组的每个元素相当于一个变量,它是一个存储单元,元素的值就存放在其中。数组可以分类为一维数组和多维数组。一维数组的定义 格式:类型说明符数组名常量表达式 格式说明:数组名是一个标识符,代表所有数组元素集合 常量表达式的值表示数组元素的个数 类型说明符说明了数组元素的类型:如i
14、ntdoublefloatcharstructclass等。举例char name20;/定义了一个名字为name,存储20个字符的数组。intstudentAge10*10;/定义了一个具有100个整型值的数组数组元素的访问 数组元素的访问是通过数组名+下标组成 若数组元素的个数为n,则最大下标是n-1,最小下标是0 访问数组第i个元素的方法是:数组名i-1;数组的复制 数组之间的复制必须对数组元素一个一个地进行。通常利用循环来完成,并且要保证目标数组尺寸大于或等于源数组。例如:将一个大小为20的数组A复制到同样大小的数组B。for(int i=0;i20;i+)Bi=Ai;数组下标越界检查
15、 C+语言中,编译和执行并不检查数组是否越界。例如:int A8;coutA10;/本行没有语法错误数组元素的初始化 初始化原则:课本p150页多维数组(二维)格式:类型说明符 数组名常量表达式1常量表达式2;格式说明:常量表达式1表示数组第1维的长度(行数)常量表达式2表示数组第2维的长度(列数)例:int a23;/定义了一个2行3列的数组二维数组的遍历 通常利用双重循环来遍历for(i=0;i2;i+)for(j=0;j3;j+)coutaij;coutendl;二维数组的初始化 原则1:各维的值可以用大括号分开int a24=1,2,3,4,5,6,7,8;原则2:各维的值也可以一起写
16、int a24=1,2,3,4,5,6,7,8;原则3:可以不给出全部的值,为赋值的部分为0。int a24=1,2,3,5,6,7;结构 在计算机的程序中,经常需要用到记录一些相互之间有逻辑关系的信息,这些信息如果用几个单独的变量表示,则无法表达逻辑关系。结构可以将几个变量组合起来。结构的定义 格式:struct结构名成员列表;例如:定义一个表示学生姓名、学号和成绩的结构struct Student char name20;char id7;float score;结构成员的访问 定义了结构以后,就可以将它当作一般的数据类型来使用。例如:StudentGrade1;此时,Grade具有了类型
17、Student,包含3个成员。访问结构的成员用“.”进行操作:Grade1.name20=“mary”;Grade1.id7=“010101”;coutGrade1.name;结构变量的初始化 结构变量可以定义的时候进行初始化例如:Student Grade=“mary”,”010101”,0;同种结构类型的变量之间可以相互赋值。Student Grade2=Grade;结构的成员可以是另一种结构structDateint year;intmonth;intday;structStudentchar name20;Date birthday;float score;结构的嵌套structStu
18、dentstructDateint year;intmonth;intday;;char name20;Date birthday;float score;第八章 指针和引用 指针是C+的重点,也是难点。它是构造复杂数据类型的关键;并且,指针与数组关系密切。引用也是重点,很多时候,可以用引用来代替指针。能使用引用的时候,就不要使用指针。指针的定义与初始化 定义格式:类型修饰符*变量名=指针表达式;格式说明:类型修饰符可以是void int char float double 变量名同以前的 指针表达式是具有指针类型的表达式或者其他地址格式指针定义举例int*pn,*ph;double d,*p
19、d1=&d,*pd2=pd1;char *s=“This is a string”;void *pd3=null,*pd4=0;pd1dpd2sThis is a stringpd3pd4null用const来限定指针const出现的位置不同,含义也不同int i;1、const int*ip=&i;/指向常量的指针2、const int *const ip=&i;/指向常量的指针常量3、int*const ip=&i;/指针常量const限定指针图示1、2、3、ipiipiipi指针与数组数组名本质是一个地址,是数组第1个元素的存储地址。因此,可以将数组名赋值给一个指针,也可以把数组名当成一
20、个指针来用。如果指针指向了数组,指针也可以当成数组名来用。数组名相当于指针常量。指针与数组的关系int array100;int*parray-array;*(parray+i)等价于arrayi等价于parrayi等价于*(array+i)指针与字符串char*str=“a string”;等价于char str=“a string”;coutstr;/输出a string cout*str;/输出a动态内存的申请和释放 申请:用关键字new格式:(1)new 数据类型 (2)new 数据类型(初始值)(3)new 数据类型常量表达式 释放:用关键字delete格式:(1)delete 指针
21、名 (2)delete 指针名函数模板 函数模板是对某些重载函数的进一步改进 模板的实例化 多种类型模板面向对象程序设计教师:刘声田内容:9-11章第九章 面向对象程序方法 面向对象的方法是吸收了软件工程领域有益的概念和有效的方法而发展起来的一种软件开发方法。这种方法集抽象性、封装性、继承性和多态性于一体,易于实现模块化、可复用、易维护、易扩充的程序。面向对象的概念 从根本上讲,是一种观点,一种思想。知道了如何构造软件系统。基本思想:从现实世界客观存在的事物出发来构造系统,并在系统构造中尽可能运用人类的自然思维方式。面向对象方法是利用抽象、封装等机制,借助于对象、类、继承、消息传递等概念进行软
22、件系统构造的软件开发方法。基本概念 对象:是对问题域中客观存在的事物的抽象,它是一组属性和在这些属性上操作的封装体。消息:消息是向对象发出的服务请求,是面向对象系统中对象之间交互的途径。类:是具有相同属性和操作的一组对象的集合,它为属于该类的全部对象提供的统一的抽象描述。继承:特殊类的对象拥有其一般类的全部属性和操作,称作特殊类对一般类的继承。封装:有两层含义 包装:把对象全部属性和操作结合在一起,形成一个不可分割的整体。信息隐藏:整体对外隐藏它的细节,只对外公布一个有限的界面,通过这个界面与其他对象交互。多态性:在基类中定义的属性和操作被派生类继承之后,可以具有不同的数据类型或表现出不同的行
23、为,从而同一个属性或操作名称在各个派生类中具有不同的含义。多态性作用,发给不同对象的同一消息会引起不同的结果。第十章 类与对象 类与对象的关系,是数据类型与具体变量或常量的关系。类是一种用户自定义的数据类型,同时定义了这种类型上可进行的操作。类的定义与使用 格式:class 类名 成员列表;格式说明:成员列表中包含了数据成员和函数成员。每一个成员都具有一定的存取权限,分别是:publicprivateprotected。例题class Rectangle public:floatwidth,height;floatarea()return width*height;floatPerimiter
24、()return 2*(width+height);类的使用 定义完毕后,可以用类名作为数据类型说明类的对象。Rectanglerect;通过类对象可以访问对象的成员:rect.width=45;rect.height=54.2;coutrect.area();coutrect.Perimeter();设置成员属性的原则 类的数据成员一般是非public。表示类接口的函数成员一般定义为public。辅助实现接口的函数成员没有必要定义为public。类的成员函数 成员函数的位置:成员函数可以定义在类中,也可以定义在类外面。通常定义在类的外部。注意,Rectangle:的意义和用法等。类的作用域:
25、是这个类的定义体以及该类所有成员函数的定义体构成的范围。类的所有成员均具有类作用域。在作用域中,可以直接使用成员,不必加上所属的类的名字,在作用域之外则必须使用类作用域符。内联成员函数和非内联成员函数:一般来说,如果一个成员函数定义于类中,则为内联成员函数;否则为非内联成员函数。若要把类外实现的成员函数说明为内联函数,可借助于关键字inline。const成员函数:类的成员函数可以通过加入const 来限定对数据成员的修改。注意:一个const成员函数不可以调用非const的成员的函数;成员函数的说明中有const,则成员函数的定义中也应该有const。类的定义与头文件 一般说来,类的定义放在
26、头文件中,类的成员函数放在源文件中。注意:如果将类的内联成员函数放在类的定义体外面,就必须保证将内联函数的实现和类的定义放在一个头文件中。对象的创建与使用 变量可以是全局的,也可以是局部的;可以是静态的,也可以是动态的。类的对象也是如此。This指针 通常情况下,this是隐藏的。下列代码是等价的:void Date:SetDate(int yr,int mh,int dy)year=yr;/等价于thisyear=yrmonth=mh;/等价于thismonth=mhday=dy;/等价于thisday=dy;类与结构的关系 唯一区别:结构成员若不指明存取属性,则认为public,而类则默认
27、作 private。第11章 构造函数与析构函数 构造函数与析构函数是类的成员函数,是特殊的成员函数。构造函数 特殊点:与所在类名相同 没有任何返回值 若用户不定义,系统默认的为类构造一个无参数构造函数。构造函数在创建类对象时自动调用。对象的几种构造方式 构造函数的默认参数 默认构造函数 拷贝构造函数 成员初始化参数表析构函数 特殊点 与所在的类名相同,且函数名前面加上符号 没有任何类型的返回值 参数表必须为空,因此不可以重载 在类对象生命期结束时自动调用 若用户不定义析构函数,系统自动定义一个,但什么也不做。用途:用于在对象退出生命期时释放这个对象所占有的一些资源。如果对象在程序运行时申请了
28、一些内存空间,需要在对象生命期结束时释放这些空间;或者打开某个文件或者数据库,需要在对象退出生命期前关闭文件或数据库。面向对象程序设计制作:刘声田内容:1213章第12章静态成员、友元一个类的所有对象有时候需要共享同一个属性,或者说,一个属性是类的属性而不是每个对象的属性。这种属于类的特性而由每个类对象所共享的属性在C+中用类的静态成员表示。文件类classFilepublic:File(char*filename=“default”);/带有默认参数的构造函数File(File&srFile);/拷贝构造函数File();/析构函数private:voidGetFilename(char *
29、)const;voidGetFileContents(char*)const;voidPrint()const;voidSetFilename(char*);voidSetFileContents(char*);char filename64;intlengh;char*contents;文件类的新要求 对生成的File类对象进行计数,以便了解生成了多少个文件对象。请思考如何修改?方法1 定义一个全局变量:int fileCount=0;同时对构造函数、拷贝构造函数以及析构函数作相应的修改。构造函数、拷贝构造函数中添加代码:fileCount+;析构函数中,添加代码:fileCount-;分析
30、 变量fileCount应该属于File类的信息,从封装角度讲,应该将其定义于File类的内部,而不应该定义成为全局变量。方法2 将变量fileCount说明为File类内部数据成员,并且作为静态数据成员:classFile static int fileCount;分析 具有static的数据成员是静态数据成员,它是类的属性,不是对象的属性。注意:对象的属性,通过对象来访问;类的对象通过类来访问。静态函数成员 类的静态数据成员也有访问权限。如果其访问权限不是public,则应该通过类的函数来访问。在函数前面加上关键字static,则函数被说明为静态函数成员。静态函数成员只能访问静态数据成员。
31、友元 一般来说,类的非公有成员不能被类外其他函数使用。但是,如果有一些函数与这个类关系比较密切,可以将这个函数定义为类的“友元函数”。友元函数拥有访问类的非公有成员的能力。同样,如果类A与类B关系密切,可以将A说明为B的“友元类”,也可以提高A对B的访问非公有成员的能力。友元函数、友元类的模式class B friendf();friendclass A;使用友元的条件课本311页使用友元的注意事项课本311页第13章运算俯重载 C+中的运算符与一般函数一样,也可以重载。使用重载后的运算符会使程序更加容易理解,符合人们的思维习惯。可以重载的运算符运算符重载规则 运算符或者是类的成员函数或者是有
32、一个参数的类型是这个类或这个类的引用。重载时,运算符的优先级、结合性以及操作数个数不能改变。定义为类的成员函数的单目运算符没有参数,定义为独立函数时,有一个参数。同理对于双目运算符,以上两种情况分别有一个参数和两个参数。运算符重载规则(续)重载的运算符不能有默认参数。不允许定义新的运算符。赋值运算符不能被派生类继承。函数调用运算符重载 函数调用运算符:()重载的()必须是类的成员函数。类的对象名就是()的一个操作数。赋值运算符重载 赋值运算符:=一般情况下,=不需要重载,因为系统会为我们所定义的类自动提供一个默认的赋值运算符。当类具有指针类型的数据成员时,一般需要重新定义=。重载的=必须是类的成员函数。双目运算符的重载 双目运算符:+-*/等 既可以是类的成员函数,也可以是独立函数。独立函数一般定义为相关类的友元。单目算术运算符重载 比较少,仅有+(正)-(负)等。重载的方法和要求与双目运算符类似。+-运算符重载+-是特殊的单目运算符。因为有前后之分,需要特殊对待。重载定义的时候,应该注意参数值以及函数值(表达式值)的计算。插入、抽取运算符重载 课本337页