420 likes | 556 Views
第 1 章 C++ 基本概念. 主讲:王 建 兴 闽江学院物理学与电子信息工程系. 1.1 面向对象介绍. 1.1.1 面向对象的必然性 软件危机 软件重用 代码的拷贝 —— C 函数库 按类别进行包装 —— 类 结论:使用面向对象的技术. 1.1.2 面向对象的程序设计与面向过程的程序设计. 结构化程序设计的设计思路 自顶向下、逐步求精 顺序、选择和循环三种基本结构 重用:子函数. 1.1.2 面向对象的程序设计与面向过程的程序设计. 1.1.2 面向对象的程序设计与面向过程的程序设计. 面向对象的程序设计
E N D
第1章 C++基本概念 主讲:王 建 兴 闽江学院物理学与电子信息工程系
1.1 面向对象介绍 • 1.1.1 面向对象的必然性 • 软件危机 • 软件重用 • 代码的拷贝 ——C函数库 • 按类别进行包装 ——类 • 结论:使用面向对象的技术
1.1.2 面向对象的程序设计与面向过程的程序设计 • 结构化程序设计的设计思路 • 自顶向下、逐步求精 • 顺序、选择和循环三种基本结构 • 重用:子函数
1.1.2 面向对象的程序设计与面向过程的程序设计
1.1.2 面向对象的程序设计与面向过程的程序设计 • 面向对象的程序设计 • 是结构化程序设计的继承和创新 • 按照特性(数据)与行为(操作)统一的方式进行组织 ——对象 • 对象是稳定的,对象的相互联系是变化多样的。
1.1.2 面向对象的程序设计与面向过程的程序设计 • 面向对象程序设计将数据及对数据的操作放在一起,作为一个相互储存、不可分割的整体(对象)来处理,它采用数据抽象和信息隐藏技术。它将对象及对象的操作抽象成一种新的数据类型——类,并且考虑不同对象之间的联系和对象类的重用性。
1.1.2 面向对象的程序设计与面向过程的程序设计 综上所述,可以归纳如下: • 面向过程:数据结构+算法。使用模块的方式构建应用系统。代码由三种程序结构构成:顺序、选择和循环。一个不足:程序的重用程度不高。 • 面向对象:类+消息传递。使用包装的类来构建应用系统。代码仍由三种结构构成。优点是符合人的思维方法,提高了软件的重用度。
1.1.3 面向对象的基本概念 1、对象与实例(Object and Instance) 对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组方法组成。 对象之间通过消息通信。一个对象通过向另一个对象发送消息激活某一相功能。 对象就是C语言中的变量.
1.1.3 面向对象的基本概念 2、类(Class) 类就是类型,类是具有相同属性和方法(或称操作)的一组对象的抽象描述。 类是静态的,类的语义和类之间的关系在程序执行前就已经定义好了。而对象(变量)是动态的,对象是在程序执行时被创建和删除的。 类的实例就是对象.
1.1.3 面向对象的基本概念 3、方法(Method) 方法指的是类对象的一组行为。就是类对象中的函数成员. 4、属性(Attribute) 属性是类对象的一组特征。就是类对象中的数据成员。
1.1.3 面向对象的基本概念 5、封装(Encapsulation) 封装就是把对象的属性和方法结合成一个独立的系统单位,并尽可能地隐蔽对象的内部细节。封装使一个对象形成两个部分:接口部分和内部部分。对于用户来说,接口部分是可见的,而内部部分是不可见的。类提供了封装的机制。。
1.1.3 面向对象的基本概念 6、消息(Message) 消息就是向对象发出的服务请求。消息就是调用一个对象的方法(函数成员)
1.1.3 面向对象的基本概念 7、继承(Inheritance) 面向对象的程序设计提供了一个类继承另一个类的方法来增加软件的复用。被继承的类称为父类、超类、基类,继承自另一个类的类被称为子类、派生类。 继承可分为单继承和多继承。单继承指的是派生类只从一个基类继承,而多继承指的是子类从多于一个的基类继承。
Graph +Draw() Circle 图1-5 多 态 Rect +Draw() +Draw() 1.1.3 面向对象的基本概念 8、多态(Polymophism) 在面向对象技术中,多态指的是同一表现形式在不同上下文中具有不同的意义和用法的能力。 多态往往和覆盖、动态绑定(dynamic binding)等概念结合在一起。多态是在运行时根据具体的指向从而调用不同方法的的一种能力。图1-5是多态的示例。有两个类(Circle和Rect类)继承自同一个基类(Graph类),可以定义一个对Graph对象的引用,但在运行时,可以把Circle类型和Rect类型的对象赋给该引用。如果调用Draw()方法,则根据引用对象调用所引用对象中的Draw()方法。 多态是保证系统具有较好适应性的一个重要手段。
1.1.4 认识C++程序 • C++程序由一个个类定义构成,类类似于C语言中的结构。 • 类就是类型,程序设计的过程就是定义一个个的类(型),类(型)是可重用的单元。 • 然后再用类(型)定义相应具体的内存实体对象,也就是变量。 • 操作这些变量就完成了程序的运行。操作变量的方法就是调用变量的数据成员和函数成员. 注意:系统预定义的类型与自定义的类型地位是一样的。
1.1.4 认识C++程序 //定义一个结构 struct Rectangle { public: void Move(int x,int y); private: int X,Y; }; //结构中成员函数的具体实现 void Rectangle::Move(int x,int y) { X=x; Y=y; } //主函数 void main() { Rectangle rect; rect.Move(1,2); }
1.2 基本数据类型 • 1.2.1 字符集与关键字 • 1.2.2 数据类型 • (1) 基本数据类型 • (2) 非基本数据类型 • ① 指针 • ② 数组【例1-2】 • ③ 结构体 • ④ 共用体 • ⑤ 枚举
1.3 常量与变量 • 1.3.1 常量与关键字const • C使用宏定义定义符号常量 #define PI 3.1415926 //宏定义 • C++采用关键字const来定义符号常量 const float PI = 3.14159; //常量定义语句
1.3 常量与变量 const有更多的优点: • const常量有数据类型,而宏常量没有数据类型。 • 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。 Const内在含义是只读。所以C++程序设计书籍建议:“Use const whenever you need”。 • Const用法 • 限定指针本身——指针常量 • 限定指针所指的内容——指向常量的指针变量 • 既限定指针也限定所指向的内容——指向常量的指针常量
1.3 常量与变量 • 1.3.2 变量简介与VC++命名规则 • C++提供变量声明语法: [存储类别]类型名〈变量名表〉[=初值]; 存储类别 :extern:全局(外部); static:静态(局部); auto: 自动(局部、动态); register:寄存器变量。 • C++中,变量类型 : 局部变量 、形参变量 、全局变量成员变量 • C++的函数体不再区分定义部分和执行部分。 可在函数体的任意位置定义一个局部变量
1.3 常量与变量 • 基于Windows的VC++中广泛地采用匈牙利命名规则表示法来标识一个变量。 表1-2 常用匈牙利表示法
1.4 表达式与运算符 • 1.4.1 运算符 • (1)算术运算符 • (2)关系运算符 • (3)逻辑运算符 • (4)增减量运算符 • (5)赋值运算符 • (6)sizeof运算符 • (7)位运算符 • (8)移位运算符 • (9)取地址运算符 • (10) 复合赋值运算符 • (11)条件运算符 • (12)逗号运算符 • (13)I/O运算符 • (14)内存分配/释放运算符
1.4 表达式与运算符 • 1.4.2 表达式 • 算术表达式 • 关系表达式 • 逻辑表达式 • 赋值表达式 • 条件表达式 • 逗号表达式 • I/O表达式 • 内存管理表达式
1.5 基本的控制结构 • (1)顺序结构 • (2)选择结构 • if语句 • swith语句 • try { … } catch (异常类型) { … } • (3)循环结构 • for 循环 • while循环 • do…while循环
1.6 函数 • 函数定义的格式: 返回类型 函数名(形式参数表) { 语句序列 } • 主函数 返回类型 main(int argc, char *argv[]); 【例1-3】
1.6 函数 • 1.6.1 内联函数 (1)内联函数的定义 inline 返回类型 函数名(形参及其类型列表) { 函数体 } (2)内联函数与普通函数的区别和联系 当在程序中调用一个内联函数时,是将该函数的代码直接插入到调用点,然后执行该段代码,所以,在调用过程中不存在程序流程的跳转和返回问题;而普通函数的调用,程序是从主调函数的调用点转去执行被调函数,待被调函数执行完毕后,再返回到主调函数的调用点的下一句继续执行。
1.6 函数 (3)对内联函数的限制 【例1-4】
1.6 函数 • 1.6.2 函数重载 (1)函数重载的概念 函数重载是指一个函数可以和同一作用域中的其他函数具有相同的名字,但这些同名函数的参加类型、参数个数、返回值以及函数功能可以完全不同。 int plus(int x,int y){return x+y;} double plus(double x,double y){return x+y;} …… int z=plus(2,3); double z=plus(2.0,3.5);
1.6 函数 (2)定义重载函数时的注意事项 ①重载函数间不能只是函数的返回值不同,应至少还在形象的个数、类型上有所不同。 ②应使所有的重载函数的功能相同。如果让重载函数完成不同的功能,是不好的编程风格,因为这样会破坏程序的可读性。
1.6 函数 • 1.6.3 默认参数的函数 【例1-5】 注意: ①默认参数一般在函数说明中提供。 ②默认参数的顺序。如果一个函数中有多个默认参数,则形参分布中默认参数应从右至左逐渐定义。如: void myfunc(int a=1,float b,long c=20);//错误 void myfunc(int a,float b=2.1,long c=30);//正确 ③在函数调用时,给定的实参值将取代参数的默认值,没有给实参值将使用参数的默认值。 ④在给参数设置默认值时,不仅可以是数值,也可以是表达式。
1.7 引用的使用 • 引用的声明方法: 类型标识符 &引用名=目标变量名; int a; int *p=&a; //表示指针p的值为变量a的地址 int &b=a; //表示b与a是同一个变量,b是a的别名,&b==&a为真;
1.7 引用的使用 • (1)引用的说明: ①&在此不是求地址运算符而是起标识作用,标识在此声明的是一个引用名称; ②类型标识符是指目标变量的类型; ③声明引用时,必须同时对其进行初始化; ④引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名; ⑤声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,所以系统并不给引用分配存储单元;
1.7 引用的使用 • (3)引用作为函数的参数 【例1-6】 • 值传递、指针传递 和引用传递 • (4)返回引用的函数 要以引用返回函数值,则函数定义时的格式如下: 返回类型& 函数名(形参列表及类型说明) {函数体} 【例1-7】
1.7 引用的使用 具体的使用说明如下: ①要以引用返回函数值,则定义函数时要在函数名的前面加上&符号; ②用引用返回一个函数值的最大好处是:在内存中不产生被返回的副本;而用普通的返回值的方法返回一个函数的函数值时,需要的内存中先创建一个临时变量,在被调函数返回时,将函数值复制到该临时变量中,主调函数再以该临时变量的值进行运算,可以看出,这种方法产生了函数值的副本; ③使用引用返回函数值,可以使用函数出现在“=”的左边。因为它返回的是函数体中return返回变量的引用。 ④在引用的使用中,单纯给某个变量取个别名毫无意义的,引用的目的主要是在函数参数传递中解决大对象的传递效率和空间不如意的问题; ⑤使用引用传递函数的参数能保证参数传递中不产生副本和提高传递的效率,且通过const的使用,又可保证了引用传递的安全性; ⑥引用与指针的区别在于:指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作,程序使用指针使程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
1.8 其它基本的语法 • 1.8.1 注释 • (1)多行注释 /*……*/ • (2)单行注释 //…… • 1.8.2 类型转换 • (1)(类型名)表达式 • (2)类型名(表达式)
1.8 其它基本的语法 • 1.8.3 动态内存分配 • C语言中是利用库函数malloc和free分配和撤销内存空间的。 student *cpp=(student *)malloc(sizeof(student));//假设student是自定义类型 free(cpp);
1.8 其它基本的语法 new运算符格式: 指针=new 数据类型(初始化值) 指针=new 数据类型[算术表达式]//开辟数组空间 delete运算符: delete 指针 delete []指针 示例如下: int *pi,*parray; pi=new int(85); delete pi; parray=new int[10]; delete []parray; new/delete必须配对使用,malloc/free也一样
1.8 其它基本的语法 • 通常有三种方式处理“内存耗尽”问题。 (1)判断指针是否为NULL,如果是则用return语句终止本函数。例如: void Func(void) { A *a = new A; if(a == NULL) { return; } … }
1.8 其它基本的语法 (2)判断指针是否为NULL,如果是则用exit(1)终止整个程序的运行。 void Func(void) { A *a = new A; if(a == NULL) { cout << “Memory Exhausted” << endl; exit(1); } … }
1.8 其它基本的语法 (3)为new和malloc设置异常处理函数。例如Visual C++可以用_set_new_hander函数为new设置用户自己定义的异常处理函数,也可以让malloc享用与new相同的异常处理函数。
1.8 其它基本的语法 • 动态内存申请与释放的一些使用要点: (1)如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。 (2)不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。 (3)动态内存的申请与释放必须配对,防止内存泄漏。 (4)用free或delete释放了内存之后,立即将指针设置为NULL。
1.8 其它基本的语法 • 1.8.4 输入输出语句 • C++支持C的外部库函数(如scanf和printf)进行输入输出。 • C++使用流对象来处理数据的输入输出。 cin>>变量1[>>变量…]; cout<<输出内容[<<输出内容…]; 在此,“>>”称为抽取操作符;“<<”称为插入操作符 示例