数组指针与字符串.ppt_第1页
数组指针与字符串.ppt_第2页
数组指针与字符串.ppt_第3页
数组指针与字符串.ppt_第4页
数组指针与字符串.ppt_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

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

文档简介

第六章 数组、指针与字符串 C+语言程序设计 本章主要内容 u数组 u指针 u动态存储分配 u指针与数组 u深拷贝与浅拷贝 u字符串 2 6.1.4 对象数组(P163) u声明: 类名 数组名元素个数; u访问方法:通过下标访问 数组名下标.成员名 3 对象数组初始化 u数组中每一个元素对象被创建时,系统都 会调用该类的构造函数初始化该对象 u通过初始化列表赋值 Point A2=Point(1,2),Point(3,4); u如果没有为数组元素指定显式初始值,数 组元素便使用默认值初始化(调用默认构 造函数) 4 数组元素所属类的构造函数 u不声明构造函数,则采用默认构造函数 u各元素对象的初值要求为相同的值时, 可以声明具有默认形参值的构造函数 u各元素对象的初值要求为不同的值时, 需要声明带形参的构造函数 u当数组中每一个对象被删除时,系统都 要调用一次析构函数 5 u例: 对象数组应用举例(L6_对象数组) u例: 利用Point类进行点的线性拟合 (P165) 6 指针 u情形1:定义寻址一个常量的指针 nint number=10; nconst int *pn= npn是常量整数的指针,pn所指的值不能通 过pn改变,但是可以改变pn,寻址int类型的 不同变量 int x=1,y=2; pn= *pn=6; pn= *pn+=1; 有效赋值 无效赋值,不能通过pn改变x的值 有效赋值 无效赋值,不能通过pn改变x的值 7 u情形2:const变量地址只能赋予一个常量的指 针 nconst int number=10; nconst int *pn= n但是常量指针可以变为普通变量的新地址 const int x=1; int y=2; const int *apn; int *bpn; apn= bpn= apn= 有效赋值 无效赋值 有效赋值 8 u情形3:可以定义变量的指针常量 nint number=10; nint * const pn= npn是个指针常量,指向整数 n这个整数可变,但指针常量不能指向别的 地方 int x=1,y=2; int * const apn; apn= *apn=6; apn= 有效赋值 有效赋值 无效赋值,不能改变 const指针 9 u情形4:可以用限定符号声明指针常量,指向常 量值 nconst int number=10; nconst int * const pn= npn是个常量整数的指针常量 npn所指的值不能改变,pn也不能指向别的 地方 const int x=1; int y=2; const int * const apn= *apn=6; apn= 有效赋值 无效赋值 无效赋值,不能改变 const指针 10 uvoid指针: n任何类型的指针都可以赋值给void类 型的指针变量 n经过强制类型转换,通过 void类型 的指针便可以访问任何类型的数据 n也可以指向除类成员函数以外的函数 n例:P172 11 6.2.7 指针数组 u类型名 *数组名下标表达式; u int *p10; u指针数组的每个元素都是一个指针 u使用原则:先赋值,后引用 u例:P176、P177 12 6.2.9 指针型函数 u 数据类型T *函数名(参数表) u u /函数体 u return 数据类型T的指针; u 13 6.2.10 指向函数的指针 u函数指针:专门用来存入函数代码首地址的变 量 u一旦函数指针指向了某个函数,即可使用函数 指针来调用函数 u声明:数据类型 (*函数指针名)(形参表); u赋值:函数指针名=函数名; u调用:函数指针名(形参); u注意:该指针只能指向已经声明,且与该函数 指针具有相同返回值类型和相同形参表的函数 u例:P180 14 6.2.11 对象指针的一般概念 u对象指针是用于存放对象地址的变量 u声明形式 类名 *对象指针名; u Point A(5,10); Piont *ptr; ptr= u通过指针访问对象成员 对象指针名-成员名 ptr-getx() 相当于 (*ptr).getx(); 15 对象指针应用举例 #include using namespace std; void main() Point A(5,10); Point *ptr; ptr= int x; x=ptr-GetX(); /x=(*ptr).GetX(); couthour=hour; 25 说明 uthis指针是隐含于每一个类的成员函数中 的特殊指针(包括构造函数和析构函数) u每次调用非静态成员函数时,自动提供 this指针 uthis指针指向各个对象,每次调用成员函 数时,把这个对象的this指针作为隐藏的 第一个变元传入成员函数 uthis指针是一个常量,不能修改。 26 指向类的非静态成员的指针(P183) u可以使用指针直接指向对象的成员 u通过指向成员的指针只能访问公有成 员 n指向公有成员变量的指针 n指向公有成员函数的指针 27 指向类的非静态公有数据成员的指针 u类型说明符 类名:*指针名; u指针名= nint *pn=new int(2); u注意: n变量是指针变量。 n类型是char、int或float数据类型。 n左边的变量应与右边的变量类型匹配。 nnew运算符无法从自由空间分配存储时( 即没有满足请求的内存容量时),返回一个 null指针 32 u用delete运算符释放内存 ndelete 指针变量; u注意: ndelete运算符只释放自由内存字节,而不 删除自由存储地址的指针 n一定要配对地使用new主和delete,否则 将发生内存泄漏 n如果被删除的是对象,则调用该对象的析 构函数 n对于用new建立的对象,只能使用delete 进行一次删除操作,否则将导致运行错误 33 两种类型的指针变量: 静态指针。 n先声明一个变量。 n然后声明一个相同类型的指针, 将变量的地址赋给指针。 n该指针就是静态指针。 n它的生存期在书写程序时确定, 或者说它的生存期是由变量确定的。 n例:int iNum=100; n int *iPtr= 34 n动态指针:在程序需要附加内存时创 建。 int *iPtr=new int; *iPtr=10; *iPtr=*iPtr+10; coutname,20); cin(*ps).age; cinps-socre; 39 浅拷贝与深拷贝 u浅拷贝 n实现对象间数据元素的一一对应复制 n默认的拷贝构造函数 u深拷贝 n当被复制的对象数据成员是指针类型 时,不是复制该指针成员本身,而是将 指针所指的对象进行复制 40 存在两种形式的类 u类中仅存在变量或对象,不具备指针成员 n缺省的拷贝构造函数和赋值运算符函 数是浅拷贝的方式 n该方式通过memcpy函数将源实例的数 据复制给目标实例占有的一片内存空间 n对于这样的类,缺省的浅拷贝方式是 安全的 u类含有指针成员 n浅拷贝不再胜任这样的类 41 考虑如下说明: 一个CDeep类的声明和对象定义 a.n a.p a.p=new inta.n b.n b.p b.p=new intb.n ?=new intb.na.n a.pa.p=new inta.nb.n b.p class CDeep public: private: int n; int*p; a, b; 中间深资源归口两个对象监控 对于存在指针成员的类,系统提供的浅拷贝 导致指针指向的内存为两个对象共享的格局 对象a,b的内存和指针成员动态扩展的内存空间b=a导致 b.p=a.p; b.n=a.n; 。指针b.p指向a对象的动态内存 42 u浅拷贝的不良结果是: ub.p原先指向的堆空间悬空 n既无法索引也不能收回这片内存 na或b对象的析构函数诱发中间共享的 深资源的流失 43 u例:对象的浅拷贝(P192) 44 拷贝前 拷贝后 pointsArray1的数组 元素占用的内存 points numberOfPoints pointsArray1 points numberOfPoints pointsArray1 pointsArray1的数组 元素占用的内存 points numberOfPoints pointsArray2 45 45 u如果类中包含了使用new初始化的指针成 员,应当定义一个拷贝构造函数,以复制 指向的数据,而不是指针 46 u例:对象的深拷贝(P194) 47 拷贝前 pointsArray1的数组 元素占用的内存 points numberOfPoints pointsArray1 拷贝后 points numberOfPoints pointsArray1 pointsArray1的数 组元素占用的内存 points numberOfPoints pointsArray2 48 48 u深拷贝的核心思路是: n目标对象与源对象内存空间独立,相应指 针成员指向的内存空间也彼此独立 n全部拷贝源对象的数据到目标对象,包括 分别拷贝指针成员指向的内存数据 u应定义一个拷贝构造函数,通过深拷贝将一个 对象初始化为另一个对象 u拷贝构造函数应分配足够的空间来存储复制的 数据,并复制数据,而不仅仅是数据的地址。 另外还应更新所有受影响的静态类成员。 u应当定义一个赋值运算符,通过深拷贝将一个 对象复制给另一个对象 49 u在构造函数中使用new中应注意的问题: n如果在构造函数中使用new来初始化 指针成员,则应在析构函数中使用 delete释放 nnew和delete必须相互兼容。 n new对应delete n new对应 delete n如果有多个构造函数,则必须以相同 的方式使用new,要么都带,要么都不 带。因为只有一个析构函数 50 6.5.2 string类 u用string类的变量存储字符串 u必须在程序中包含头文件 ustring类位于名称空间std中 ustring类封装了串的属性并提供了一系 列允许访问这些属性的服务 u使用string对象的方式与使用字符数组 相同 u类设计让程序能够自动处理string的大 小 51 u类的数据组件 n字符序列 n字符序列的大小或长度 n序列中字符的类型 n字符的特点 n一个字符的大小 n分配算符 n迭代器 u有关串操作的服务 n查找、分配、连接、追加 52 u构造函数 nstring(); nstring(const string nstring(const char *s); nstring(const string nstring(const char *s,unsigned int n); nstring(unsigned int n,char c); 53 常用成员函数 ustring append(const char *s); u添加串对象、字符数组或单个字符到另一个串对 象 ustring assign(const char *s); uint compare(const string ustring ustring substr(unsigned int pos, unsigned int n)const; uunsigned int find(const basic_string uunsigned int length()const; uvoid swap(string 54 usize() ,返回string对象元素的个数 uresize(),用来改变string对象的大小 uerase(),返回string对象中的所有字符 uempty(),如果size=0,返回true 55 构造string 类对象 u构造一个空的string对象 nstring str1; u用一个字符串数组构造一个string对象 nstring str2(“China“); u用一个string对象构造另一个string对 象 nstring str3(str2); 56 给字符串对象赋值 u将一个字符赋值给一个string对象 nstr1=a; u将一个字符数组赋值给一个string对象 nstr2=“Wust“; u将一个string对象赋给另一个string对 象 nstr3=str2; 57 u字符串的连接 nstr3=str1+str2; nstr3=str1+str2+!; nstr1+=str2; nstr1+=!; u字符串的下标 n可以用下标运算符或成员函数at(int)来检 索字符串的某个字符或修改字符串中的某个字 符 nchar ch1=str31; nchar ch2=str3.at(1);

温馨提示

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

评论

0/150

提交评论