




已阅读5页,还剩37页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C+面向对象程序设计 第四章 数组、指针与字符串,陈春丽 CCL,第四章 数组、指针与字符串,4.1 数组 4.2 指针 4.3 动态内存分配 4.4 深拷贝与浅拷贝 4.5 字符串,4.1 数组,数组是具有一定顺序关系的若干相同类型变量的集合体,数组属于构造类型 1)数组的长度是固定的 2)数组元素在内存中顺次存放,它们的地址是连续的 3)数组名是数组首元素的内存地址 4)数组名是一个常量,不能被赋值 一维数组的声明 类型说明符 数组名 常量表达式 ; 例如:int a10; 表示 整型数组a有10个元素a0.a9 引用 必须先声明,后使用。只能逐个引用数组元素,而不能一次引用整个数组。例如:a0=a5+a7-a2*3,例4. 1一维数组的声明与引用,#include using namespace std; int main() int A10,B10; int i; for(i=0;i10;i+) Ai=i*2-1; B10-i-1=Ai; ,for(i=0;i10;i+) cout “A“ i “=“ Ai; cout “ B“ i “=“ Bi endl; ,二维数组的声明及引用,声明 类型说明符 数组名常量表达式常量表达式; 例如:float a34;,存储顺序:按行存放,上例中数组a的存储顺序为:,引用 例如:b12=a23/2(下标不要越界),数组作为函数参数,1)数组元素作实参,与单个变量一样 2)数组名作参数,形、实参数都应是数组名,类型要一样,传送的是数组首地址 对形参数组的改变会直接影响到实参数组 例4-2:使用数组名作为函数参数 定义一个函数,计算矩阵中每一行的元素之和,将和直接存放在每行的第一个元素中 主函数测试,#include using namespace std; void RowSum(int A4, int nrow) int sum; for (int i = 0; i nrow; i+) sum = 0; for(int j = 0; j 4; j+) sum += Aij; cout “Sum of row “ i “ is “ sum endl; Ai0=sum; int main() int Table34 = 1,2,3,4,2,3,4,5,3,4,5,6; for (int i = 0; i 3; i+) for (int j = 0; j 4; j+) cout Tableij “ “ endl; RowSum(Table,3); for (int i = 0; i 3; i+) cout Tablei0; ,运行结果: 1 2 3 4 2 3 4 5 3 4 5 6 Sum of row 0 is 10 Sum of row 1 is 14 Sum of row 2 is 18 10 14 18,对象数组,声明:类名 数组名元素个数; 访问形式:数组名下标.成员名 对象数组初始化 数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象(同样,当数组中每一个对象被删除时,系统都要调用一次析构函数) 通过初始化列表赋值。 例:Point A2=Point(1,2),Point(3,4); 如果没有为数组元素指定显式初始值,数组元素便使用默认值初始化(调用默认构造函数),例4-3 对象数组应用举例,/Point.h class Point public: Point(); Point(int xx,int yy); Point(); int GetX() return X; int GetY() return Y; void Display(); void Move(int x,int y); private: int X,Y; ;,/Point.cpp #include using namespace std; #include “Point.h“ Point:Point() X=Y=0; cout“Default Constructor.“endl; Point:Point(int xx,int yy) X=xx; Y=yy; cout “Constructor called.“endl; Point :Point() cout“Destructor called.“endl; void Point :Move(int x,int y) X=x; Y=y; void Point:Display() cout “(“ x “,“ y “)“; ,/prjPoint.cpp #include using namespace std; #include “Point.h“ int main() cout“Entering main.“endl; Point A2; for(int i=0;i2;i+) Ai.Move(i+10,i+20); Ai.Display(); cout endl; cout“Exiting main.“endl; ,运行结果: Entering main. Default Constructor. Default Constructor . (10,20) (11,21) Exiting main. Destructor called. Destructor called.,4.2 指针,内存空间的访问方式 通过变量名访问 通过地址访问 地址运算符:则&var 表示变量var在内存中的起始地址 指针:内存地址,用于间接访问内存单元 指针变量:用于存放地址的变量,声明: 例:int i; int *p = 指向整型变量的指针,引用: 例1:i = 3; 例2:*p = 3;,指针变量的初始化,语法形式 存储类型 数据类型 *指针名初始地址; 例:int *pa= 注意事项 用变量地址作为初值时,该变量必须在指针初始化之前已说明过,且变量类型应与指针类型一致 可以用一个已赋初值的指针去初始化另一 个指针变量 不要用一个内部 auto 变量去初始化 static 指针,指针变量的赋值运算,指针名=地址 “地址”中存放的数据类型与指针类型必须相符 向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针 指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针本身的数据值都是unsigned long int型 允许声明指向 void 类型的指针。该指针可以被赋予任何类型对象的地址。例: void *general;,例:指针的声明、赋值与使用,#include using namespace std; int main() int *i_pointer; int i; i_pointer= ,程序运行的结果是: Output int i=10 Output int pointer i=10,指针变量的算术运算,指针与整数的加减运算 指针p加上或减去n,其意义是指针当前指向位置的前方或后方第n个数据的地址 这种运算的结果值取决于指针指向的数据类型 指针加一,减一运算 指向下一个或前一个数据 例如:y=*px+ 相当于 y=*(px+) (*和+优先级相同,自右向左运算),指针变量的关系运算,关系运算 指向相同类型数据的指针之间可以进行各种关系运算。 指向不同数据类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。 指针可以和零之间进行等于或不等于的关系运算。例如:p=0或p!=0 赋值运算 向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针,指向数组元素的指针,声明与赋值 例:int a10, *pa; pa= 通过指针引用数组元素 经过上述声明及赋值后: *pa就是a0,*(pa+1)就是a1,. ,*(pa+i)就是ai. ai, *(pa+i), *(a+i), pai都是等效的。 不能写 a+,因为a是数组首地址是常量,设有一个int型数组a,有10个元素。用三种方法输出各元素:(1)使用数组名和下标;(2)使用数组名和指针运算;(3)使用指针变量,使用数组名和下标 int main() int a10; int i; for(i=0; iai; coutendl; for(i=0; i10; i+) coutai; ,使用数组名和指针运算 int main() int a10; int i; for(i=0; iai; coutendl; for(i=0; i10; i+) cout*(a+i); ,使用指针变量 int main() int a10; int *p,i; for(i=0; iai; coutendl; for(p=a; p(a+10);p+) cout*p; ,指针数组,数组的元素是指针型 例:Point *pa2;数组pa由pa0,pa1两个指针组成 例:利用指针数组存放单位矩阵,#include using namespace std; int main() int line1=1,0,0; int line2=0,1,0; int line3=0,0,1; int *p_line3; p_line0=line1; p_line1=line2; p_line2=line3;,/输出单位矩阵 cout“Matrix test:“endl; for(int i=0;i3;i+) /对指针数组元素循环 for(int j=0;j3;j+)/对矩阵每一行循环 coutp_lineij“ “; coutendl; ,输出结果为: Matrix test: 1,0,0 0,1,0 0,0,1,以指针作为函数参数,以地址方式传递数据,可以用来返回函数处理结果 实参是数组名时形参可以是指针 题目:读入三个浮点数,将整数部分和小数部分分别输出,#include using namespace std; void splitfloat(float x, int *intpart, float *fracpart) /形参intpart、fracpart是指针 *intpart=int(x); / 取x整数部分 *fracpart=x-*intpart; /取x小数部分 ,int main() int i, n; float x, f; cout x; splitfloat(x, ,运行结果: Enter three(3) floating point numbers: 4.7 Integer Part is 4 Fraction Part is 0.7 8.913 Integer Part is 8 Fraction Part is 0.913 -4.7518 Integer Part is -4 Fraction Part is -0.7518,指向常量的指针,不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。 例1 char *name1=“John“; /name1是一般指针 *name1=A; /编译正确,运行出错 例2 const char *name1=“John“; /指向常量的指针 char s=“abc“; name1=s; /正确,name1本身的值可以改变 *name1=1; /编译时指出错误,指针类型的常量,若声明指针常量,则指针本身的值不能被改变 例: char *const name2=“John“; name2=“abc“;/错误,指针常量值不能改变,指向变量的指针:int *p,a; p=,4.3 动态内存分配,运算符new: 功能:动态分配内存 语法:new 类型名 对象名(初值列表); 例如:int *p; p=new int(2); 运算符delete: 功能:删除由new建立的对象,释放该指针指向的空间 格式:delete 指针名; 注意: 用new建立的对象,只能使用delete一次删除 用delete运算符作用的对象必须是用new分配的内存空间的首地址,例如:一维数组的创建与删除: int size,count; int *array; cinsize; array = new intsize ; /数组大小可以是变量 delete array; /释放堆内存,数组的创建与删除,也可以创建多维数组,其中第一维可以是变量,其他维数必须是常量 int row=3; const int col=5; double (*ptr)col=new doublerowcol; delete ptr;,#include #include using namespace std; int main() float (*cp)5; cp = new float45; int i,j; for (i=0; i4; i+) for (j=0; j5; j+) *(*(cp+i)+j)=i*10+j*1; for (i=0; i4; i+) for (j=0; j5; j+) coutcpij“ “; coutendl; coutendl; ,运行结果为: 0 1 2 3 4 10 11 12 13 14 20 21 22 23 24 30 31 32 33 34,#include “Point.h“ int main() cout“Step One:“endl; Point *Ptr1= new Point; delete Ptr1; cout“Step Two:“endl; Ptr1=new Point(1,2); delete Ptr1; return 0; ,#include using namespace std; class Point public: Point() X=Y=0; cout“Default Constructor.n“; Point (int xx,int yy) X=xx;Y=yy; cout “Constructor called.n“; Point() cout“Destructor called.n“; int GetX() return X; int GetY() return Y; void Move(int x,int y) X=x; Y=y; private: int X,Y; ;,运行结果: Step One: Default Constructor. Destructor called. Step Two: Constructor called. Destructor called.,常见的内存错误及其对策,1)内存分配未成功,却使用了它。 动态分配不成功时,指针为空指针(NULL)。 如果是用new来申请内存,应该用if(p=NULL) 或if(p!=NULL)进行防错处理。 2)内存分配虽然成功,但是尚未初始化就引用它 内存的缺省初值究竟是什么并没有统一的标准。所以必须赋初值后方可以使用,即便是赋零值也不可省略,3)内存分配成功并且已经初始化,但操作越过了内存的边界 例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界 4)忘记了释放内存,造成内存泄露 程序执行时申请的内存忘了释放,函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,终有一次程序突然死掉:内存耗尽 5)释放了内存却继续使用它 动态内存的申请与释放必须配对,4.4 深拷贝与浅拷贝,C+提供的默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),testCopy1,深拷贝 当被复制的对象数据成员是指针类型时,不是复制该指针成员本身,而是将指针所指的对象进行复制,testCopy2,4.5 字符串,1使用字符数组和字符指针实现字符串 例如: char str10=“hello“; char *pStr=“welcome“; 说明:可以初始化,但是不能赋值。例如: char str10; str = “hello“; /错误,2C+中提供了string类型,更方便,string是C+标准库中声明的一个字符串类。# include 1)定义字符串变量。 与int、char等基本数据类型的定义方法类似例如: string str1; /定义变量 string str2=“China“; /定义的同
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 行政管理核心考点试题及答案
- 高考数学考核趋势题目及答案2023
- 敏捷项目管理2025年考试试题及答案
- 科学探索活动实施方案计划
- 课程整合幼儿园班级的有效探索计划
- 法学概论复习季度计划与分配试题及答案
- 2025届吉林省长春市数学七下期末检测模拟试题含解析
- 2025届湖北省十堰市郧西县八年级数学第二学期期末达标检测模拟试题含解析
- 企业战略与政策风险试题及答案
- 城市交通信号控制策略重点基础知识点
- (高清版)DG∕TJ 08-7-2021 建筑工程交通设计及停车库(场)设置标准
- 无房无车离婚协议书
- 2025-2030年中国甲巯咪唑片行业市场现状供需分析及投资评估规划分析研究报告
- 史明清时期社会经济的发展课件++2024-2025学年统编版七年级历史下册
- 2025年安徽国控资产管理有限公司第二季度社会招聘5人笔试参考题库附带答案详解
- 2025中考语文7-9年级总复习古诗词默写
- 中国特色社会主义+综合练习(三)-2025届中职高考政治一轮复习高教版(2023版)
- 情境+任务驱动作文(兼审“情境”与“任务”)-2024年中考语文重难点复习专练(江苏)学生版
- (二模)临沂市2025年高三高考模拟考试地理试题卷(含答案)
- 2024年新疆巴楚县事业单位公开招聘村务工作者笔试题带答案
- 城管协管笔试题及答案
评论
0/150
提交评论