第5章构造数据类型.ppt

上传人:sccc 文档编号:5637681 上传时间:2023-08-04 格式:PPT 页数:101 大小:616.01KB
返回 下载 相关 举报
第5章构造数据类型.ppt_第1页
第1页 / 共101页
第5章构造数据类型.ppt_第2页
第2页 / 共101页
第5章构造数据类型.ppt_第3页
第3页 / 共101页
第5章构造数据类型.ppt_第4页
第4页 / 共101页
第5章构造数据类型.ppt_第5页
第5页 / 共101页
点击查看更多>>
资源描述

《第5章构造数据类型.ppt》由会员分享,可在线阅读,更多相关《第5章构造数据类型.ppt(101页珍藏版)》请在三一办公上搜索。

1、C+语言程序设计教程第11章C+输入输出流,第5章 构造数据类型,5.1 枚举类型,1.枚举类型的定义:“枚举”是指将变量所有可能的取值一一列举出来,变量的取值只限于列举出来的常量。枚举类型的声明的一般形式如下:枚举类型名以及枚举常量为标识符,遵循标识符的取名规则。在定义一个枚举类型时,定义了多个常量,供枚举类型变量取值,称此常量为枚举常量。当没给各枚举常量指定值时,其值依次默认为0、1、2、;在定义枚举类型时,也可使用赋值另行指定枚举常量的值。,enum 枚举类型名 枚举常量1,枚举常量2,枚举常量n;,枚举!,C+语言程序设计教程 第5章构造数据类型,5.1 枚举类型,枚举类型的定义:例1

2、:enum weekday SUN,MON,TUE,WED,THU,FRI,SAT;定义了7个枚举常量以及枚举类型weekday。枚举常量具有默认的整数与之对应:SUN的值为0、MON的值为1、TUE为2、SAT为6。例2:enum city Beijing,Shanghai,Tianjin=5,Chongqing;枚举常量Beijing的值为0,Shanghai的值为1,Tianjin的值指定为5。对于指定值后面的没有指定值的枚举常量,编译器会将前一个常量值加1(下一个整数)赋给它,所以Chongqing的值为6。,C+语言程序设计教程 第5章构造数据类型,5.1 枚举类型,枚举类型的定义说

3、明:枚举类型定义了以后就可以使用枚举常量、使用用枚举类型来定义变量,定义枚举变量的方法与定义其它变量的方法一样。例如:enum city city1,city2;city city1,city2;用两种不同方法定义了city1、city2两个枚举类型的变量名。枚举类型变量也可以在定义枚举类型的同时定义例如:enum cityBeijing,Shanghai,Tianjin=5,Chongqingcity1,city2;在定义枚举类型的同时定义枚举类型变量可以省略枚举类型 例如:enum Beijing,Shanghai,Tianjin=5,Chongqing city1,city2;在定义变量

4、时,可以顺便给出初值,若不给初值,默认初值为随机的无意义的数。,C+语言程序设计教程 第5章构造数据类型,5.1 枚举类型,枚举类型的使用:用枚举类型建立枚举变量后就可以对枚举变量实施赋值以及进行其它运算了,对枚举变量进行赋值,其值要求为同一枚举类型。否则,在编译时出错。例如:weekday d1,d2,d3,d4;d1=SUN;d2=6;/错误,因整数6不是枚举常量,可以写成d2=(weekday)6;d3=Shanghai;/错误 枚举常量、枚举类型的变量可进行算术运算、关系运算。对枚举类型实施算术、关系运算时,枚举值转换成整型值参加运算,结果为整型值。所以,如果要将结果赋给枚举变量,还要

5、将结果转换成枚举值。例如:d1=d1+2;/是错误的,因为结果为int型。需要将它强制转换成枚举型:d1=(weekday)(d1+2);,C+语言程序设计教程 第5章构造数据类型,5.1 枚举类型,枚举类型的使用:枚举常量、枚举类型的变量可直接进行各种形式的关系运算。例如:if(city1=3);if(city2=Beijing);if(Shanghai=1);if(city1SUN);枚举类型变量不能直接进行输入 例如:cind1;/错误,C+语言程序设计教程 第4章函数,注意:枚举常量是常量,不是变量,所以不能对枚举常量进行赋值。例如:在上例中不能进行赋值 Shanghai=Beijin

