C++程序设计(第2版中)清华出版社ppt.ppt_第1页
C++程序设计(第2版中)清华出版社ppt.ppt_第2页
C++程序设计(第2版中)清华出版社ppt.ppt_第3页
C++程序设计(第2版中)清华出版社ppt.ppt_第4页
C++程序设计(第2版中)清华出版社ppt.ppt_第5页
已阅读5页,还剩132页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C 程序设计 第2版 作者 戴仕明 赵传申等建议课时 64学时 第6章数组第7章结构体 共用体和枚举型第8章指针和引用第9章类和对象第10章构造函数和析构函数 第6章 数组 本章主要内容 6 1一维数组的定义及应用6 2多维数组的定义及使用6 3字符数组的定义和使用6 4字符串处理函数 6 1一维数组的定义及应用 6 1 1一维数组的定义6 1 2一维数组的初始化6 1 3一维数组存储6 1 4一维数组元素的引用6 1 5一维数组应用 6 1 1一维数组的定义 一维数组变量的定义格式为 其中 指定了数组元素的数据类型 可以是基本类型或自定义的类型 为一个标识符 它标识一维数组变量的名字 数组名应符合标识符的命名规则 为一个整型常量表达式 它规定了数组元素的个数 即数组长度 表示定义数组 注意 1 在定义数组时 数组大小必须是常量或符号常量 不能是变量或变量表达式 2 在同一个函数中 数组的名称不能和其他局部变量的名称相同 3 相同类型的数组或变量可以在一个语句中定义 6 1 2一维数组的初始化 在定义一维数组的同时 可以给数组元素赋初值 这称为数组的初始化 一维数组初始化赋值有三种方法 初始化值用一对大括号 括起来 各初值间用逗号分开 1 给所有元素赋初值 2 给部分元素赋初值 初始化表中的值可以少于数组元素个数 未指定初值的元素被赋值为0 3 由初始化列表值个数决定元素个数的初始化 说明 1 如果初始化列表值的个数超过数组指定的元素个数 则数组的初始化出错 2 数组如果没有赋初值 在定义时则必须指定数组的大小 3 数组定义为全局或静态变量时 所有数组元素初值均为0 数组定义为局部变量时 数组元素没有确定的值 不要使用 6 1 3一维数组存储 数组经过定义之后 系统也会为其分配一块连续的存储空间 对于一维数组变量 如果定义一个n个元素的数组 系统会为该数组申请n个连续的内存单元来存储这n个数组元素 内存单元的大小取决于数组的类型 数组 包括后面多维数组和字符数组 所占用的存储单元大小可以用sizeof运算符来计算 一维数组占用的存储单元即其所有元素所占用的存储单元的和 6 1 4一维数组元素的引用 C 语言规定 对数组进行操作时 只能对数组中的元素进行引用 不能把整个数组作为一个整体使用 一维数组元素的引用格式为 其中 下标可以是整型变量或整型表达式 C 语言规定 下标的最小值是0 对应数组的第一个元素 最大值为数组的大小 即元素个数 减1 对应数组的最后一个元素 6 1 5一维数组应用 求N个数的平均值的方法是 首先求N个数的累加和 并保存在和变量sum中 然后将累加和sum除以数据个数N 即可求得N个数的平均值 求N个数中的最大值的方法是 首先设变量max 存放第1个数 然后将余下的数按次序分别与max进行比较 若某一数大于max 则将其值赋给max 若某一数小于max 则max的值不变 当余下的数都比较完后 max中存放的就是N个数中的最大值 求N个数中的最小值的方法同求N个数中的最大值的方法类似 冒泡排序法 对N个元素 从第一个元素开始 用每一个元素与它的后一个元素进行比较 如果后者小则交换前 后两个元素的位置 一直到这N个元素两两比较完 选择排序法 对N个元素 选第一个元素与后面的第二个元素进行比较 如果后者小则交换两个元素位置 再用第一个元素与第三个元素比较 这样 一轮下来 最小的元素被选择到第一个位置 第二轮从第二个元素开始与其后面的每个元素比较 6 2多维数组的定义及使用 6 2 1二维数组的定义6 2 2二维数组的初始化6 2 3二维数组的存储6 2 4二维数组元素的引用 6 2 1二维数组的定义 二维数组的定义与一维数组类似 其语法格式为 其中 是指二维数组元素的数据类型 可以是任意的C 类型 void除外 为二维数组的名字 用标识符表示 和都为一个整型常量表达式 它们分别表示二维数组的行数和列数 6 2 2二维数组的初始化 二维数组初始化有3种方法 1 给所有元素赋初值 给数组的所有元素赋初值的方式有两种 方式一 分行对数组元素赋初值 形式为 0行初值 1行初值 m行初值 即每行一个花括号 花括号间用逗号分隔 全部初值再用一个花括号 方式二 单行对数组元素赋初值 形式为 0行初值 1行初值 m行初值 所有初值放在一个花括号中 按数组排列的顺序给各元素赋初值 2 给部分元素赋初值 初始化表中的值少于数组元素个数 未指定初值的元素被赋值为0 也可以有两种方式 方式一 分行初始化 形式为 0行部分初值 1行部分初值 m行部分初值 方式二 单行对数组元素赋初值 6 2 3二维数组的存储 对于二维数组 编译器也将在内存中分配连续的存储空间来存储数组元素 在C 中 二维数组元素在内存中的排列顺序是按行存放 即先顺序存放第一行的数组元素 然后存放第二行的数组元素 依此类推 6 2 4二维数组元素的引用 二维数组的引用形式为 其中 下标表达式1为数组元素的行号 下标表达式2为数据元素的列号 行号与列号必须为整型 如果定义了一个m n的二维数组 那么下标1的范围是0到m 1 下标2的范围是 到n 1 6 3字符数组的定义和使用 6 3 1字符串6 3 2字符数组 6 3 1字符串 字符串是常量 是用一对双引号括起来的字符序列 1 字符串中字符为普通字符或转义字符 如回车换行符 n 2 以 0 为字符串结束标志 在C 中 为了判断字符串是否结束 系统自动在字符串的末尾加上一个字符 0 作为字符串的结束标志 3 串常量和字符常量的区别串常量 是用双引号括起来的n个字符序列 占n 1个字节空间 后加结束标志 0 字符常量 是用单引号括起来的单个字符 占1个字节空间 不加结束标志 0 6 3 2字符数组 字符数组就是类型为字符型的数组 1 字符数组定义字符数组的定义格式为 char 2 字符数组的初始化字符数组初始化赋值有两种方法 1 为各元素逐个赋初值 2 指定字符串初值 C 语言允许将字符串作为初值 初始化字符数组 3 字符数组的存储方式当字符数组str n 定义后 系统为数组分配n个字节内存单元 每个单元存放一个字符的ASCII码 4 字符数组的输入与输出字符数组的输入与输出有两种方法 逐个元素输入输出或按字符串的方式输入输出 1 字符数组元素逐个输入输出2 字符数组作为字符串进行整体的输入输出 6 4字符串处理函数 1 求字符串长度函数strlen字符的串长度是指字符串中的字符个数 函数原型为 intstrlen constchars 功能 字符数组中字符的个数 不包括 0 其中的const表示函数strlen不会和不能修改参数的值 使用的使用传入的是数字名或字符串 2 字符串复制函数strcpy字符串复制函数strcpy函数的原型为 char strcpy charstr1 constcharstr2 功能 将参数str2表示的字符串复制到参数str1指定的字符数组中 str1中原来的字符串将会被自动覆盖 3 字符串连接函数strcat符串连接函数strcat 可以将两个字符串连接起来 形成一个新的字符串 函数原型为 char stcat charstr1 constcharstr2 功能 把str1表示的字符串链接到str2中原来字符串的后面 结果存放在数组str1中 4 字符串比较函数strcmp可以采用字符串比较函数strcmp来比较两个字符串的大小 函数原型为 intstrcmp constchars1 constchars2 5 字符串中大写字母变换成小写字母函数strlwr函数原型为 intstrlwr chars 其中s为字符数组 或字符串常量 这个函数的功能就是将字符数组s中大写字母换成小写字母 第7章 结构体 共用体和枚举型 本章主要内容 7 1结构体的定义及应用7 2共用体的定义及应用7 3枚举类型 7 1结构体的定义及应用 7 1 1结构体类型的定义7 1 2结构体类型变量的定义7 1 3结构体类型变量的使用7 1 4结构体数组 7 1 1结构体类型的定义 结构体定义的语法形式如下 struct结构体标识符 成员变量列表 其中struct为系统关键字 keyword 说明当前定义一个新的结构体类型 结构体标识符遵循C 语言标识符命名规则 在 之间通过分号分割的变量列表称为成员变量 structuremember 用于描述此类事物的某一方面特性 成员变量可以为基本数据类型 如float 数组和指针类型 也可以为结构体 由于不同的成员变量分别描述事物某一方面的特性 因此成员变量不能重名 7 1 2结构体类型变量的定义 结构体类型定义之后 就可说明和使用结构体类型的变量 结构体类型的变量简称为结构体变量 1 定义结构体变量定义结构体变量的方法有以下3种 分别说明之 1 定义结构体后定义变量在上面定义了一个结构体类型structPoint之后 可以用它定义变量 以便存储一个具体的点 2 定义类型同时定义变量此种方法是在定义结构体类型的同时 定义结构体类型变量 3 直接定义变量此种方法在定义结构体的同时定义结构体类型的变量 但是不给出结构体标识符 2 结构体变量的初始化C 语言中引用变量的基本原则是在使用变量前 需要对变量进行定义并初始化 其方法是在定义变量的同时给其一初始值 具体的形式如下 struct结构体标识符 成员变量列表 struct结构体标识符变量名 初始化值1 初始化值2 初始化值n 3 结构体变量的存储结构体变量在内存中占用一块连续的内存空间 其各个元素依它们在结构体类型中的定义次序存储在这块内存空间中 7 1 3结构体类型变量的使用 1 结构体变量的使用结构体变量不能直接输入和输出 否则是违法的 但是作为函数参数传递或作为函数的返回值返回时 可以将一个结构体变量作为一个整体进行复制和赋值 2 结构体成员的使用结构体变量包括一个或多个成员变量 引用其成员变量的语法格式如下 7 1 4结构体数组 结构体数组 由结构体类型元素组成的数组称为结构体数组 1 结构体数组的定义及初始化 定义结构体数组有三种方法 1 先定义结构体后定义数组2 在定义结构体的同时定义结构体数组3 直接定义结构体数组2 结构体数组的使用结构体数组和一般数组一样 用下标来指定某个元素 不同的是 结构体数组元素通过成员运算符来指定结构体的成员 7 2共用体的定义及应用 7 2 1共用体类型的说明7 2 2共用体类型变量的说明及使用 7 2 1共用体类型的说明 定义一个共用体的语法形式为 union共用体标识符 成员变量列表 说明 1 关键字union说明定义的是共用体类型 2 共用体类型名必须符合标识符命名规则 3 共用体由若干个数据成员组成 每个数据成员可以有不同的数据类型 数据类型可以是基本类型 也可以是导出类型 4 各成员共用一个存储区 存储区的大小等于各成员占用字节长度的最大值 7 2 2共用体类型变量的说明及使用 1 共用体变量的说明及初始化1 定义共用体后定义变量在上面定义了一个共用体类型unionData之后 可以用它定义变量2 定义类型同时定义变量此种方法是在定义共用体类型的同时 定义共用体类型变量 3 直接定义变量此种方法在定义共用体的同时定义共用体类型的变量 但是不给出共用体标识符 2 共用体变量的使用和特点共用体变量的引用方式与结构体变量的引用方式相同 即使用成员运算符 连接变量名与成员名即可 其引用格式为 7 3枚举类型 7 3 1枚举类型的说明7 3 2枚举类型变量的使用 7 3 1枚举类型的说明 1 枚举类型一般的枚举类型的定义的语法描述如下 enum枚举标识符 常量列表 其中enum为系统关键字 枚举标识符遵循变量的命名规则 2 枚举类型的变量定义枚举类型变量有三种方法 即 先定义类型后定义变量 定义类型的同时定义变量 直接定义变量1 先定义类型后定义变量 格式 2 定义类型的同时定义变量 格式 enum 3 直接定义枚举变量 格式 enum 说明 1 在程序的执行过程中 每个枚举类型的元素都是用整数来表示的 2 可以给枚举成员指定整数值 3 当前面的枚举成员指定整数值 而后面的没有指定时 默认后面的枚举成员赋值为前面的值 1 4 一般情况下 枚举成员取相同的值也是可以的 但是没有意思 所以一般不要取相同的值 7 3 2枚举类型变量的使用 注意 枚举类型的变量不能直接输入和输出 输入输出通常采用switch语句来转换 若直接输出枚举类型的变量 输出值为该变量的序号 无符号整数值 结构体 共用体和枚举类型本身还可以作为函数的形参类型以及函数的返回值类型 当需要把一个结构数据传给一个函数时 相应函数的形参应定义为结构体类型 而实参则写结构体变量的名字 第8章 指针和引用 本章主要内容 8 1指针和指针变量8 2指针运算8 3指针和数组8 4指针数组和多级指针8 5指针和函数8 6new和delete运算符8 7引用和其他类型的指针8 8简单链表8 9类型定义 8 1指针和指针变量 8 1 1指针的概念8 1 2指针变量的说明 8 1 1指针的概念 指针 一个变量的地址 一个内存单元的地址 变量的地址 该变量所占存储单元的首地址 变量的值 内存单元中的内容 变量地址的表示 变量名 取地址运算符 指针变量 专门存放变量地址的变量 8 1 2指针变量的说明 指针变量与其他类型的变量一样 必须先说明后使用 说明指针变量的一般格式为 存储类型 类型 变量名1 变量名2 其中 存储类型是可任选的 变量名前的星号 指明所说明的变量为指针变量 而类型则指出指针变量所指向的数据类型 即指针所指向的内存单元中存放的数据值的类型 1 指针的类型从语法的角度看 只要把指针声明语句里的指针名字去掉 剩下的部分就是这个指针的类型 2 指针所指向的数据类型当通过指针来访问指针所指向的内存区域时 指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待 8 2指针运算 8 2 1指针的赋值运算8 2 2指针的算术运算8 2 3指针的关系运算 8 2 1指针的赋值运算 指针赋值运算常见的形式如下 1 将一个变量的地址以 运算的结果形式赋给一个同类型的指针 2 将另一同类型的指针值赋给某一指针 3 在C 中可以将0赋给任一指针变量 其含义是初始化指针变量 使其值为 空 8 2 2指针的算术运算 左值所能进行的算术运算有两种 一是指针变量与一个整数的加或减运算 二是自增 自减运算 1 与整数的加或减运算指针加法的计算公式为 如果指针变量的定义为datatype p p初始地址值为DS 那么p n DS n sizeof datatype 指针加法的单位是指针对应类型的字节数 2 指针的自增或自减指针的自增或自减表示指针从当前位置向后或向前移动sizeof 数据类型 长度的存储单元 指向下一个或上一个元素 8 2 3指针的关系运算 指针变量可以进行关系运算 两个指针变量的关系运算是根据两个指针变量值的大小 作为无符号整数 来进行比较的 通常只有同类型的指针变量进行比较才有意义 相等 比较的含义是判断两个指针变量是否指向相同的内存单元 即两个指针值是否相同 而不等比较 的含义是判断两个指针变量是否指向不同的内存单元在C 中 同一个符号可能表示不同的运算符 编译器是根据运算符的优先级 操作级的类型及个数来区分的 8 3指针和数组 8 3 1指针与一维数组8 3 2指针与多维数组8 3 3指针和字符串 8 3 1指针与一维数组 如图8 3所示 定义一个数组a 10 和一个指针pa inta 10 pa pa a Apa BA B行的效果是一样的 都是把数组的首地址赋给指针 引用一个数组元素 有3种方法 仍然采用上面的数组和指针 1 下标法 如a i 形式 2 数组名地址法 如 a i 3 指针法 有两种形式 指针地址法 如 pa i 指针下标法 如pa i 图8 3一维数组与指针示意图 8 3 2指针与多维数组 在C 中 二维数组的各个元素值按行的顺序逐行来存放 编译程序为二维数组分配一片连续的内存空间来依次存放各个元素值 行数组首地址a 相当于 a 0 行指针a I 行元素a i 即为 a i 实际为各列数组首地址 各列数组首地址a i 相当于 a i 0 列元素地址 a i j 可用a i j或者 a i j表示 列元素a i j 即为 a i j 或者 a i j 这里i 0 1 2 j 0 1 2 3 图8 4所示为二维数组与指针的关系示意图 图8 4二维数组与指针关系示意图 8 3 3指针和字符串 用字符指针表示字符串有3种方法 1 指向字符数组 让字符指针与存放字符串的字符数组关联 就可以用字符指针表示该字符串 2 直接定义指针并初始化 让它指向指定的字符串 3 直接将字符串常量赋予字符指针 8 4指针数组和多级指针 8 4 1指针数组8 4 2指向一维数组的指针变量8 4 3多级指针 8 4 1指针数组 指针数组是指针变量的集合 它的每一个元素都是一个指针 且具有相同的数据类型 其一般的定义格式为 存储类型 数据类型指指针所指向变量的数据类型 因为 的优先级高于 指针与 构成一个数组 再与 结合 指明是一个指针数组 数据类型指明指针数组中每个元素所指变量的类型 8 4 2指向一维数组的指针变量 可以声明一个指针变量使其只能指向一维数组 声明的格式为 其中 表示一维数组元素的数据类型 表示变量是指针 表示是数组 表示一维数组的大小 要注意这样两种写法 int p 4 定义了一个指针数组 该数组有4个指针元素int p 4 定义了一个指针 该指针指向一个有4个元素的数组因为运算符 的优先级高于 所以用圆括号 将 与指针变量名括起来以改变运算符的优先级顺序 使 先作用于指针变量 然后再与 结合 形成指向一维数组的指针变量 8 4 3多级指针 如果指针变量中存放的是另一个指针的地址 就称该指针变量为指向指针的指针变量 指向指针的指针变量也称为二级指针 其声明的语法格式为 两个符号 表示后面声明的变量为指向指针的指针变量 8 5指针和函数 8 5 1指针作为函数的参数8 5 2返回指针的函数8 5 3指向函数的指针8 5 4带参数的main 函数 8 5 1指针作为函数的参数 当形参为指针时 实参可以是一个基类型相同的指针变量或变量的地址 当函数的参数为指针时 可将指针值和指针所指向的数据作为函数的输入参数 即在函数体内可使用指针值和指针所指向的数据值 也可将指针所指向的数据作为函数的输出参数 即在函数体内改变了形参指针所指向的数据值 调用函数后 实参指针所指向的数据也随之改变 8 5 2返回指针的函数 函数的返回值可以为整型 实型 双精度型 字符型数据 同样函数的返回值也可以为指针 返回指针值的函数的定义方法如下 类型说明符 函数名 参量表列 函数体 其中类型说明符为函数返回的指针指向的数据类型 8 5 3指向函数的指针 编译器为每个函数确定一个入口地址 当调用该函数时 系统会从这个 入口地址 开始执行函数 存放函数的入口地址的指针就是一个指向函数的指针 简称为函数指针 定义函数指针的格式为 注意在定义指向函数的指针变量假设为p时 p 两侧的括号不可省略 表示p先与 结合 它是指针变量 然后再与后面的 结合 表示此指针变量指向函数 否则将与返回指针的函数相混淆 8 5 4带参数的main 函数 为执行一个可执行文件而在操作系统提示符下输入的命令叫命令行 命令行一般语法形式 命令名参数1参数2 参数n带参数的main 函数形式 main intargc char argv 形参名任意 习惯上使用argc和argv 其中argc为命令行中参数的个数 包括可执行文件名 而argv为一字符指针数组 元素个数随命令行参数而定 每个指针数组元素都指向命令行中的一个参数 8 6new和delete运算符 8 6 1new和delete运算符的用法8 6 2使用new和delete运算符的注意事项 8 6 1new和delete运算符的用法 1 new操作符的使用C 提供了操作符new和new 来创建动态变量 1 new用来动态创建单个变量 语法格式为 new 2 可以在申请内存空间时 同时对该内存空间进行初始化 3 new 用来创建动态变量数组 语法格式为 2 delete操作符的使用 1 delete 释放 或归还 所指向的内存空间 对应上面的第一点 释放时用语句 deletep 释放p所指向的内存空间 2 delete 或者用delete 8 6 2使用new和delete运算符的注意事项 两个运算符 应注意以下几点 1 用new运算符为指针变量所分配的存储空间 其初值是不确定的 所以在使用前要进行初始化 2 用new运算符分配空间后 要判断其指针的值是否为0 若new运算符运算的结果为0 表示动态分配内存失败 进行出错处理 3 当定义一个指针 动态分配数组时 不能对数组进行初始化 4 当new运算符计算的指针类型与赋值运算符左操作数类型不一致时 必须进行强制类型装换 5 用new运算符分配的内存空间 该指针不能随意指向别的空间 否则 当指针已不再指向用new运算符分配的内存空间时 delete会出错 6 对于一个动态申请的内存空间 不需要的动态内存一定要及时归还给操作系统 让操作系统能够分配给其他需要的指针 8 7引用和其他类型的指针 8 7 1引用类型变量的说明和使用8 7 2函数的引用传递8 7 3const类型变量8 7 4void型指针 8 7 1引用类型变量的说明和使用 在C 中引入引用类型的主要目的是为了在函数的参数传递时提供方便 引用类型主要用作函数的参数或用作函数的返回值类型 定义一个引用类型变量的一般格式为 定义了一个引用类型的变量aa 它是变量a的别名 8 7 2函数的引用传递 1 引用作为函数的参数引用可以作为函数的参数 建立函数参数的引用传递方式 传递引用实际上传递的是变量的地址 这一点与指针是一样的 但是这种传递方式避免了传递大量数据带来的额外空间开销 从而节省大量存储空间 减少了程序运行的时间 2 函数的返回值为引用类型当函数的返回值为引用类型时 它的返回值一定是某一个变量的别名 8 7 3const类型变量 1 定义const型常量constintDeadLine 365 constfloatA 1 00009 用const定义的标识符常量时 一定要对其初始化 2 const型指针const是一个左结合的类型修饰符 用于指针的有以下几种情况 1 将const放在指针变量的类型的前面 constint A 表示指针变量所指向的值是一个常量 即指针A可变 指针所指向的数据 A不可变 2 将const放在指针变量的 的后面 int constA 表示指针A不可变 但是指针变量所指向的数据 A可变 在定义时必须赋初值 3 将一个const放在指针变量的类型的前面 将另一个const放在指针变量的 的后面 constint constA 表示指针变量所指向的值是一个常量 即指针A可变 指针所指向的数据也是一个常量 A也不可变 在定义时必须赋初值 8 7 4void型指针 说明void型指针的语法格式为 void 其中 指针变量 可指向任何类型的数据 可将任何地址赋给指针变量 实际使用void型指针时 只有通过强制类型转换才能使void型指针得到具体变量的值 在没有转换前 void型指针不能进行指针的算术运算 8 8简单链表 8 8 1链表概述8 8 2建立链表8 8 3链表的输出8 8 4链表的插入8 8 5链表的删除 8 8 1链表概述 链表是一种物理存储单元上非连续 非顺序的存储结构 数据元素的逻辑顺序是通过链表中的指针链接次序实现的 链表由一系列结点 链表中每一个元素称为结点 组成 结点可以在运行时动态生成 链表的结构如图8 11所示 图8 11链表结构示意图 8 8 2建立链表 创建链表的基本步骤如下 第一步 创建第一个节点 并将此节点的内存地址保存第二步 创建第二个节点 将第二个节点的首地址保存在第一个节点的成员变量中 第三步 以此类推 创建第n个节点 并将此节点的地址存储到第n 1节点的成员变量中 8 8 3链表的输出 链表的输出步骤如下 1 找到表头 2 若是非空表 输出节点的值成员 是空表则退出 3 跟踪链表的增长 即找到下一个节点的地址 4 转到 2 8 8 4链表的插入 在链表中插入节点的基本步骤如下 第一步 获得第一个节点的地址 第二步 找到插入节点的位置 第三步 创建新的节点InsertNode 第四步 将当前节点的下一节点信息存储到新创建节点InsertNode的成员变量 第五步 将InsertNode的地址存储到当前节点的成员变量中 第六步 结束 8 8 5链表的删除 删除链表的基本步骤如下 第一步 获得第一个节点的地址 第二步 根据第一个节点获得第二个节点地址 第三步 调用free函数释放第一个节点 第四步 根据第二个节点获得第三个节点地址 第五步 调用free函数释放第二个节点 第六步 以此类推从头到尾删除所有的对象 8 9类型定义 定义新类型标识符的一般格式为 typedef 类型 标识符1 标识符2 其中 类型是标准的类型名 如int float等 或是用户自定义的类型名 如结构体 共用体等 或是已定义的新类型标识符 经类型定义后 该标识符可以作为类型说明符或者作为强制类型标识符来使用 第9章 类和对象 本章主要内容 9 1面向对象的程序设计概述9 2类的声明和对象的定义9 3类的成员函数9 4对象成员的引用9 5类的封装性和信息隐藏 9 1面向对象的程序设计概述 9 1 1面向对象程序设计概念9 1 2面向对象程序设计的特点9 1 3类和对象的作用9 1 4面向对象的软件开发 9 1 1面向对象程序设计概念 简单地说 面向对象是一种观察和组织应用程序的方式 采用面向对象开发的程序是由若干对象构成 每个对象由一些数据和对数据所能实施的操作构成 如图9 1所示 对数据的操作通过向包含数据的对象发送消息 调用对象的操作 来实现 对象的特征 属性和行为 由根据多个具有相同特征的对象抽象出的类来描述 一个类所描述的特征可以从其他的类继承 面向对象程序设计就是采用面向对象的思想和方法进行的程序设计 图9 1对象的组成 对象 算法 数据结构程序 对象 对象 对象 消息 9 1 2面向对象程序设计的特点 面向对象的程序设计语言具有以下特点 1 对象唯一性每个对象都有自身唯一的标识 通过这种标识 可找到相应的对象 2 分类性分类性是指将具有一致的数据结构 属性 和行为 操作 的对象抽象成类 3 继承性继承性是子类自动共享父类数据结构和方法的机制 这是类之间的一种关系 4 多态性 多形性 多态性使指相同的操作或函数 过程可作用于多种类型的对象上并获得不同的结果 9 1 3类和对象的作用 在一个面向对象的系统中 对象是运行期的基本实体 在面向对象程序设计中 问题的分析一般以对象及对象间的自然联系为依据 类是对一组性质相同事物的程序描述 它由描述该类事物的共同特性的数据和处理这些数据的函数组成 9 1 4面向对象的软件开发 面向对象开发方法的开发过程分为以下几步 1 系统调查和需求分析 对系统将要面临的具体管理问题以及用户对系统开发的需求进行调查研究 2 分析问题的性质和求解问题 在繁杂的问题域中抽象地识别出对象及其行为 结构 属性 方法等 3 整理问题 对分析的结果作进一步的抽象 归类 整理 并最终以范式的形式将它们确定下来 4 程序实现 用面向对象的程序设计语言将上一步整理的范式直接映射 即直接用程序设计语言来取代 为应用软件 5 识别客观世界中的对象及行为 分别独立设计出各个对象的实体 分析对象之间的联系和相互所传递的信息 由此构成信息系统的模型 由信息系统模型转换成软件系统的模型 对各个对象进行归并和整理 并确定它们之间的联系 由软件系统模型转换成目标系统 面向对象开发方法有Booch方法 Coad方法和OMT方法等 9 2类的声明和对象的定义 9 2 1类和对象的关系9 2 2类的定义9 2 3对象的定义9 2 4类和对象的作用域9 2 5类和结构体类型的异同 9 2 1类和对象的关系 具有相同或相似性质的对象的抽象就是类 因此 对象的抽象是类 类的具体化就是对象 也可以说类的实例是对象 类具有属性 它是对象的状态的抽象 用数据结构来描述类的属性 类具有操作 它是对象的行为的抽象 用操作名和实现该操作的方法来描述 9 2 2类的定义 定义一个类 一般包括两个部分 说明部分和实现部分 类说明部分 是用来说明类中的成员 包含数据成员的说明和成员函数的说明 成员函数是用来对数据成员进行操作的 也称为 方法 类实现部分 对成员函数的定义 类的说明部分语法格式为 class public 公有成员protected 保护成员private 私有成员 其中 指定所定义的类的名称 它是一种自定义数据类型名 用标识符表示 类所拥有的成员包括数据成员和成员函数 分别描述类所表达问题的属性和行为 关键字public private和protected称为访问权限修饰符 它们限制了类成员的访问控制范围 9 2 3对象的定义 定义一个类时 就是定义一个类型 一旦定义了一个类 就可以定义该类的对象 为其分配存储空间 说明对象的一般格式为 存储类型 classnameobject1 object2 其中 存储类型 是指定对象的存储类型 classname是一个已经定义过的类名 object1 object2是为对象起的名字 对象名要符合标识符的定义 说明对象的方法有3种 第一种方法是先定义类的类型 再说明对象 第二种方法是在定义类的同时说明对象 第三种方法是直接说明对象 而不定义类的类名 9 2 4类和对象的作用域 在定义类时 用一对花括号将类体括起来的区域称为类的作用域 在类的作用域中说明的标识符仅在该类的作用域内有效 类的类型名的作用域与普通标识符的作用域相同 即在函数外定义的类 其类名作用域为文件作用域 在函数内定义的类 其类名作用域为块作用域说明 成员函数的作用域只要是在类中定义的 无论是不是内联 其函数名都属于类的作用域 不能直接通过调用函数名来实现调用函数 类的说明分为引用性说明和定义性说明 在说明类时 没有给出类体 仅给出类名 属于类的引用性说明 引用性说明不能用来建立对象 9 2 5类和结构体类型的异同 类的定义格式可以看出 类与结构体类型是相同的 类的成员可以是数据成员或函数成员 结构体中的成员与此类似 并且在结构体中 也可以使用关键字private public和protected限定其成员的访问权限结构体类型与类的唯一区别在于 在类中 其成员的默认的存取权限是私有的 而在结构体类型中 其成员的默认的存取权限是公有的 9 3类的成员函数 9 3 1成员函数的性质9 3 2在类外定义成员函数9 3 3内联成员函数9 3 4成员函数的存储方式 9 3 1成员函数的性质 类的成员函数是函数的一种 它的用法和作用与函数基本上是一样的 它也有返回值和函数类型 它与一般函数的区别只是 它是属于一个类的成员 出现在类体中 它可以被指定为private 私有的 public 公用的 或protected 受保护的 在使用类函数时要注意调用它的权限及其作用域 一般的做法是将需要被外界调用的成员函数指定为public 它们是类的对外接口 有的函数并不是准备为外界调用的 而是为本类中的成员函数所调用 就应该将它们指定为private 9 3 2在类外定义成员函数 类成员函数的实现可以放到类体外 当把类成员函数的实现放到类体外 则类的说明和实现完全分开 若在类体外定义成员函数 必须在成员函数名前加上类名和作用域运算符 作用域运算符用来标识成员属于某个类 作用域运算符的使用格式为 函数体类函数必须先在类体中作原型声明 然后在类外定义 也就是说类体的位置应在函数定义之前 否则编译时会出错 9 3 3内联成员函数 如果一个成员函数的说明和定义都在类体内 则该成员函数是内联函数 如果一个成员函数的说明在类体内 而函数的定义在类体外 这时对该成员函数的调用是按一般函数进行的 如果要将定义在类体外的成员函数也作为内联函数处理 就必须在成员函数的定义前加上关键字 inline 显式地说明该成员函数也是一个内联函数在使用内联函数时 应该注意以下几点 1 在内联函数内不允许用循环语句和开关语句 2 内联函数的定义必须出现在内联函数第一次被调用之前 9 3 4成员函数的存储方式 系统并不为类分配存储空间 当说明对象时 系统才为对象分配相应的存储空间 为对象分配存储空间的大小取决于在定义类时所定义的成员类型和成员多少 不同的对象占据内存中不同的区域 它们保存的数据各不相同 但是对成员数据的操作即成员函数的程序代码是相同的 为了减少成员函数所占用的空间 在建立对象时 只为对象分配用于保存成员数据的内存空间 而成员函数的代码则为该类的每一个对象所共享 9 4对象成员的引用 9 4 1通过对象名和成员运算符访问对象中的成员9 4 2通过指向对象的指针访问对象中的成员9 4 3通过对象的引用访问对象中的成员 9 4 1通过对象名和成员运算符访问对象中的成员 访问对象中成员的一般形式为 对象名 成员名 例如 定义一个类的对象a 则可以用以下形式访问a的成员 a s a r a q分别表示访问对象a的s成员 r成员和q成员 a set 表示调用对象a的成员函数set 9 4 2通过指向对象的指针访问对象中的成员 定义一个类的对象a和一个指针p 则可以通过指向对象的指针访问对象a中的成员 代码如程序清单9 17所示 includeclassA public ints intr intq voidset cin s r q voidmain void coutsrq endl 说明 p s p r p q分别表示p指向当前对象a的成员s r q 在p 的前提下 p s p s与a s等价 程序清单9 17通过指向对象的指针访问对象中的成员 9 4 3通过对象的引用访问对象中的成员 如果为一个对象定义了一个引用变量 它们是共占同一段存储单元的 实际上它们是同一个对象 只是用不同的名字表示而已 因此完全可以通过引用变量来访问对象中的成员 其概念和方法与通过对象名来引用对象中的成员是相同的 对于类A 定义一个类的对象a和一个引用变量b 则可以用以下形式访问a的成员 9 5类的封装性和信息隐藏 9 5 1公用接口和私有实现的分离9 5 2类声明和成员函数定义的分离 9 5 1公用接口和私有实现的分离 类的作用是把数据和算法封装在用户声明的抽象数据类型中 在面向对象的程序设计中 在声明类时 一般都是把所有的数据指定为私有的 使它们与外界隔离 把需要让外界调用的成员函数指定为公用的 外界通过公用的函数来实现对数据的操作 外界与对象唯一的联系渠道就是调用公用的成员函数 这样就使类与外界的联系减少到最低限度 在声明了一个类以后 用户主要是通过调用公用的成员函数来实现类提供的功能 因此 公用成员函数是用户使用类的公用接口 类中被操作的数据通常是私有的 实现的细节对用户是隐蔽的 这种实现称为私有实现 这种 类的公用接口与私有实现的分离 形成了信息隐蔽 9 5 2类声明和成员函数定义的分离 在面向对象的程序开发中 一般做法是将类的声明 其中包含成员函数的声明 放在指定的头文件中 用户如果想用该类 只要把有关的头文件包含进来即可 不必在程序中重复书写类的声明 以减少工作量 节省篇幅 提高编程的效率 由于在头文件中包含了类的声明 因此在程序中就可以用该类来定义对象 由于在类体中包含了对成员函数的声明 在程序中就可以调用这些对象的公用成员函数 通常对类成员函数的定义一般不放在头文件 h中 而另外放在一个文件 cpp中 9 6this指针 C 提供了一个this指针来时时刻刻指向一个实例本身 它是成员函数所属对象的指针 它指向类的对象的地址 成员函数通过这个指针可以知道它属于哪一个对象 任何一个方法都是在一个对象中 而如果想调用一个方法 而这个方法又是属于这个对象 那么在不方便写出这个对象时 就可以用this来代替 编译程序先将对象的地址赋给this指针 然后调用该成员函数 第10章 构造函数和析构函数 本章主要内容 10 1构造函数10 2析构函数10 3调用构造函数和析构函数的顺序10 4对象数组和对象指针10 5共用数据的保护10 6对象的动态建立和释放10 7对象的赋值和复制10 8静态成员10 9友元 10 1构造函数 10 1 1定义构造函数10 1 2对象的初始化10 1 3构造函数的作用10 1 4带参数的构造函数10 1 5用参数初始化列表对数据成员初始化10 1 6默认的构造函数10 1 7构造函数的重载 10 1 1定义构造函数 在定义一个类时 可根据需要定义一个或多个构造函数 构造函数与类的成员函数一样 可以在类中定义函数体 也可在类外定义函数体 在类中定义构造函数的一般语法格式为 ClassName 函数体在类外定义构造函数的一般格式为 ClassName ClassName 函数体对构造函数 须说明以下几点 1 构造函数的函数名必须与类名相同 2 因构造函数是由系统自动调用的 构造函数与其他成员函数不一样 在定义构造函数时 不能指定函数返回值的类型 也不能指定为void类型 3 构造函数可以不带参数 也可以带若干个参数 也可以指定参数的默认值 4 若定义的类要说明该类的对象时 构造函数必须是公有的成员函数 5 在构造函数的函数体中不仅可以对数据成员赋初值 而且可以包含其他语句 如cout语句 6 如果用户自己没有定义构造函数 则C 系统会自动生成一个构造函数 只是这个构造函数的函数体是空的 也没有参数 不执行初始化操作 10 1 2对象的初始化 在产生对象时 对对象的数据成员进行初始化的方法有3种 1 使用初始化数据列表的方式 2 通过构造函数实现初始化 3 通过对象的复制初始化函数实现 构造函数 Constructor 是类的一个特殊的成员函数 它的特点如下 1 构造函数是类的成员函数 在类内声明 可以在类体内或类体外实现 2 构造函数名与类名相同 3 构造函数无返回值 4 构造函数在创建对象时 自动调用 不需要程序员写代码显式调用 10 1 3构造函数的作用 通常在产生对象时 使用构造函数对数据成员进行初始化 而不是通过直接初始化列表的方式 10 1 4带参数的构造函数 在创建一个对象时 构造函数会被自动调用 至于调用哪个构造函数 由创建对象时对象名后面的实参数列表来确定 语法格式为 对象名 编译器根据对象名后的 采用重载函数的调用规则选择匹配的构造函数并调用 若对象名后没有 则调用的是无参数的构造函数 若想让对象调用无参数构造函数 不要在对象名后指定任何参数 也不要小括号 10 1 5用参数初始化列表对数据成员初始化 参数初始化表来实现对数据成员的初始化 这种方法不在函数体内对数据成员初始化 而是在函数首部实现 某个对象object的初始化过程 1 根据创建对象object时指定的参数确定对象初始化所要调用的构造函数 2 初始化对象object中的每个数据成员 如调用对象成员的构造函数等 10 1 6默认的构造函数 在定义类时 若没有定义类的构造函数 则编译器自动产生一个默认的构造函数 其格式为 ClassName ClassName 关于默认的构造函数 说明以下几点 1 在定义类时 若定义了类的构造函数 则编译器就不产生默认的构造函数 2 在类中 若定义了没有参数的构造函数或各参数均有默认值的构造函数 也称为默认的构造函数 默认的构造函数只能有一个 3 要对对象的数据成员进行初始化时 必须定义构造函数 4 产生对象时 系统必定要调用构造函数 所以任一对象的构造函数必须唯一 10 1 7构造函数的重载 当用new动态地建立一个对象时 自动调用构造函数来初始化对象 new的对象有参数 则调用带参数的构造函数 new的对象无参数 则调用不带参数的构造函数 最后必须要用delete动态分配内存空间 对对象的数据成员进行初始化的第三种方法是通过对象的复制初始化函数实现 复制构造函数的语法格式为 const 复制构造函数体 其中 修饰词const可有可无 复制构造函数也是构造函数 函数名与类名相同 它只有一个参数 同类对象的引用 每一个类中必定有一个复制构造函数 如果类中没有显式定义复制构造函数时 编译器为该类自动生成上述格式的公有的复制构造函数 它完成对象间数据成员值的复制 10 2析构函数 10 2 1析构函数的定义10 2 2默认的析构函数10 2 3不同存储类型的对象调用构造函数及析构函数 10 2 1析构函数的定义 析构函数也是类的成员函数 在类中定义构造函数的一般语法格式为 ClassName 函数体在类外定义构造函数的一般语法格式为 ClassName ClassName 函数体对于析构函数 须说明以下几点 1 系统约定 析构函数名必须与类名相同 并在其前面加上字符 以便和构造函数名相区别 2 析构函数不能带有任何参数 不能有返回值 函数名前也不能用关键字void 3 析构函数是在撤销对象时由系统自动调用 它的作用是在撤销对象之前做好结束工作 10 2 2默认的析构函数 在定义类时 若没有定义类的析构函数 则编译器自动产生一个默认的析构函数 其语法格式为 ClassName ClassName 从定义格式可以看出 这是一个函数体为空的析构函数 函数什么事也不做 在撤销对象时 若不做任何结束工作 可以不显式地定义析构函数 例如 定义以下的类sample classsample intmember 则编译器自动提供的析构函数代码为 sample 但在撤销对象时 要释放对象的数据成员用new运算符分配的动态空间时 必须显式地定义析构函数 10 2 3不同存储类型的对象调用构造函数及析构函数 通常在产生对象时调用构造函数 在撤销对象时调用析构函数 但对于不同存储类型的对象 调用构造函数与析构函数的情况有所不同 1 对于全局定义的对象 在程序开始执行时 调用构造函数 在程序的流程离开其作用域时 调用析构函数 2 对于在函数内定义的对象 自动局部对象 当程序执行到对象的地方时 调用构造函数 在退出对象的作用域时 调用析构函数 3 用static定义的局部对象 在首次到达对象的定义时调用构造函数 在函数调用结束时对象并不释放 因此也不调用析构函数 只在main函数结束或调用exit函数结束程序时 才调用static局部对象的析构函数 4 对于用new运算符动态生成的对象 在产生对象时调用构造函数 只有使用delete运算符来释放对象时 才调用析构函数 若不使用delete运算符来撤销动态生成的对象 程序结束时对象仍存在 并占用相应的存储空间 即系统不能自动地调用析构函数来撤销动态生成的对象 10 3调用构造函数和析构函数的顺序 析构函数的调用顺序与构造函数相反 最先被调用的构造函数 其对应的 同一对象中的 析构函数最后被调用 而最后被调用的构造函数 其对应的析构函数最先被调用 10 4对象数组和对象指针 10 4 1对象数组10 4 2对象指针

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论