C++程序设计-郑莉第四版(第6章).ppt_第1页
C++程序设计-郑莉第四版(第6章).ppt_第2页
C++程序设计-郑莉第四版(第6章).ppt_第3页
C++程序设计-郑莉第四版(第6章).ppt_第4页
C++程序设计-郑莉第四版(第6章).ppt_第5页
已阅读5页,还剩93页未读 继续免费阅读

下载本文档

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

文档简介

1,第六章数组指针与字符串,C+语言程序设计,2,本章主要内容,数组指针指针与数组指针与函数动态存储分配字符串,3,数组的概念,数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。因此当需要多个同类型变量时就要考虑定义数组。,数组,4,数组的说明与使用,数组的声明一般形式:类型说明符标识符常量表达式1;例如:inta10;表示a为整型数组,有10个元素:a0.a9,数组,引用必须先声明,后使用。只能逐个引用数组元素,而不能一次引用整个数组例如:a0=a5+a7-a2*3,5,数组的说明与使用,数组,数组的使用使用数组时,只能分别对数组的各个元素进行操作。数组的元素是由下标来区分的,对于一个已经声明过的数组,其元素的使用形式为:数组名下标表达式1下标表达式2,使用数组注意:(1)数组元素的下标表达式可以是任意合法的算术表达式,其结果必须为整型数。(2)数组元素的下标值不得超过声明时所规定的上下界,否则运行时数组越界错误。,6,例:给出下面程序的输出结果。#includeintcount5=1,2;voidmain()inti;charc=hello!;for(i=0;i=4;i+)coutcountiendl;coutcendl;coutsizeof(c)endl;coutcountendl;coutsizeof(count)endl;coutsizeof(count)/sizeof(int)endl;,运行结果为:1/count02/count10/count20/count30/count5hello!/输出字符串c7/字符串c长度为70 x00408040/数组count首地址20/数组count占总字节数5/数组count元素个数,7,一维数组的存储顺序,数组元素在内存中顺次存放,它们的地址是连续的。例如:具有10个元素的数组a,在内存中的存放次序如下:,数组名字是数组首元素的内存地址。数组名是一个常量,不能被赋值。,数组,8,一维数组的初始化,可以在编译阶段使数组得到初值:在声明数组时对数组元素赋以初值。可以只给一部分元素赋初值。在对全部数组元素赋初值时,可以不指定数组长度。,数组,例如:staticinta10=0,1,2,3,4,5,6,7,8,9;,例如:staticinta10=0,1,2,3,4;,例如:staticinta=1,2,3,4,5,9,二维数组的声明及引用,数据类型标识符常量表达式1常量表达式2;例:inta53;表示a为整型二维数组,其中第一维有5个下标(04),第二维有3个下标(02),数组的元素个数为15,可以用于存放5行3列的整型数据表格。,数组,存储顺序按行存放,上例中数组a的存储顺序为:,二维数组的声明类型说明符数组名常量表达式常量表达式例如:floata34;,引用例如:b12=a23/2,下标不要越界,二维数组的声明及引用,数组,分行给二维数组赋初值例如:staticinta34=1,2,3,4,5,6,7,8,9,10,11,12;将所有数据写在一个内,按顺序赋值例如:staticinta34=1,2,3,4,5,6,7,8,9,10,11,12;可以对部分元素赋初值例如:staticinta34=1,0,6,0,0,11;,二维数组的初始化,数组,12,数组作为函数参数,数组元素作实参,与单个变量一样。数组名作参数,形、实参数都应是数组名,类型要一样,传送的是数组首地址。对形参数组的改变会直接影响到实参数组。,数组,13,例6-2使用数组名作为函数参数,例:主函数中初始化一个矩阵并将每个元素都输出,然后调用子函数,分别计算每一行的元素之和,将和直接存放在每行的第一个元素中,返回主函数之后输出各行元素的和。,数组,#includevoidRowSum(intA4,intnrow)intsum;for(inti=0;inrow;i+)sum=0;for(intj=0;j4;j+)sum+=Aij;coutSumofrowiissumendl;,voidmain(void)intTable34=1,2,3,4,2,3,4,5,3,4,5,6;for(inti=0;i3;i+)for(intj=0;j4;j+)coutTableij;coutendl;RowSum(Table,3);,运行结果:123423453456Sumofrow0is10Sumofrow1is14Sumofrow2is18,17,对象数组,声明:类名数组名元素个数;访问方法:通过下标访问数组名下标.成员名,数组,18,对象数组初始化,数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象。通过初始化列表赋值。例:PointA2=Point(1,2),Point(3,4);如果没有为数组元素指定显式初始值,数组元素便使用缺省值初始化(调用缺省构造函数)。,数组,19,数组元素所属类的构造函数,不声明构造函数,则采用缺省构造函数。各元素对象的初值要求为相同的值时,可以声明具有缺省形参值的构造函数。各元素对象的初值要求为不同的值时,需要声明带形参(无缺省值)的构造函数。当数组中每一个对象被删除时,系统都要调用一次析构函数。,数组,20,例6-3对象数组应用举例,/Point.h#ifndef_POINT_H#define_POINT_HclassPointpublic:Point();Point(intxx,intyy);Point();voidMove(intnewX,intnewY);intGetX()returnx;intGetY()returny;staticvoidshowCount();private:intx,y;#endif,数组,/Point.cpp#include#include“Point.h“usingnamespacestd;Point:Point()x=y=0;coutDefaultConstructorcalled.endl;Point:Point(intx,inty):x(x),y(y)coutConstructorcalled.endl;,Point:Point()coutDestructorcalled.endl;voidPoint:Move(intnewX,intnewY)cout“Movingthepointto(“newX“,”newYendl;x=newX;y=newY;,/6_3.cpp#include“Point.h”#includeusingnamespacestd;intmain()coutEnteringmain.endl;Pointa2;for(inti=0;i2;i+)ai.Move(i+10,i+20);coutExitingmain.ai;coutendl;for(i=0;i10;i+)coutai;coutendl;for(i=0;i10;i+)coutai;coutendl;for(p=a;p(a+10);p+)cout*p;,48,指针数组,数组的每个元素是指针变量,这个数组就是指针数组,指针数组的每个元素都是同一类型的指针声明一维指针数组的语法形式:类型名*数组名下标表达式例:int*p_i3;,指针,声明了一个int型指针数组p_i,数组有3个元素,每个元素都是一个指向int型数据的指针.,49,例6-8利用指针数组输出单位矩阵,#includevoidmain()intline1=1,0,0;/声明数组,矩阵的第一行intline2=0,1,0;/声明数组,矩阵的第二行intline3=0,0,1;/声明数组,矩阵的第三行int*p_line3;/声明整型指针数组p_line0=line1;/初始化指针数组元素p_line1=line2;p_line2=line3;,指针,/输出单位矩阵coutMatrixtest:endl;for(inti=0;i3;i+)/对指针数组元素循环for(intj=0;j3;j+)/对矩阵每一行循环coutp_lineij;coutendl;,输出结果为:Matrixtest:1,0,00,1,00,0,1,51,例6-9二维数组举例,#includevoidmain()intarray223=11,12,13,21,22,23;for(inti=0;i2;i+)cout*(array2+i)endl;for(intj=0;j3;j+)cout*(*(array2+i)+j);coutx;splitfloat(x,指针与函数,54,运行结果:Enterthree(3)floatingpointnumbers4.7IntegerPartis4FractionPartis0.78.913IntegerPartis8FractionPartis0.913-4.7518IntegerPartis-4FractionPartis-0.7518,55,指针型函数,除了void类型的函数之外,函数在调用结束后都会有返回值,指针同样可以作为函数的返回值。当一个函数的返回值是指针类型时,这个函数就是指针型函数。通常非指针型函数调用结束后,可以返回一个变量或对象,但这样每次调用只能返回一个数据,而指针型函数在函数结束时把大量的数据从被调函数返回到主调函数中。,指针与函数,指针型函数的一般定义形式:数据类型*函数名(参数表)函数体,56,例:#includeint*fun();voidmain()int*p;p=fun();while(*p!=-1)cout*p+endl;int*fun()int*h=newint4;h0=1;h1=2;h2=3;h3=-1;returnh;,57,含义:数据指针指向数据存储区,而函数指针指向的是程序代码存储区。实际上函数名就表示函数的代码在内存中的起始地址。,指向函数的指针,指针与函数,注意:函数指针在使用之前也要进行赋值,使指针指向一个已经存在的函数代码的起始地址。一般语法为:函数指针名=函数名;,P212例6-11,58,#includeusingnamepsacestd;voidprintStuff(floatdata_to_ignore)coutThisistheprintstufffunction.“endl;voidprintMessage(floatlist_this_data)coutThedatatobelistedis“list_this_dataendl;voidprintFloat(floatdata_to_print)coutThedatatobeprintedis“data_to_printx;每一个非静态成员函数都有一个this指针,当对象调用成员函数时,该成员函数的this指针便指向这个对象。这样,当不同的对象调用同一个成员函数时,编译器将根据该成员函数的this指针指向的对象确定引用哪个对象的成员函数。成员函数访问类中数据成员的形式为:this-成员变量,对象指针,64,指向对象成员的指针使用前要先声明,再赋值,然后引用。声明形式为:类型说明符类名:*指针名;类型说明符(类名:*指针名)(参数表);对数据成员指针赋值形式为:指针名=Point*pl=,67,对类的静态成员的访问不依赖于对象,因此可用普通指针来指向和访问静态成员,参见P216218页例6-14和例6-15:,指向类的静态成员的指针,68,#includeusingnamespacestd;classPointpublic:Point(intx=0,inty=0):x(x),y(y)count+;Point(Point,例6-14通过指针访问类的静态数据成员,69,private:intx,y;intPoint:count=0;/静态数据成员,初始化intmain()int*ptr=,70,#includeusingnamespacestd;classPointpublic:Point(intx=0,inty=0):x(x),y(y)count+;Point(Point,例6-15通过指针访问类的静态函数成员,71,private:intx,y;staticintcount;intPoint:count=0;/静态数据成员,初始化intmain()void(*funcPtr)()=Point:showCount;Pointa(4,5);coutPointA,a.getX(),a.getY();funcPtr();Pointb(a);coutPointB,b.getX(),b.getY();funcPtr();return0;,72,动态申请内存操作符new,动态内存分配,堆对象:在程序运行过程中申请和释放的存储单元,该过程称为建立(new)和删除(delete)new:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值。若成功,返回指向新分配的内存;否则,抛出异常new数据类型(初始化参数列表);int*point;point=newint(2);区别:point=newint;和point=newint();区别:若类存在默认构造函数,“new”T和“newT()”效果相同;否则,“newT()”会为基本数据类型和指针类型的成员用0赋初值,73,释放内存操作符delete,delete指针名;功能:释放指针P所指向的内存。P必须是new操作的返回值。注意:若被删除的是对象,则其析构函数将被调用;对于用new建立的对象,只能使用delete进行一次删除操作,动态存储分配,74,例6-16动态创建对象,#includeclassPointpublic:Point()X=Y=0;coutDefaultConstructorcalled.n;Point(intxx,intyy)X=xx;Y=yy;coutConstructorcalled.n;Point()coutDestructorcalled.n;intGetX()returnX;intGetY()returnY;voidMove(intnewX,intnewY)x=newX;y=newY;private:intx,y;,动态存储分配,75,intmain()coutStepOne:endl;Point*Ptr1=newPoint;deletePtr1;coutStepTwo:endl;Ptr1=newPoint(1,2);deletePtr1;return0;,运行结果:StepOne:DefaultConstructorcalled.Destructorcalled.StepTwo:Constructorcalled.Destructorcalled.,76,例6-17动态创建对象数组,#includeusingnamespacestd;classPoint/类的声明同例6-16,略;intmain()Point*Ptr=newPoint2;/创建对象数组Ptr0.Move(5,10);/通过指针访问数组元素的成员Ptr1.Move(15,20);/通过指针访问数组元素的成员coutDeleting.count;ArrayOfPointspoints(count);points.element(0).move(5,0);points.element(1).move(15,20);return0;,运行结果:Pleaseenterthecountofpoints:2DefaultConstructorcalled.DefaultConstructorcalled.Deleting.Destructorcalled.Destructorcalled.,81,动态分配数组时应注意:,用new创建多维数组:new类型名T下标表达式1下标表达式2;如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,是一个T类型的数组。例如:char(*fp)3;fp=newchar23;,82,char(*fp)3;,fp,fp+1,83,例6-18动态创建多维数组,#includevoidmain()float(*cp)98;inti,j,k;cp=newfloat898;for(i=0;i8;i+)for(j=0;j9;j+)for(k=0;k9;k+)*(*(*(cp+i)+j)+k)=i*100+j*10+k;/通过指针访问数组元素,动态存储分配,84,for(i=0;i8;i+)for(j=0;j9;j+)for(k=0;k8;k+)/将指针cp作为数组名使用,/通过数组名和下标访问数组元素coutcpijk;coutendl;coutarri;cout“Average=“average(arr)count;ArrayOfPointspointsArray1(count);pointsArray1.element(0).move(5,10);pointsArray1.element(1).move(15,20);,例6-21对象的浅复制,深复制与浅复制,91,ArrayOfPointspointsArray2=pointsArray1;cout“copyofpointsArray1:”endl;cout“point_0ofarray2:“pointsArray2.element(0).getX()“,”pointsArray2.element(0).getY()endl;cout“point_1ofarray2:“pointsArray2.element(1).getX()“,”pointsArray2.element(1).getY()endl;pointsArray1.element(0).move(25,30);pointsArray1.element(1).move(35,40);cout“AfterthemovingofpointsArray1:”endl;cout“point_0ofarray2:“pointsArray2.element(0).getX()“,”pointsArray2.element(0).getY()endl;cout“point_1ofarray2:“pointsArray2.element(1).getX()“,”pointsArray2.element(1).getY()endl;ruturn0;,例6-21对象的浅复制(续),深复制与浅复制,根据P227页的运行结果,发现当移动pointsArray1中的点后,pointsArray2中的点也被移动。这是与预期不相符的,原因是只是浅复制(参见P222页ArrayPoints类的定义和P228页图6-11)。,92,#include#includeusingnamespacestd;classPoint/类的声明同例6-16,略;classArrayOfPointspublic:ArrayOfPoints(constArrayOfPointsintmain()/同例6-21,例6-22对象的深复制,深复制与浅复制,根据P229页的运行结果,发现当移动pointsArray1中的点不再影响pointsArray2

温馨提示

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

评论

0/150

提交评论