6、g;枚举常量的值不是列举的字符串,其值为整数。编译器对赋给枚举变量的对象(数)进行类型检查,如类型不相符则发出警告。当类型相 同,而值超出此类枚举类型枚举常量范围时,也是正常的。,枚举类型定义,C+语言程序设计教程 第5章构造数据类型,【例5-1】输入城市代号,输出城市名称。,5.1 枚举类型,运行结果:Input a city number(-1 to exit):1Shanghai8Invalid city number!-1,C+语言程序设计教程 第5章构造数据类型,枚举类型的使用,5.1 枚举类型,5.2 数组,数组:数组是一组在内存中依次连续存放的、具有同一类型的数据变量所组成的集合

7、体。其中的每个变量称为数组元素,它们属于同一种数据类型,数组元素用数组名与带方括号的数组下标一起标识。数组可以是一维的,也可以是多维的。特点:若干个同类型的数据元素,并且各个数据元素之间存在某种次序关系。这类数据有一个共同的特点:它们有若干个同类型的数据元素,并且各个数据元素之间存在某种次序关系。,C+语言程序设计教程 第5章构造数据类型,5.2.1 一维数组定义与使用,一维数组定义的一般形式为:说明:数组元素的类型可以是void型以外的任何一种基本数据类型,也可以是已经定义过的构造数据类型;数组名是用户自定义的标识符,用来表示数组的名称,代表数组元素在内存中的起始地址,是一个地址常量。常量表

8、达式必须是unsigned int类型的正整数。表示数组的大小或长度,也就是数组所包含数据元素的个数。是数组下标运算符,在数组定义时用来限定数组元素的个数。,数据类型 数组名常量表达式;,C+语言程序设计教程 第5章构造数据类型,注意:数组属于构造数据类型,在使用之前必须先进行类型定义。,5.2.1 一维数组定义与使用,数组元素的类型可以是void型以外的任何一种基本数据类型,也可以是已经定义过的构造数据类型;例如:下面定义了2个不同类型的数组:int a5;/定义了一个5个元素的整型数组a weekday b10;/定义了一个10个元素的枚举数组b,weekday为已定义的枚举型。数据类型相

9、同的多个数组可以在同一条语句中予以定义。例如:int a110,a220;/同时定义了两个整型数组 数据类型相同的的简单变量和数组也可以在一个语句中定义。例如:int x,a20;/同时定义了一个整型变量和一个整型数组,C+语言程序设计教程 第5章构造数据类型,5.2.1 一维数组定义与使用,数组定义之后,系统会将从内存中为其分配一块连续的存储空间,从第1个数据元素开始依次存放各个数组元素。例如,定义的数组a其内存排列(分配)示意图如图5-1所示。.例如:int a5;/定义了一个5个元素的整型数组a,C+语言程序设计教程 第5章构造数据类型,5.2.1 一维数组定义与使用,一维数组初始化:是

10、指在定义数组的同时给数组中的元素赋值。其一般语法形式为:初值1,初值2,初值n称为初值表,初值之间用逗号,分隔,所有初值用 括起来。初值可以是一个变量表达式,初值与数组元素的对应关系是:初值i给数组第i个元素;所以,初值个数n不能超过数组的大小。若初值表中初值个数(项数)小于数组的大小,则未指定值的数组元素被赋值为0;但初值表中项数不能为0。例如:weekday b10=MON,WED,FRI;当对全部数组元素赋初值时,可以省略数组的大小,此时数组的实际大小就是初值列表中初值的个数。例如:char str=a,b,c,d,e;/数组str的实际大小为5。在函数中定义数组时,如果没有给出初值表,

11、数组不被初始化,其数组元素的值为随机值;在函数外定义数组如果没有初始化,其数组元素的值为0。数组初值表的可以用一个逗号结尾,其效果与没有逗号一样。,数据类型 数组名 常量表达式=初值1,初值2,初值n;,C+语言程序设计教程 第5章构造数据类型,5.2.1 一维数组定义与使用,对一维数组实施的存取操作有两类:存取数组元素与读取数组元素的地址。数组元素是通过数组名及下标来标识的,这种带下标的数组元素也称为下标变量,下标变量可以象简单变量一样参与各种运算。存取一维数组元素的一般语法形式为:说明:下标表达式可以是变量表达式,用来标识数组元素;不同于数组定义时用来确定数组长度的常量表达式。当定义了一个

