《6章 数组指针与字符串.ppt》由会员分享,可在线阅读,更多相关《6章 数组指针与字符串.ppt(47页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第六章第六章 数组指针与字符串数组指针与字符串l 数组数组l 指针指针l动态内存分配动态内存分配l字符串字符串数组的概念数组的概念数组数组是具有一定是具有一定顺序关系顺序关系的若干的若干相同类型变量相同类型变量的集合体的集合体,组成数组的变量称为该数组的,组成数组的变量称为该数组的元素元素。每个元素有每个元素有n个下标的数组称为个下标的数组称为n维数组。维数组。数组属于自定义数据类型,使用之前首先要进数组属于自定义数据类型,使用之前首先要进行类型声明。行类型声明。说明说明:1.数组元素在内存中顺次存放,它们的地址是连续的。2.数组名字是数组首元素的内存地址。3.数组名是一个常量,不能被赋值。数
2、组数组 在声明数组时对数组元素赋以初值。在声明数组时对数组元素赋以初值。例如:例如:intint a10=0,1,2,3,4,5,6,7,8,9;a10=0,1,2,3,4,5,6,7,8,9;l可以只给一部分元素赋初值。可以只给一部分元素赋初值。例如:例如:intint a10=0,1,2,3,4;a10=0,1,2,3,4;l在对全部数组元素赋初值时,可以不指定数组在对全部数组元素赋初值时,可以不指定数组长度。长度。例如:例如:intint a=1,2,3,4,5 a=1,2,3,4,5一维数组声明形式:一维数组声明形式:数组类型数组类型 标识符标识符常量表达式常量表达式二维数组的声明及使
3、用二维数组的声明及使用数据类型数据类型 标识符标识符常量表达式常量表达式1常量表达式常量表达式2;例例:int a53;表表示示a为为整整型型二二维维数数组组,其其中中第第一一维维有有5个个下下标标(04),第第二二维维有有3个个下下标标(02),数数组组的的元元素素个个数数为为15,可可以以用用于于存存放放5行行3列列的的整整型型数数据据表表格。格。存储顺序按行存放,上例中数组a的存储顺序为:l二维数组的声明二维数组的声明l类型说明符类型说明符 数组名数组名常量表达式常量表达式常量表达式常量表达式l例如:例如:float a34;a00 a01 a02 a03 a10 a11 a12 a13
4、 a20 a21 a22 a23a0a00 a01 a02 a03a1a10 a11 a12 a13a2a20 a21 a22 a23a可以理解为:使用例如:b12=a23/2下标不要越界下标不要越界二维数组的声明及使用二维数组的声明及使用二维数组的初始化二维数组的初始化l将所有数据写在一个将所有数据写在一个内,按顺序赋值内,按顺序赋值例如:例如:intint a34=1,2,3,4,5,6,7,8,9,10,11,12;a34=1,2,3,4,5,6,7,8,9,10,11,12;l分行给二维数组赋初值分行给二维数组赋初值例如:例如:intint a34 a34 =1,2,3,4,5,6,7
5、,8,9,10,11,12;=1,2,3,4,5,6,7,8,9,10,11,12;l可以对部分元素赋初值可以对部分元素赋初值例如:例如:intint a34=1,0,6,0,0,11;a34=1,0,6,0,0,11;2.数组作为函数参数数组作为函数参数l数组元素作实参,与单个变量一样。数组元素作实参,与单个变量一样。l数组名作参数,形、实参数都应是数数组名作参数,形、实参数都应是数组名,类型要一样,传送的是数组首组名,类型要一样,传送的是数组首地址。对形参数组的改变会直接影响地址。对形参数组的改变会直接影响到实参数组。到实参数组。数组元素和数组名都可作为函数参数来进行数据传递和共享。数组元
6、素和数组名都可作为函数参数来进行数据传递和共享。#includevoid RowSum(int A 4,int nrow)/算A每行元素之和,nrow为行数 for(int i=0;inrow;i+)for(int j=1;j4;j+)Ai0+=Aij;void main()int Table34=1,2,3,4,2,3,4,5,3,4,5,6;for(int i=0;i3;i+)for(int j=0;j4;j+)coutTableij“;coutendl;RowSum(Table,3);/数组名实参,传递首地址 for(i=0;i3;i+)couti“:”Tablei0endl;1 2 3
7、 42 3 4 53 4 5 60:101:142:18例例 计算数组每行元素之和计算数组每行元素之和3.对象数组对象数组声明:下标表达式.访问:数组名下标.公有成员名例如:TDate dates7;TDate date35;对象数组初始化对象数组初始化l数组中每一个元素对象被创建时,系统都会调用类数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象。构造函数初始化该对象。通过初始化列表赋值通过初始化列表赋值。例:例:point a2=Point(1,2),Point(3,4);point a2=Point(1,2),Point(3,4);如果没有为数组元素指定初始值,数组元素便使
8、用如果没有为数组元素指定初始值,数组元素便使用默认值初始化(调用默认构造函数)默认值初始化(调用默认构造函数)。例:例:Point a2=Point(1,2);Point a2=Point(1,2);对象数组赋赋值对象数组赋赋值a0=Point(1,2);a1=Point(3,4);l 当数组中每一个元素对象被删除时,系统都要调当数组中每一个元素对象被删除时,系统都要调用一次析构函数来完成扫尾工作。用一次析构函数来完成扫尾工作。对象数组例对象数组例/Point.h#ifndef _POINT_H#define _POINT_Hclass Pointpublic:Point();Point(in
9、t x,int y);/构造函数重载Point();void move(int newX,int newY);int GetX()const return x;int GetY()const return y;static void showCount()coutX:x“Y:yendl;private:int x,y;#endif对象数组例对象数组例#includePoint.hPoint:Point()x=0;y=0;coutDefault Constructor called.endl;Point:Point(int x,int y):x(x),y(y)coutConstructor ca
10、lled.endl;Point:Point()coutDestructor called.endl;void Point:move(int newX,int newY)coutMoving point to(newX,newY)“endl x=newX;y=newY;对象数组例对象数组例#include Point.h#include using namespace std;void main()coutEntering main.endl;Point a2;/调用默认构造函数置空for(int i=0;i2;i+)ai.move(i+10,i+20);coutExiting main.end
11、l;Entering main.Default Constructor called.Default Constructor called.Moving point to(10,20)Moving point to(11,21)Exiting main.Destructor called.Destructor called.指针概念指针概念内存空间访问方式:一是通过变量名,二是通过地址指针变量:存放内存单元地址的变量指针声明:数据类型 *标识符声明 例:int i;int*ptr=&i;指向整型变量的指针指针:内存地址,用于 间接访问内存单元指针变量:用于存放地址的变量20003ptr*ptr
12、i2000引用 例1:i=3;例2:*ptr=3;内存用户数据区变量 i变量 j变量 ptr362000200020043010指针变量的初始化指针变量的初始化l语法形式l 存储类型 数据类型*指针名初始地址;l例:int*pa=&a;l注意事项l用变量地址作为初值时,该变量必须在指针初始化之前已说明过,且变量类型应与指针类型一致。l可以用一个已赋初值的指针去初始化另一 个指针变量。运算符运算符*和和&:lint c;lint*p=&c;/声明p是一个int指针l cout*p;/输出指针p所指向的内容l int&rf;/声明一个int型的引用l int a,*pa;l pa=&a;/取a的地
13、址送到pal float b10;l float*ptr=b;/声明并初始化float指针指针变量的赋值运算指针变量的赋值运算指针名=地址l“地址”中存放的数据类型与指针类型必须相符。l向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。l指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针本身的数据值都是unsigned long int型。l允许声明指向 void 类型的指针。该指针可以被赋予任何类型对象的地址。例:void*pv;例例 指针的定义、赋值与使用指针的定义、赋值与使用#includeusing namespace std;
14、void main()int*ptr;/声明int型指针ptr int i;/声明int型数i ptr=&i;/取i的地址赋给ptr i=10;/int型数赋初值 couti=iendl;/输出int型数的值 cout“*ptr=*ptrendl;/输出int型指针所指地址的内容指向常量的指针:例:char a=”abc”;char b=cde;const char*name1=a;name1=b;/正确,name1本身值可变 *name1=1;/错,不能通过name1改变所指对象常量指针:例:char a=”abc”;char b=cde;char*const name2=a;*name2=
15、1;/正确,name2指向的值可变 name2=b;/错,name2是常量指针,本身值不能变void类型指针:例:void a;/错,不能声明void型变量 void*pv;/可以声明void型指针 int*pt,i;pv=&i;pt=(int*)pv;/强制类型转换指针变量的算术运算指针变量的算术运算l 指针与整数的加减运算指针p加上或减去n,其意义是指针当前指向位置的后方或前方第n个数据的地址。这种运算的结果值取决于指针指向的数据类型。l 指针加一,减一运算指向下一个或前一个数据。指针变量的关系运算指针变量的关系运算l关系运算l指向相同类型数据的指针之间可以进行各种关系运算。l指向不同数据
16、类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。l指针可以和零之间进行等于或不等于的关系运算。例如:p=0或p!=0l赋值运算l向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。用指针处理数组元素用指针处理数组元素例:int array5;int*p;p=array;则:array,&array0,p相同,均指向数组首地址,array为常量指针,p为指针arrayi *(array+i)*(p+i)pi 表示第i个数组元素例 使用数组名指针运算使用数组名指针运算void main()int a10;int i;for(i=0;iai;couten
17、dl;for(i=0;i10;i+)coutai;*(a+i);使用指针变量使用指针变量void main()int a10;int*p,i;for(i=0;iai;coutendl;for(p=a;p(a+10);p+)cout*p;指针数组指针数组一维指针数组格式:类型名 *数组名下标表达式;例:int*pa3;TDate*pb4;/由pb0,pb1,pb2,pb3四个指针组成说明:1)后条语句声明了一个TDate类的指针数组,有 4个元素,每个元素都是指向TDate型数据的 指针;2)指针数组要先赋值,再引用。例例 指针数组指针数组#include void main()int line
18、1=1,0,0;line2=0,1,0;line3=0,0,1;int*pLine3=line1,line2,line3;coutMatrix test:endl;for(int i=0;i3;i+)for(int j=0;j3;j+)coutpLineij;coutendl;输出:1 0 00 1 00 0 1例例 二维数组二维数组#include using namespace std;void main()int array223=11,12,13,21,22,23;for(int i=0;i2;i+)for(int j=0;j3;j+)cout*(*(array2+i)+j);/或者
19、coutarray2ij;coutendl;例例 指针数组指针数组#include class Apublic:A(int i=0,int j=0)a=i;b=j;void Print()couta,bendl;private:int a,b;void main()A a1(7,8),a2,a3(5,7);A*b3=&a3,&a2,&a1;/指针数组的定义及赋值 for(int i=0;iPrint();输出:5,70,07,8指向数组的指针指向数组的指针一维格式:类型名(*指针名)下标表达式;例:int a4=1,2,3,4;int (*pa)3;pa=&a;TDate (*pb)4;说明:
20、后条语句声明了一个指向类TDate数组的指针变量pb,有4个元素,每个元素为TDate型,pb为行指针,不能指向一维数组中第j个元素。例例 指向数组的指针指向数组的指针#includevoid main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int(*p)4,i,j;p=a;coutij;coutai,j=*(*(p+i)+j);结果:i,j=1 3 a1,3=15指针作为函数参数指针作为函数参数指针为形参时的作用:1)使实参与形参指针指向共同的内存空间,达到数据双向传递的目的;C+中由引用实现该目的;2)减少函数调用时数据传递的开销;3)通过指向函数
21、的指针传递函数代码的首地址。例 指针作为函数参数例 读入三个浮点数,将整数、小数部分分别输出#includevoid splitfloat(float x,int*intpart,float*fracpart)*intpart=int(x);*fracpart=x-*intpart;void main()int i,n;float x,f;coutEnter 3 float point numbers:endl;for(i=0;ix;splitfloat(x,&n,&f);coutInteger Part=n Fraction Part=fendl;结果:Enter 3 float point
22、 numbers:4.7Integer Part=4 Fraction Part=0.78.913Integer Part=8 Fraction Part=0.913-4.7518Integer Part=-4 Fraction Part=-0.7518例例:输出数组元素的内容和地址输出数组元素的内容和地址#include void Array_Ptr(long*P,int n)int i;coutIn func,address of array is unsigned long(P)endl;coutAccessing array using pointers endl;for(i=0;i
23、n;i+)cout Address for index i is unsigned long(P+i);cout Value is*(P+i)endl;void main()long list5=50,60,70,80,90;coutIn main,address of array is unsigned long(list)endl;coutendl;Array_Ptr(list,5);结果:In main,address of array is 1245036In func,address of array is 1245036Accessing array using pointers
24、Address for index 0 is 1245036 Value is 50 Address for index 1 is 1245040 Value is 60 Address for index 2 is 1245044 Value is 70 Address for index 3 is 1245048 Value is 80 Address for index 4 is 1245052 Value is 90Press any key to continue指针型函数和指向函数的指针指针型函数和指向函数的指针1)指针型函数 定义:数据类型*函数名(形参表)函数体 说明:当一个函
25、数的返回值是指针类型,该函数就是指针型函数 用途:在函数结束时返回大量数据到主调函数中.2)指向函数的指针 定义:数据类型(*函数指针名)(形参表)赋值:函数指针名=函数名;说明:函数指针是用于存放函数代码首地址的变量.用途:用指向函数的指针来调用函数(同函数名调用函数一样)函数名表示函数代码在内存中的起始地址。例 函数指针#includevoid printStuff(float)coutThis is the print stuff function.n;void printMessage(float data)coutThe data to be listed is data成员名;/利
26、用对象指针访问对象成员2)this指针 该指针是隐含于每一个类的成员函数中的特殊指针;用于指向正在被成员函数操作的对象;this-x指明成员函数当前所操作数据所属的对象;*this标识正在调用该成员函数的对象;指向类的非静态成员的指针指向类的非静态成员的指针(1)声明指向数据成员的指针:类型名 类名:*指针名;int A:*p1;对数据成员指针赋值:指针名=&类名:数据成员名;p1=&A:x;用指针访问数据成员:对象名.*类成员指针名;a.*p1;(等价于a.x;)或 对象指针名-*类成员指针名;p2-*p1;A a,*p2;(2)声明指向成员函数的指针:类型名(类名:*指针名)(参数表);i
27、nt(A:*p3)();对成员函数指针赋值:指针名=&类名:函数成员名;p3=&A:getX;用指针访问成员函数:(对象名.*类成员指针名)(参数表);(a.*p3)();或 (对象指针名-*类成员指针名)(参数表);(p2-*p3)();例例 访问对象的公有成员函数的不同方式访问对象的公有成员函数的不同方式class Point public:Point(int a,int b)x=a;y=b;int GetX()return x;private:int x,y;void main()Point a(4,5),*p1=&a;int(Point:*funcPtr()=&Point:getX;/
28、声明成员函数指针并初始化 cout(a.*funcPtr)()endl;/成员函数指针访问成员函数 cout*funcPtr)()endl;/成员函数指针和对象指针 couta.GetX()endl;/使用对象名访问成员函数 coutGetX()endl;/使用对象指针访问成员函数指向类的静态成员的指针指向类的静态成员的指针例 类的静态成员可以用普通的指针来指向和访问 class Point public:static int countP;/静态数据成员 static void GetC()coutcountPendl;/静态成员函数 ;int Point:countP=10;void ma
29、in()int*count=&Point:countP;/int型指针指向类的静态成员 void(*gc)()=Point:GetC;/void型函数指针指向类的静态成员函数 cout*countendl;/直接用指针访问静态数据成员 gc();/直接用指针访问静态成员函数 动态内存分配动态内存分配1.堆对象 在程序运行过程中根据需要可以随时建立或删除的对象;2.堆对象运算符:new、delete3.new运算符 动态内存分配或称动态创建堆对象。格式:new 类型名(初始值列表)例:int*pi;pi=new int(2);new运算符返回一个与new所分配对象类型相匹配的指针,如果new运算
30、符不能分配到所需要的内存,将返回0,这时为空指针;动态内存分配动态内存分配 用new运算符创建数组的语法形式:new 类型名下标表达式;/一维数组例:A*ptr;/建立对象指针ptr=new A5;/动态分配用于存放类A类型数据的空间,A有5个数组元素,将首地址赋给指针ptr.注意:1)使用new创建对象数组或一般数组时,不能为该数组指定初始值,其初始值为缺省值;2)使用new创建对象数组时,类中必须说明缺省构造函数;动态内存分配动态内存分配 delete运算符 作用:删除用new创建的对象或一般类型的指针.格式:delete 指针名 例:A*ptr;ptr=new A(5,6);delete
31、 ptr;删除对象数组格式:delete 指针名 例:A*ptr;ptr=new A5;delete ptr;例例 动态内存分配动态内存分配#include class Pointpublic:Point():x(0),y(0)coutDefault Constructor called.endl;Point(int x,int y):x(x),y(y)coutConstructor called.endl;Point()coutDestructor called.endl;void move(int newX,int newY)x=newX;y=newY;private:int x,y;结果
32、:结果:Step One:Default Constructor called.Destructor called.Step Two:Constructor called.Destructor called.Step Three:Default Constructor called.Default Constructor called.Destructor called.Destructor called./用new创建的动态对象,只能用delete释放./可以用动态数组类解决动态数组的自动建立和删除void main()coutStep One:endl;Point*ptr1=new Poi
33、nt;/动态创建对象,无初值,调用默认构造函数 delete ptr1;/删除对象,自动调用析构函数 coutStep Two:endl;ptr1=new Point(1,2);/动态创建对象并给初值,调用有形参构造函数 delete ptr1;/删除对象,自动调用析构函数 coutStep Three:endl;ptr1=new Point2;/动态创建对象数组,调用默认构造函数 ptr10.move(5,10);/通过指针访问数组元素的成员 ptr11.move(15,20);delete ptr1;例例 动态内存分配动态内存分配动态数组类动态数组类 将数组的建立和删除过程封装起来,形成一
34、个动态数组类例 由动态数组类完成Point类动态数组的创建和释放class Point;class ArrayOfPoint public:ArrayOfPoint(int size):size(size)points=new Pointsize;ArrayOfPoint()cout“Deleting”endl;delete points;Point&element(int n)/获取下标为n的数组元素 return pointsn;private:Point*points;/指向动态数组首地址 int size;/数组大小;void main()int number(4);ArrayOfPo
35、int points(number);points.element(0).move(5,10);字符串字符串C+处理字符串的两种方法:1)字符型数组字符型数组 例:char str8=p,r,o,g,r,a,m,0;char str8=“program”;char str=“program”;2)string类类 串类封装了串的属性,并提供了一系列允许访问这些属性的服务。可以直接使用字符串常量对string对象初始化。例:string str=“Hello world!”;例例 string类应用类应用#include /使用标准C+库#include using namespace std;
36、/使用名空间 inline void test(const char*title,bool value)couttitle“returns”(value?”true:“false)endl;void main()string S1=“DEF”;/定义对象 cout“S1 is”S1endl;string S2;coutS2;coutlength of S2:S2.length()endl;test(“S1=”ABC”,S1=“ABC”);test(“DEF”=S1”,“DEF”=S1);S2+=S1;/连接运算符的测试 cout“S2=S2+S1:S2endl;coutlength of S2
37、:S2.length()endl;结果:S1 is DEFPlease enter S2:123length of S2:3S1=“ABC”returns false“DEF”=S1 returns trueS2=S2+S1:123DEFlength of S2:6本章小结本章小结 组成数组的变量为该数组的元素,同一数组的各元素具有相同的数据类型。对象数组:数组类型是类,则数组的每一个元素都是该类的一个对象,该数组为对象数组。指针也是一种数据类型,具有指针类型的变量为指针变量。指针可指向对象或指向函数。指针经声明、赋值后才能引用。动态分配和释放内存的运算符new和delete。字符数组和string类。