《数组和指针》PPT课件.ppt
1,第四部分 数组,一、数组概述,数组是具有相同数据类型的元素序列。在内存中,它占据一组连续的内存空间。数组的每一项都是一个变量,称为元素。,实际上,数组是一组相关的内存位置,它们具有相同的名字和类型。为了引用数组中的特定位置或元素,需指定数组名和数组中特定元素的位置编号。,当若干数据具有相同的数据类型并且互相有一定关系时,把它们组织成数组非常有效。,2,数组分为一维数组、二维数组和三维及以上的数组,通常把二维数组称为矩阵,三维及以上的数组成为多维数组。,和其他变量一样,在使用数组之前需要对数组进行定义。,3,形式:,类型名,数组名,常量表达式,注:1)类型名:数组中的元素的类型(如 int char 等),2)数组名的命名规则同前面的变量的命名规则。,3)常量表达式:表示数组中数组元素的个数,即数组的 长度。,不允许为变量,既不允许对数组做动态定义。数组的大小一旦定义即已固定。,例如:定义一个包含3个元素的整型数组a:,int,例如:定义一个包含20个元素的字符型数组c:,char c20;,3;,a,例:int a3,b5,c10;,一个定义中,可以同时说明多个相同类型的数组。,例:char c,s30;,普通变量和数组可以出现在同一个定义中。,二、一维数组的定义形式:,4,注:4)数组名:是一个地址常量,代表整个数组的首地址。,例如:int a2;,3000H,3001H,3002H,3003H,3004H,3005H,3006H,数组a所占的内存,couta;,输出结果为:3000,a的值,5,数组元素的引用:把数组中的每个元素当成普通的变量来使用,就是所谓的“数组元素的引用”。,三、数组元素的引用,对数组中某一个元素进行访问是通过数组名加下标实现的,也就是说,在数组名字后面的方括号 内加入特定元素的位置编号,就可以应用这些元素中的任何一个了。,6,下标的范围:下标,形式:数组名称下标表达式,表达式的值必须为整数,例如:int a3;,该数组中包含3个元素,分别为:,2)数组元素默认的下标值从0开始。,a0、a1、a2,注:1)下标表达式必须为整型常量或者整型的表达式。,0,长度-1,3)数组不能整体引用。如 不能用a表示a0到a2的3个元素。,7,void main()int a10;,例题:定义一个具有10个元素的整型数组a,给数组元素赋值,并分别将其按正序、倒序输出。,/给10个元素分别赋值为0 1 2 3 49,a0=0;,a1=1;,a2=2;,a9=9;,i,i,ai=i;,for(i=0;i10;i+),ai=i;,/输出数组的10个元素,couta0;,1,2,9,i,for(i=0;i10;i+),coutai;,/倒序输出数组的10个元素,for(i=9;i=0;i-),coutai;,8,答:普通变量,例题1:输入10名同学的成绩,统计其中的最高分、最低分和平均分。,#include using namespace std;void main(),如何存储?,答:数组,如果成绩为浮点型数据,该数组如何定义?,float score10;,如果分别用max,min,aver表示3个成绩,则该如何定义?,float max,min,aver;,9,如何求最高分,将其保存在max中?,max=score0;,if(score1max),max=score1;,if(score2max),max=score2;,if(score3max),max=score3;,if(score9max),max=score9;,if(scorei max),max=scorei;,for(i=1;i10;i+),min,min,min,min,低,10,如何求总分,将其保存在sum中?,sum=score0;,sum=sum+score1;,sum=sum+score2;,sum=sum+score3;,sum=sum+score9;,for(i=1;i10;i+),sum=sum+scorei;,11,max=score0;for(i=1;imax)max=scorei;,void main()float score10;float max,min,aver;,如何输入10个成绩?,for(i=0;i10;i+),cin,scorei;,int i;,如何求最高分,将其保存在max中?,如何求最低分,将其保存在min中?,min=score0;for(i=1;i10;i+)if(scoreimin)min=scorei;,如何求平均分,并保存在aver中?,sum;,sum=score0;for(i=1;i10;i+)sum=sum+scorei;,aver=sum/10;,cout“最高分:”max“,最低分:”min“,平均分:”aver;,如何将结果输出?,12,注意:在求最大值、最小值、平均值时,循环次数及循环变量的取值相同,所以可以简化程序为:,for(i=1;i10;i+),max=score0;,if(scoreimax)max=scorei;,min=score0;,if(scoreimin)min=scorei;,sum=score0;,sum=sum+scorei;,aver=sum/10;,13,14,四、数组的初始化,可以在定义数组的同时给数组元素赋值。,1)例:int a3=1,2,3;,注:初值列表用大括号括起来,各数值间用逗号隔开。从第一个元素开始依次赋值。,2)、直接用字符串常量给字符赋值,例如:char s4=“abc”;,注:此时可以把大括号省略。即:char s4=“abc”;注:也可以省略长度。即char s=“abc”;,在C+中,更多的使用string类来表示字符串对象。该部分内容在第二章中详细介绍。,15,课程回顾,1、定义一个具有5个元素的浮点型的数组x,应使用的语句为:。,float x5;,2、若有定义int a3;则:数组a中共有 个元素。引用方式分别为:、。,a0,a1,a2,3,16,sum=0;,i3,sum=sum+ai;,17,4.下列程序中有一处错误,请指出并给出修改意见(2009.1)#include usingnamespacestd;intmain()constintnum=20;intscoresnum;for(inti=1;i=num;i+)scoresi=i;return0;,下标越界。改为,18,五、二维数组的定义和引用,二维数组:每个元素带有两个下标,在逻辑上可以把二维数组看成是一个具有若干行和列的表格或者矩阵。,1、定义:,类型名称,数组名称,常量表达式1,常量表达式2,二维数组的行数。,二维数组的列数。,例如:定义一个具有2行3列的整型数组a,int a23;,分析:1)数组名称:a,2)共有2 x 3=6个元素,注意:不能写成 int a2,3;,19,2、引用,格式:,数组名称行下标列下标,例如前例中的a11等,注:1)下标为整型表达式,而且不能越界。,2)两个下标分别放在方括号中。,例如:a1,2 是错误的,20,3)逻辑结构如下:,第1行,第2行,第1列,第2列,第3列,a00,a01,a02,a10,a11,a12,int a23;,注:每个元素有两个下标:第1个方括号中的下标代表行号,称为行下标 第2个方括号中的下标代表列号,称为列下标,4)存储方式:,按行存放,即在内存中先存放第1行的元素,再存放第二行的元素。,21,/按行输出各个元素赋值,a00,a00,例题:程序运行时给数组元素赋值,并输出各数组元素。,void main()int a23,i,j;,/给各个元素赋值,cin,只给a00元素赋值:,只给第1行元素赋值:,for(j=0;j3;j+),j,for(j=0;ja0j;,只输出a00元素:,cout,只输出第0行元素:,for(j=0;j3;j+),j,for(i=0;i2;i+)for(j=0;j3;j+)cout aij);,coutendl;,i,for(i=0;i2;i+),22,六 字符数组,字符数组:用来存放字符数据的数组。字符数组中的 一个元素存放一个字符。,一、定义:,char 数组名长度,例如:char c5=c,h,i,n,a;,在内存中占5个字节,a0,a1,a2,a3,a4,c,h,i,n,a,?这种定义方式正误?,int c5=c,h,i,n,a;,23,2、直接用字符串常量赋值,例如:char s=“abc”;,也可以省略大括号:char s=“abc”;,1)char s=A,B,C;,2)char s=A,B,C,0;,说明:,3)char s10=A,B,C,0;,4)char s=“abc”;,注意:如果一个字符数组中包含一个以上0,则遇第一个0时输出就结束。,24,课程回顾,1.下面关于数组的初始化正确的是()(2009.10)A.charstr=a,b,c;B.charstr2=a,b,c;C.charstr12=a,b,e,d;D.charstr=a,b,c;,A,2.数组的元素默认的下标值从 开始。,下标的范围:下标。,0,0,长度-1,25,第五部分 指针,变量和数据在内存中存放都要占用一定数量的内存空间(单位为字节)。计算机内存中的每个字节都有一个编号,该编号称为内存地址即指针。,变量的地址:每个变量的地址是指该变量所占存储单元 的第一个字节的地址。,指针:由于通过地址能找到所需的变量单元,可以说,地址“指向”该内存单元。所以,c+语言中又将 地址形象化的称作“指针”。即某个变量的指针就是该变量的地址。,一、指针和地址的概念,26,指针变量:C+中有一种特殊的变量可以存放普通变量的地址,称为指针变量。而要取得一个普通变量a的地址可使用&运算符(取地址运算符)。例如:若有变量a,则:&a即表示变量a的地址。即:专门存放指针(地址)的变量称为指针变量。,假设p是一个指针变量,a是一个普通变量,则p中可存放a变量的地址,操作语句为:,p=,经过此操作后,我们说p指向了变量a。,27,二、变量的指针和指向变量的指针变量,由上节可知,变量的指针就是变量的地址。存放变量地址的变量就是指针变量,用来指向另一个变量。,例如:int i=3;,3,变量p的空间,2000H,此处p即为指针变量,变量i的空间,28,在这里也可以说变量p指向变量i。,29,形式:,变量名,*,类型名称,注:1)*说明符,用来说明该变量为指针变量,2)类型名称:基类型,用来指定指针变量所指向的变量的类型。,3)指针变量的值是其所指向的变量的地址,而不能是普通的数据。,例如:若有定义 int*p,x;,若使p指向x,则可用:,p=,p=3;(错误),三、指针变量的定义和初始化,1、定义,30,练习:(1)定义一个指向单精度型数据的指针变量q(2)定义一个指向字符型数据的指针变量p,float*q;,char*p;,3)一个指针变量只能指向同一类型的变量。,例如:若有定义 int x;float y;int*p;,p=,p=,cannot convert from float*to int*,31,2、指针变量的初始化,指针变量在使用之前必须先定义,而且必须赋值后才能使用,未经赋值的指针变量不能使用。,(1)定义的同时赋值如:int a;int*pa=&a;,(2)先定义再赋值如:int a,b;int*p;p=&a;p=&b;,注:指针变量的赋值只能赋予地址,而不允许把一个数值赋给指针变量。,如:int*p;P=1000;(错误),32,例 int i;int*p=,变量必须已说明过类型应一致,例 int i;int*p=,用已初始化的指针变量作初值,33,四、指针变量的使用,注:*指针运算符或者间接访问运算符,指针变量经过定义及初始化后,就可以使用指针变量来引用普通变量的值了。形式:*指针变量,若有:int a;int*p=,一旦p指向了a,则*p和a就是等价的了,34,例题1:main()int*p;int a=10;p=,输出结果为:,1212,35,特别注意:此处的*号和指针变量定义时的*号含义是不一样的,此处*号表示取所指向变量的内容。,请牢记指针变量中只能存放地址(指针),不要将一个整型量(或任何其他非地址类型的数据)赋给一个指针变量。,当定义了指针变量p而p未指向任何变量时(即未给p赋值时),使用*p是不合理的。,36,例题2:,pa=,pb=,main()int a,b,*pa,*pb;,/用pa指向变量a,/用pb指向变量b,cin*pa*pb;,cout*pa“,”*pbendl;,cinab;,couta“,”bendl;,/从键盘输入数据给a,b赋值,/输出a,b的值,37,指针小节总结,1、指针就是地址,2、指针变量只能存放地址数据,3、指针变量的类型必须与指向的变量的类型一致。,4、*号出现位置不同表示的含义不同,若出现在定义中,则表示定义的是指针变量,若定义后,则*p和指向的变量x的值含义相同,38,课程回顾,1、若想定义一变量p存放整型变量x的地址,应如何定义:,int*p=,2、通过 或 语句可以为x赋值为5。,x=5;,*p=5;,3、p=100;判断正误?,4、若有int*p;float x;int y;判断下面语句正误?,p=,39,五、指针与数组,在C+中,数组和指针密切相关,几乎可以相互使用。,数组名可以认为是常量指针,它指向数组第一个元素的内存地址。指针可以用于完成任何涉及数组下标的操作。,例如,若有定义:int a10;,则:a 与&a0的关系?,数值相等,再有定义:int*p=a;,则:p、a 与&a0的关系?,数值相等,则:*p、*a 与a0的关系?,相等,1、指针与数组的关系,40,根据前面所讲述内容:数组名:是一个地址常量,代表整个数组的首地址。,例如:int a2;,3000H,3001H,3002H,3003H,3004H,3005H,3006H,数组a所占的内存,couta;,输出结果为:3000,a的值,a+1的值是多少?,3004,注:对地址进行增减运算,移动的最小单位是一个存储单元而不一定是一个字节,具体由数组元素的类型决定。,41,所以若有定义:int a10;,则:a 与&a0的关系?,数值相等,a+1 与&a1的关系?,数值相等,a+i 与&ai的关系?,数值相等,再有定义:int*p=a;,则:p+i、a+i 与&ai 的关系?,数值相等,*(p+i)、*(a+i)与 ai 的关系?,数值相等,数组中任意元素的地址,数组中任意元素的引用,42,所以若有定义:int a10,*p=a;请考虑以下问题:,a=a+1;是否正确,为什么?,p=p+1;是否正确,为什么?,43,2、用指针引用数组元素,44,或者*(a+i)或者*(p+i),#include using namespace std;void main()int a5=1,2,3,4,5,i;for(i=0;i5;i+)cout ai“;,例题:以下程序是输出数组中的所有元素的值。,int*p=a;,/定义一个指针变量p并使其指向首元素,*(p+i),cout*p“;p=p+1;,p+;,cout*p“;p+;,45,综上:虽然数组名和指针在引用数组元素和取得它们的地址方面可以互换,但两者有一个重要的不同点:数组名是在定义时就已经分配好了内存空间的,因此,数组名是一个地址常量,在程序中不能将数组名作为变量为其赋值,而指针变量作为变量则可多次赋值。,46,1、new运算符 在使用指针时,如果不使用对象地址初始化指针,可以使用new运算符给它分配地址。(课本第10页),(1)使用格式1:开辟单变量地址空间对于只存储一个基本类型数据的指针,申请的方式如下:new 类型名;,五、动态分配内存,功能:返回指定类型的一个指针,如果分配失败(如没有足够的内存空间),则返回0。,47,例如:int*p;p=new int;系统自动根据int类型的空间大小开辟一个内存单元,并将地址放在指针P中。,p,申请的空间,可以通过指针P来使用这个内存单元。例如:给该内存赋值3。,*p=3;,3,48,(2)new使用格式2:作用同上,但同时给内存空间赋值。,可以在申请空间的同时对内存单元初始化。格式:new 类型名(初始值),例如:int*p=new int(3);,3,49,(3)new使用格式3:开辟数组空间,可以申请多个指定类型的连续的存储空间。格式:new 类型名size,功能:申请可以存储size个指定类型的空间。,例如:int*p=new int3;即向系统申请了3个int类型的连续空间。,p,申请的空间,请思考:p+1、p+2的值?,p+1,p+2,此时,p就和一个一维数组很类此。,50,例题:以下程序是new的演示实例。,#include using namespace std;void main()double*p;p=;for(int i=0;i5;i+),new double5;,/申请5个double类型的存储空间,/输入数据存入5个单元,/输出5个单元的数据,cin,*(p+i);,for(i=0;i5;i+),cout*(p+i)“;,51,delete用法:(1)int*a=new int;delete a;/释放单个int的空间(2)int*a=new int5;delete a;/释放int数组空间,2、delete运算符,用户使用new运算符动态申请的空间当不需要的时候必须用delete运算符来释放。,52,#include using namespace std;void main()double*p;p=new double5;for(int i=0;i*(p+i);for(i=0;i5;i+)cout*(p+i);,delete p;,综上,下列程序应增加什么语句?,53,练习:完成下面程序,使其输出l0,并在退出运行时正确释放分配给指针的存储空间 2009.1#include using namespace std;void main()int*a,*p;a=new int(10);p=_;cout*pendl;_,a,delete a;,或者delete p;,54,六、对指针使用const限定符,const int*p;,int*const p;,const int*const p;,const 也可以用来修饰指针,有以下几种形式:,用const来修饰普通变量表示的是常值变量,其值不可变。例如:const int x=100;,55,1、指向常量的指针,形式:const Type*指针变量名,例如:const int*p;,表示*p是一个常量,不能通过*p的形式改变p所指向的单元内容。,例如:int x=7;const int*p=&x;,则不能通过*p的形式来改变x单元的值。,例如:*p=100;,错误,cin*p;,错误,但仍可以通过x来改变其单元的内容。,例如:x=100;,正确,cinx;,正确,56,p=,#include using namespace std;void main()int x=10;const int*p=,*p=50;coutx,*pendl;,value specifies const object,x=30;coutx,*pendl;,const int y=100;,couty“,”*pendl;,y=300;couty,*pendl;,57,2、常量指针,形式:Type*const 指针变量名,例如:int x;int*const p=&x;,表示p是一个常量指针,在程序中不能再改变P的指向。,注:在定义常量指针的同时需要赋初值。,58,p=,#include using namespace std;void main()int x=10;int*const p=,*p=50;coutx,*pendl;,x=30;coutx,*pendl;,const int y=100;,couty“,”*pendl;,59,3、指向常量的指针常量,形式:const Type*const 指针变量名,例如:int x;const int*const p=&x;,表示p的值不可改变,即不能改变p的指向。而且不能使用*p的形式修改p所指的空间内容。,60,p=,#include using namespace std;void main()int x=10;const int*const p=,*p=50;coutx,*pendl;,int y=100;,couty“,”*pendl;,61,const int*p;,int*const p;,const int*const p;,还有一种区别方法:沿着*号划一条线,如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。,62,作业:课本第27页改错题:2、3题编程题:3题,