12、长度为n的一维数组a,C+规定数组的下标从0开始,依次为0、1、2、3、n-1。对应的数组元素分别是a0、a1、an-1,因此下标表达式的值要在0,n-1范围内。例如:a1+2=100;/将数组a的第4个元素赋值100。,数组名 下标表达式;,C+语言程序设计教程 第5章构造数据类型,5.2.1 一维数组定义与使用,【例5-2】学生成绩排序。分析:学生成绩由键盘输入,当输入一个负数时,输入完毕。采用直观的“选择排序法”进行排序,基本步骤如下:将a0依次与a1-an-1比较,选出大者与a0交换;最后a0为 a0-an-1中最大者;将a1依次与a2-an-1比较,选出大者与a1交换;最后a1为 a

13、1-an-1中最大者;同理,从i=2到i=n-1,将ai依次与ai+1-an-1比较,选出较大 者存于ai中。,C+语言程序设计教程 第5章构造数据类型,数组定义,数组使用,C+语言程序设计教程 第5章构造数据类型,运行结果:80 90 95 70-195 90 80 70,C+语言程序设计教程 第5章构造数据类型,5.2.1 一维数组定义与使用,4.数组的地址 数组元素的地址通过数组名来读取,其格式如下:由于其地址不是实际的地址值,称这个地址表达式为符号地址表达式。例如:一维数组元素a5的符号地址表达式为a+5。若a是一个int型数组,数组的符号地址表达式a+n所表达的地址是第n+1个元素a

14、n的地址,代表的实际地址值为:a+n*sizeof(int)而不是:a+n。,C+语言程序设计教程 第5章构造数据类型,数组名+整型表达式;,5.2.1 一维数组定义与使用,C+语言程序设计教程 第5章构造数据类型,使用数组要注意:在使用数组时最常犯的错误是数组元素越界,包括上标越界和下标越界。上标越界是指数组元素的访问地址值超过了数组的起始地址;下标越界是指数组元素的访问地址越过了数组中最后一个数组元素的地址。对于这种错误,编译器无法知道,往往在运行时出错。因此在程序设计时应格外注意。数组名是一个地址常量,不能作为左值(赋值的目标)。因此,不能将一个数组整体拷贝给另外一个数组。例如:int

15、a5,c5,i;a=c;/错误!正确的方法是将对应的元素进行拷贝,见下列程序段:for(i=0;i5;i+)ai=ci;/将数组c中元素的值拷贝到数组c的对应元素中在函数中,可以将一个一维数组作为函数的形式参数,用来接受一个一维数组传递过来的地址。,5.2.2 二维数组的定义与使用,二维数组的定义的一般形式为:其中:常量表达式1为第1维的元素的个数,常量表达式2为第2维元素的个数。二维数组amn是以长度为n的一维数组为元素的数组,因此,等价于如下定义方式:例如:int M23;定义了一个整型二维数组M,数组M也可以用下列方式定义:typedef int M13;/定义了一个一维整型数组M1;M

16、1 M2;/以M1为类型定义数组M,数据类型 数组名常量表达式2常量表达式1;,C+语言程序设计教程 第5章构造数据类型,typedef 数据类型 一维数组名常量表达式1;一维数组名 二维数组名常量表达式2;,5.2.2 二维数组的定义与使用,如果一维数组描述排列成一行的数据,那么,二维数组则描述若干行这样的数据。因此,二维数组可以看作是数学上的一个矩阵。第1维元素个数为矩阵的列数,第2维元素个数为矩阵的行数。二维数组的定义格式可以写成:定义一个二维数组后,系统为它分配一块连续的内存空间。二维数组amn占内存空间的计算公式为:,数据类型 数组名行数列数;,C+语言程序设计教程 第5章构造数据类

17、型,sizeof(数组名);或 m*sizeof(a0);或 m*n*sizeof(数据类型),5.2.2 二维数组的定义与使用,既然一个二维数组是由若干个一维数组排列构成,二维数组在内存中的排列顺序为:先顺序排列每个一维元素,构成一维数组;再将各个一维数组顺序排列,构成二维数组。int M23的排列顺序为:先将3个int元素排列组成2个一维数组M0,M1。M0:M00,M01,M02 M1:M10,M11,M12 再将2个一维数组排成一个二维数组。M:M0,M1 数组M在内存中的排列图如图所示。,C+语言程序设计教程 第5章构造数据类型,5.2.2 二维数组的定义与使用,二维数组的初始化:其

18、中初值表具有两种形式:嵌套的初值表,线性初值表。(1)嵌套初值表以二维数组Mmn为例,嵌套初值表的格式为:嵌套初值表由一维初值表嵌套构成,各层构成规则与一维数组的初值表相同。例如:int M34=1,2,3,4,3,4,5,6,5,6,7,8;/M数组元素被全部初始化 int a23=1,0,0,1;/初始化了部分数组元素 int b3=1,2,3,;/初始化了全部数组元素 int d3=1,3,5,5,7,9;/初始化了全部数组元素,省略了高维元素个数,数据类型 数组名 常量表达式2常量表达式1=初值表;,C+语言程序设计教程 第5章构造数据类型,M的初值表=M0初值表,M1初值表,Mm-1

19、初值表Mi初值表=Mi0初值表,Mi1初值表,Min-1初值表;i从0到m-1;,5.2.2 二维数组的定义与使用,(2)线形初值表 线形初值表与一维数组的初值表相同,初值表的项数不超过各维元素个数的乘积(总元素个数)。数组元素按内存排列顺序依次从初值表中取值,下列各数组使用了线形初值表,结果与使用嵌套初值表相同。例如:int M34=1,2,3,4,3,4,5,6,5,6,7,8;/M数组元素被全部初始化 int a23=1,0,0,0,1,1;/初始化了全部数组元素,一部分元素未给初值 int b 3=1,0,0,0,0,0;/初始化了全部数组元素,省略了高维元素个数 当使用线形初值表而省

20、略高维元素个数时,高维元素个数为:例如:int b 3=1,0,0,0;/高维元素个数为2,C+语言程序设计教程 第5章构造数据类型,向上取整数(线形初值表项数/低维元素个数),5.2.2 二维数组的定义与使用,(3)二维数组的存取 存取维数组元素的格式为:说明:行下标表达式与列下标表达式的值同样从0开始,aij表示数组的第i+1行、第j+1列的元素。由于数组元素是变量,可以对其进行各种各种操作。数组元素如果定义数组amn,即数组第1维大小为n,第2维大小为m。aij的排列位置与在内存中的地址计算公式如下:例如:a,a0:为数组a的起始地址,即a00的地址;ai+j:为数组的第i+1行的第j+

21、1元素的地址,即aij的地址;,C+语言程序设计教程 第5章构造数据类型,数组名 行下标表达式 列下标表达式,aij的排列位置=第1维大小n*i+j+1;aij的地址=a的起始地址+(第1维大小n*i+j)*sizeof(数据类型),二维数组定义并初始化,二维数组使用,C+语言程序设计教程 第5章构造数据类型,运行结果:70 71 72 73 7482 83 84 85 8692 93 94 95 96-1 0 0 0 070 71 72 73 74 36082 83 84 85 86 42092 93 94 95 96 470-81.3333 82.3333 83.3333 84.3333

22、85.3333 416.667,C+语言程序设计教程 第5章构造数据类型,5.2.3 多维数组,(1)三维以及高于三维的数组称为多维数组 多维数组的定义与二维数组类似,可以一次定义,也可以逐步由低维数组定义。例如:int b234;/定义了一个三维数组 也可用下列方式步定义:typedef int B134;B1 b2;多维数组在内存的排列方式同样是先排低维数组,由低向高依次排列。如:b234的排列顺序为:b00:b000,b001,b002,b003 b0 b01:b010,b011,b012,b013b b02:b020,b021,b022,b023 b10:b100,b101,b102,

23、b103 b1 b11:b110,b111,b112,b113 b12:b120,b121,b122,b123,C+语言程序设计教程 第5章构造数据类型,5.2.3 多维数组,(2)多维数组的初始化与存取多维数组的初始化形式与二维数组类似:有嵌套初值表、线性初值表两种形式。使用线性初值表初始化时,数组元素按内存排列顺序依次从初值表中取值。对多维数组进行存取包括对数组元素的存取和对数组元素的地址的读取,当一个多维数组的下标数与维数相同时,为对数组元素的存取。当下标个数小于维数时表示的是一个地址,表示地址时,下标也不能越界。如:下列都是b234的地址表达式。b1;/b100的地址;b2;/错误,下

24、标越界;b0+1;/与b01相同,b010的地址。b12;/b120的地址 b12+4;/b124的地址,但数组b中没有b124这个元素,故指向了其它地方。,C+语言程序设计教程 第5章构造数据类型,C+语言程序设计教程 第5章构造数据类型,运行结果:Add of b:&b=0012FEF0 b=0012FEF0&b000=0012FEF0Add of bk:&bk=0012FF40 bk=0012FF40 b+k=0012FF40&b0+k=0012FF40&bk00=0012FF40Add of bkm:&bkm=0012FF5E bkm=0012FF5E bk+m=0012FF5E&b0

25、0+k*M+m=0012FF5E&bkm0=0012FF5E&b00+(k*sizeof(b0)/sizeof(b00)+m=0012FF5EAdd of bkmn:&bkmn=0012FF66 bkm+n=0012FF66&b000+k*M*N+m*N+n=0012FF66&b000+(sizeof(b0)*k+sizeof(b00)*m)/sizeof(b000)+n=0012FF66,C+语言程序设计教程 第5章构造数据类型,5.2.4 数组与函数,数组名是一个地址,不能当作一个左值,但是可以作为函数的形参,接受实参传送来的地址。当形参接受实参传送来的地址后,形参数组与实参共享内存中的一

26、块空间。函数体通过形参对数组内容的改变会直接作用到实参上。数组名作为形参是数组应用的一个重要方面。注意:(1)使用数组名传递地址时,虽然传递是地址,但形参与实参的地址(数组)类型应一致。(2)形式参数中数组元素个数没有给定,因此,在函数体中,对数组存取的下标可以为任意值而不会出现编译错误。但是,当这个下标超过了实参数组的元素个数范围时,存取的就不是实参数组中的内容了。,C+语言程序设计教程 第5章构造数据类型,C+语言程序设计教程 第5章构造数据类型,数组作为函数形式参数,运行结果:20060101182861682006010217586161200602042869017620060205

27、290831732006020328080160,C+语言程序设计教程 第5章构造数据类型,数组作为函数形式参数,5.2.5 字符数组与字符串,存放字符型数据的数组称为字符数组。字符数组也分为一维数组和多维数组。前述的数组的定义及初始化同样适用于字符数组,除此以外,C+对字符数组的初始化还可以使用字符串形式。1.用字符进行初始化 例如:chars1=C,h,i,n,a;chars2 4=H,o,w,a,r,e,y,o,u;2.用字符串进行初始化 例如:chars3=China;chars4 4=how,are,you;,C+语言程序设计教程 第5章构造数据类型,3.字符数组的使用 字符数组也是

28、数组,我们同样可以通过数组名及下标引用数组中的元素。为方便对字符与字符串的处理,C+提供了许多专门处理字符与字符串的函数,这些函数原型在各自的头文件中定义。下表列出了常用的字符与字符串处理函数的调用方法与功能简介,函数原形与详细的功能可以从C+编译器的帮助文档中获得。,C+语言程序设计教程 第5章构造数据类型,5.2.5 字符数组与字符串,常用字符与字符串处理函数,C+语言程序设计教程 第5章构造数据类型,5.2.5 字符数组与字符串,常用字符与字符串处理函数,C+语言程序设计教程 第5章构造数据类型,1 ChenHailing2 CuiPeng3 GongJing4 HuangPin5 Li

29、anXiaolei6 LiuNa7 LiuPing8 ZhouZijunInput the searching name:LiuPingPosition:7,C+语言程序设计教程 第5章构造数据类型,5.3 指针,指针是C+语言最重要特性之一,也是C+的主要难点。指针提供了一种较为直观的地址操作的手段,正确地使用指针,可以方便、灵活而有效地组织和表示复杂的数据。指针在C+程序中扮演着非常重要的角色,从某种程度上而言,如果不能深刻的理解指针的概念,正确而有效的掌握指针,就不可能真正学好C+,但是指针也是我们最容易产生困惑并导致程序出错的原因之一。,C+语言程序设计教程 第5章构造数据类型,5.3

30、 指针,1.地址与指针地址:当定义一个变量后,内存中将会划出一块由若干个存储单元组成的区域,用于保存该变量的数据。在内存里每个存储单元都有各自的编号,称为地址。指针:在C+中,提供了指针类型,它是一种用于存放内存单元地址的变量类型,地址就存储在这种指针类型的变量中。正因为指针变量存储的是地址,用它来指明内存单元,所以形象地称这种地址变量为指针。,C+语言程序设计教程 第5章构造数据类型,5.3 指针,2.指针变量的定义 每存储一个地址,就要定义一个指针变量。定义指针变量的格式如下:数据类型是指针变量所指向对象的数据类型,它可以是基本数据类型,也可以是构造数据类型以及void 类型。变量名是用户

31、自定义的标识符。*表示声明的变量是一个指针变量,而不是普通变量。例如:int*ip;/定义了一个int型的指针变量ip float*fp;/定义了一个float型指针变量fp typedef int A10;A*ap;/定义了一个A类型的指针变量ap sizeof(ip)=sizeof(fp)=sizeof(ap)=4;,数据类型*变量名;,C+语言程序设计教程 第5章构造数据类型,5.3 指针,3指针的初始化与赋值 定义了一个指针,只是得到了一个用于存储地址的指针变量。若指针变量既没有初始化,也没有赋值,其地址值是一个随机的数。(1)不要将一个非地址常量、变量以及无意义的实际地址赋给指针变量

32、。如:int*p=100;/错误,100是一个int型常量,不是一个地址常量。int*p=(char*)100;/危险!100是一个无意义的实际地址,可能指向危险区域。(2)可以使用一个已初始化的指针去给另一个指针赋值,但类型必须一致如果不一致,可 进行强制类型转换。char*p=NULL;int*ip=(int*)p+100;/将char型指针强制转化成int型指针。(3)对于基本数据类型的变量、数组元素我们可以使用取地址运算符/定义void类型的指针,数据类型*指针变量名=初始地址表达式;,C+语言程序设计教程 第5章构造数据类型,5.3 指针,4指针运算 指针变量存放的是地址,因此指针的

33、运算实际上就是地址的运算,但正是由于指针的这一特殊性,使指针所能进行的运算受到了一定的限制。指针通常进行下列几种运算:赋值运算、取值运算、算术运算、相减运算、比较运算。(1)*和,C+语言程序设计教程 第5章构造数据类型,5.3 指针,(2)指针与整数的加减运算 指针的加减运算与普通变量的加减运算不同,由于指针存储的是变量的内存地址,指针加上或减去一个整数n,表示指针从当前位置向后或向前移动n个sizeof(数据类型)长度的存储单元。因此对于不同的数据类型,n的实际大小就不同。例如程序段:int b234;typedef char A10;int*p1=b10;int*p2=(int*)b1;

34、int*p3=(int*)(b+1);double*pd=(double*)p3;A*pa=(A*)p3;coutp1,p2,p3,pd,paendl;coutp1+1,p2+1,p3+1,pd+1,pa+1endl;,运行结果:0013FF80,0013FF80,0013FF80,0013FF80,0013FF800013FF84,0013FF84,0013FF84,0013FF88,0013FF8A,C+语言程序设计教程 第5章构造数据类型,5.3 指针,(3)指针自增、自减运算 指针的自增、自减运算是指针加减运算的特例。指针的自增或自减表示指针从当前位置向后或向前移动sizeof(数据类

35、型)长度的存储单元。例如:程序段:int*p,*q,a=5;p=/这是一种常用的表达式,依次执行:*q=*p,q+,p+(4)两指针相减 当两个指针指向同一数组时,两个指针的相减才有意义。两个指针相减的结果为一整数,表示两个指针之间数组元素的个数。,C+语言程序设计教程 第5章构造数据类型,5.3 指针,(5)两个指针的比较运算 两个指针的比较一般用于下列两种情况:一是比较两个指针所指向的对象在内存中的位置关系;二是判断指针是否为空指针。5void类型指针 指向void类型的指针是一种不确定类型的指针,它可以指向任何类型的变量。实际使用void型指针时,只有通过强制类型转换才能使void型指针

36、得到具体变量的值。在没有转换前void型指针不能进行指针的算术运算。例如:void*vp;/定义了一个void型指针vp inti=6,*ip;vp=,C+语言程序设计教程 第5章构造数据类型,5.3.2 指针与字符串,字符型指针:用于存放字符型变量的地址,而字符串的本质是以0结尾的字符数组,一个字符型指针存储了字符数组的第一个元素的地址,也就存储了字符串的地址,这个指针就指向了字符串。在定义一个字符数组时,可以将一个字符串常量作为初值,但将字符串常量作为初值赋给字符数组和将字符串常量作为初值赋给字符指针变量,二者的含义是不同的。例如:char str5=abcd;char*p_str=abc

37、d;在上述字符串定义有下列不同:(1)字符数组str5被赋值为“abcd”,因此,数组str的五个数组元素的值分别为 字符a、b、c、d和0。字符指针p_str被赋值为“abcd”,则意味着 指针p_str的值为字符串常量abcd的第一个字符a在内存中的地址。(2)字符指针p_str比str多分配了一个存储地址的空间,用于存储字符串的首地 址。,C+语言程序设计教程 第5章构造数据类型,5.3.3 指针与数组,1.使用指针操作符*存取数组 指针的加减运算的特点使得指针操作符特别适合处理存储在一段连续内存空间中的同类型数据。这样,使用指针操作符来对数组及其元素进行操作就非常方便。(1)一维数组的

38、指针操作 当定义数组一维数组T aN(T为类型),下式为存取数组元素ai的等效方式:*(a+i);而a+i为ai的地址。(2)多维数组的指针操作 对于多维数组,使用指针同样可以灵活访问数组元素。若定义数组T bKM,下式为存取数组元素aij的等效方式:例如:*(*(b+i)+j);其中:*(b+i)+j为bij的地址,即*(b+i)为bi0的地址,即bi,也是bi0地址;,C+语言程序设计教程 第5章构造数据类型,5.3.3 指针与数组,2.指针数组 指针数组是以指针变量为元素的数组,指针数组的每个元素都是同一类型的指针变量。在指针数组的定义中有两个运算符:*和,运算符 的优先级高于*,所以*

39、pN等价于*(pN),p N表示一个数组,而*表示数组元素为指针变量。例如:int*p_a5;定义了一个指针数组,其中有5个数组元素,每个数组元素都是一个int类型的指针。,注意:对指针数组的存取同样可以使用指针方式、数组方式、以及指针与数组结合的方式。一维指针数组与二维指针数组对应,可采用存取二维数组的方式存取。指针数组的每一个元素都是一个指针,因此必须先赋值,后引用。,C+语言程序设计教程 第5章构造数据类型,5.3.3 指针与数组,3)数组指针 数组指针是指向数组的指针。虽然运算符 的优先级高于*,但是,在数组指针的定义式中,(*指针名)改变了这种优先级,它表明定义的首先是一个指针,然后

40、才是什么类型的指针。例如:int(*a_p)5;等效于下列定义方式:typedef int I_A5;I_A*a_p;,C+语言程序设计教程 第5章构造数据类型,5.3.4 多重指针,如果已经定义了一个指针类型,我们再定义一个指针,用于指向已经定义的指针变量,后面定义的指针变量就是一个指向指针的指针变量,简称指向指针的指针,这样的指针也称二重(级)指针。三重及以上的指针统称为多重指针。例如:int*pp;定义了一个二级指针变量,等效于下列定义方式:typedef int*P;P*p;二级指针常用来指向一个指针数组。例:int a23=1,2,3,4,5,6;/声明并初始化二维数组 int*p_

41、a3;/声明整型指针数组 p_a0=a0;/初始化指针数组元素 p_a1=a1;int*pp;pp=p_a;,C+语言程序设计教程 第5章构造数据类型,5.3.4 多重指针,注意:在使用二级指针时经常容易犯两类错误。(1)类型不匹配 例如:pp=a;/错误,因为pp是一个int*型变量,a是一个int23型的地址 pp=只是定义了一个指针变量,变量中的内容(地址)是一个无意义的地址,而*p2=&i是对无意义的内存单元赋值,这样是错误与危险的。正确的作法是从第一级指针开始,逐级初始化。,C+语言程序设计教程 第5章构造数据类型,5.3.4 多重指针,3)逐级初始化多级指针 例:int i=3;i

42、nt*p2;int*p1;p1=/结果为5 上述两个二级指针在内存中的分布如右图所示。,C+语言程序设计教程 第5章构造数据类型,5.3.4 多重指针,当一个二级指针指向一个指针数组后,对数组元素的存取可以使用指针方式、数组方式、混合方式:例如:pij;/存取数组元素aij的数组方式;*(*(p+i)+j);/存取数组元素aij的指针方式;*(pi+j);/存取数组元素aij的混合方式;一般而言,二重指针就足够使用了,三重指针使用场合就很少了,使用多重指针同样要:,注意:不管是多少重指针,定义后,只建立了一个指针变量,分配一个指针变量的空间。要初始化多重指针,要从第一层开始,逐步向高层进行。,

43、C+语言程序设计教程 第5章构造数据类型,5.3.5 动态内存分配,在C+中,动态内存分配技术可以保证程序在运行过程中根据实际需要申请适量的内存,使用结束后还可以释放。C+通过new运算和delete运算来实现动态内存分配。1.new运算 new运算的作用是按指定类型和大小动态的分配内存。基本语法形式为:其中:数据类型可以是基本数据类型,也可以是用户自定义的复杂数据类型。new运算符在堆(内存)中创建一个由类型名指定类型的对象,如果创建成功,返回对象的地址;否则返回空指针NULL。初值列表给出被创建对象的初始值。由于返回的是地址,所以要用事先定义一个类型相同的指针变量来存储这个 地址。,指针变

44、量=new 类型名(初值列表);,C+语言程序设计教程 第5章构造数据类型,5.3.5 动态内存分配,1)new创建指定类型对象 例:int*ip;ip=newint(5);/ip指向1个初值为5的int型对象 也可以使用一条语句定义:int*ip=new int(5);,C+语言程序设计教程 第5章构造数据类型,说明:首先定义了一个整型指针ip;然后申请内存,创建一个int型数据对象,并将该数据对象初始化为5;最后返回创建的数据对象的地址,存入ip。,5.3.5 动态内存分配,2)new创建动态数组时 使用new运算可创建一个数据对象,也可以创建同类型的多个对象-数组。由于数组大小可以动态给

45、定,所创建的对象称为动态数组。new创建动态数组时,需要给出数组的结构说明。其语法格式如下:其中:下标表达式与数组初始化时的常量表达式不同,可以是变量表达式。用new申请失败时,返回NULL。申请一个动态数组,往往需要较大的空间,因此,在程序中需要对new的返回值进行判断,看是否申请成功。例:int*pa;pa=newint5;/ip指向5个未初始化的int型数据对象的首地址,C+语言程序设计教程 第5章构造数据类型,指针变量=new 类型名 下标表达式;,5.3.5 动态内存分配,3)new创建多维数组 使用new也可创建多维数组,其语法形式如下:其中:当用new创建多维数组时,只有下标表达

46、式1可以任意结果是正整数的表达式,而其它下标表达式必须是值为正整数的常量表达式。如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,它是一个T类型数组的指针,而不是T类型指针。数组元素的个数为除最左边一维(最高维)外各维下标表达式的乘积。例:int*pb;pb=new int345;/错误,new操作产生的是指向一个int45的二维int/型数组的指针 int(*pb)45;pb=new int345;/正确,针pb既可以作为指针使用,也可以像一个/三维数组名一样使用,C+语言程序设计教程 第5章构造数据类型,指针变量=new 类型名T 下标表达式1 下标表达式2,5.3.5 动态

47、内存分配,2、delete运算 当程序不再需要由new分配的内存空间时,可以用delete释放这些空间。其语法格式为:如果删除的是动态数组,则语法格式为:其中:括号表示用delete释放为多个对象分配的地址,中不需要说明对象的个数。不管建立的动态数组是多少维,释放的格式都是一样。对于例分配的空间,释放语句如例:delete ip;delete pa;delete pb;,delete 指针变量名;,delete 指针变量名;,C+语言程序设计教程 第5章构造数据类型,C+语言程序设计教程 第5章构造数据类型,C+语言程序设计教程 第5章构造数据类型,运行结果:input matrix size

48、 m,n:2 31 2 34 5 61 2 34 5 6,注意:各用new运算符申请分配的内存空间,必须用delete释放;delete作用的指针必须是由new分配内存空间的首地址;对于一个已分配内存的指针,只能用delete释放一次;new和delete运算实现了堆空间的动态分配,它在带来方便的同时也潜伏了可能的隐患:使用new进行内存分配之后,忘记了使用delete运算进行内存回收,即“内存泄露”,如果程序长时间运行,则有可能因内存耗尽而使系统崩溃,以对new和delete要养成配对使用的良好习惯。,C+语言程序设计教程 第5章构造数据类型,【例5-8】动态创建多维数组分析:当用new动态

49、创建多维数组时,如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,它是一个T类型数组的指针,而不是T类型指针,数组元素的个数为除最左边一维(最高维)外各维下标表达式的乘积。,C+语言程序设计教程 第5章构造数据类型,运行结果:0 1 2 310 11 12 1321 22 23100 101 102 103110 111 112 113120 121 122 123,思考:建立一个动态数组后,如果在程序的运行过程中,数组溢出,程序运行结果又将是什么?请读者尝试修改程序,使数组溢出并分析程序的运行结果。,数组的new操作(动态指针)例:int(*pa)20=new int1520;

50、int(*pa)20=new intn20;/n为已定义变量并赋了值。合法但int(*pa)20=new int 20;或int5n 不合法注意二维数组a105是一个二级地址,int(*p)5是一个指向二维数组的行指针或称数组指针,且数组每行为5列,a105可以看成10个一维数因此(*p)n是行指针,一般的*P为列指针,p,py,C+语言程序设计教程 第5章构造数据类型,可以这样定义:int a35;int(*p)5=a;int*p=a0等但 int b5,a35,(*p)5;如果执行p=b;or p=a0均为错误,编译不能通过。报错如下:C+Error Cannot convert int*

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号