第五章构造数据类型.ppt
《第五章构造数据类型.ppt》由会员分享,可在线阅读,更多相关《第五章构造数据类型.ppt(126页珍藏版)》请在三一办公上搜索。
1、第五章 构造数据类型,C+开发实例教程刘畅主编 电子工业出版社,本章学习内容,掌握数组的概念以及应用;理解指针的概念,掌握指针的使用;掌握指针与数组的区别,能够使用多重指针以及指针与数组的多种混合体,会分配动态数组;掌握常用的字符串处理函数;理解引用的概念,掌握引用型函数参数的用法;掌握结构与联合类型的定义与应用,并注意二者之间的区别;掌握枚举数据类型的使用。,本章目录,第十一讲 数 组第十二讲 指针基础知识第十三讲 字符指针、指针数组、指向指针的指针和常用字符串处理函数第十四讲 指针和函数第十五讲 动态存储分配、void指针和引用第十六讲 结构、联合与枚举类型本章小结,结 束,第十一讲 数
2、组,一、一维数组的定义、初始化、数据赋值、数组越界二、二维数组三、数组作为函数参数练一练,返回本章目录,一、一维数组的定义、初始化、数据赋值、数组越界,【实例5-1】将学生成绩从大到小排序(学生成绩由数组初始化得到,使用冒泡法进行排序)。点击打开【实例5-1】源程序。程序运行结果如下:,返回本讲目录,1一维数组的定义,一维数组定义的一般形式为:其中:(1)数据类型为数组元素的数据类型,可以由基本的数据类型进行定义,例如整型、浮点型等基本类型,也可以是结构、类等用户自定义类型(后面介绍),但void类型除外。(2)数组名为数组的名称,必须遵循标识符的命名规则,同一函数中的数组名不能与其他变量同名
3、。,数据类型 数组名常量表达式;,返回本讲目录,(3)常量表达式为一维数组中存储的元素的个数,可以为常量或符号常量,必须是正整数,表示数组的大小或长度,不能为变量。(4)方括号“”是数组下标运算符,在数组定义时用来限定数组元素的个数。数组名是一个地址常量,不能作为赋值的目标。因此,不能将一个数组整体赋值给另外一个数组。,返回本讲目录,2数组初始化,数组的初始化就是在声明数组时给部分或全部元素赋初值。一维数组初始化的一般形式为:,数据类型 数组名常量表达式=初值1,初值2,初值n;初值表,返回本讲目录,(1)其中初值1,初值2,初值n称为初值表,初值之间用逗号分隔。例如,定义了5个元素的整型数组
4、a的语句如下:int a5=1,2,3,4,5;(2)当对全部数组元素赋初值时,可以省略数组的大小,此时数组的实际大小就是初值列表中初值的个数。例如,定义具有5个元素的字符数组c的语句如下:char c=a,b,c,d,e;(3)可以只给数组中部分元素赋初值。int a10=1,2,3,4,5;,返回本讲目录,3数组引用,一维数组元素引用的一般格式为:对一维数组的两点说明:(1)下标表达式可以是变量表达式,用来标识数组元素。(2)C+中数组的下标从0开始,若数组中元素个数为n,则数组的下标依次为0,1,2,3,n-1,对应的数组元素依次为a0,a1,an-1。例如,在【实例5-1】中第17行语
5、句:t=ai;中的ai就是对数组a中第i个元素的引用。,数组名下标表达式,返回本讲目录,4数组越界,C+中,编译和执行时并不检查数组下标是否越界。例如,如果有int a10;语句,则该一维数组a中元素的最大下标值为9,若在程序中引用数组元素时使用a10则数组越界。但是在编译和执行时并不能检查出这种错误。这是因为数组的名字即为数组的首地址,a10对应于内存地址a+10,但是此地址可能不在程序可以控制的范围内,由此带来的非法内存地址访问可能会对系统或程序产生不可预知的影响。所以,使用数组时需要特别注意检查下标是否越界。,返回本讲目录,二、二维数组,【实例5-2】有一个34的矩阵,求其中元素的最大值
6、,以及该元素所在的行号和列号。点击打开【实例5-2】源程序。(1)定义二维数组int a34,定义变量max存放最大值,变量row存放最大值的行号,变量col存放最大值的列号;(2)将第一个元素a00作为临时最大值max,row和col的初值设为0;(3)将max与每一个元素aij进行比较,若aijmax,把aij作为新的临时最大值,并将其下标i和j赋给row和col;(4)当全部元素比较完后,max是整个矩阵全部元素的最大值,输出最大值max和其所在的行号row和列号col。程序运行结果如下:,返回本讲目录,5二维数组,当数组元素的下标有两个或两个以上时,称该数组为多维数组。下标为两个时,称
7、为二维数组;下标为三个时,称为三维数组;以此类推,下面我们主要介绍一下二维数组。(1)二维数组定义的一般格式为:说明:常量表达式1是数组元素的行数,常量表达式2是数组元素的列数。,数据类型 数组名常量表达式1常量表达式;,返回本讲目录,(2)二维数组的初始化:二维数组的初始化与一维数组初始化方法相似,初值表有两种形式:嵌套的初值表和线性初值表。嵌套初值表例子如下所示:int a23=1,2,3,4,5,6;/a数组分行初始化int a23=1,2,3,4,5,6;/a数组不分行初始化int a23=1,2,4;/对二维数组a部分元素初始化int a3=1,2,3,4,5,6;/省略第一维的数组
8、长度,返回本讲目录,(2)二维数组的初始化:线性初值表例子如下所示:int a23=1,2,3,4,5,6;/初始化了全部数组元素int a23=1,2,3;/初始化了部分数组元素int a3=1,2,3,4,5,6;/初始化了全部数组元素,此时可以省略第一维数组的长度当使用线性初值表省略第一维元素个数时,该值计算方法为:向上取整(线性初值表项数/第二维元素个数)例如:int a3=1,0,0,0;则第一维元素个数为4/3=2。,返回本讲目录,(3)二维数组元素引用的一般格式:说明:行下标表达式与列下标表达式的值同样从0开始,如果有一个二维数组行数为m,列数为n,则行下标范围为0m-1,列下标
9、范围为0n-1。如第i行、第j列的元素可表示成为aij。,数组名行下标表达式列下标表达式,返回本讲目录,三、数组作为函数参数,【实例5-3】设计一个函数,计算二维数组每行元素值的和。).点击打开【实例5-3】源程序。程序分析:在主函数中初始化一个二维数组并将每个元素都输出,然后调用子函数RowSum()计算每一行的元素之和,将和直接存放在每行的第一个元素中,返回主函数之后输出各行元素的和。程序运行结果如下:,返回本讲目录,6数组作为函数参数,数组名是一个地址,它可以作为函数的形参,接收实参传送来的地址,当形参接收实参传送来的地址后,形参数组与实参共享内存中的存储空间,形参值改变将影响实参的值。
10、数组作为形式参数时,函数调用时传递的是地址。所以,形式参数中数组的大小没有意义,可以省略。,返回本讲目录,关于数组作为函数参数的几点说明:(1)用数组名作函数参数,应该在主调函数和被调用函数中分别定义数组。例如,在【实例5-3】中table是实参数组名,a是形参数组名。且数据类型必须一致,否则结果将出错。(2)用数组名作函数实参时,不是把数组元素的值传递给形参,而是把实参数组的起始地址传递给形参数组,这样两个数组就共占同一段内存单元。(3)C+编译系统对形参数组大小不做检查,所以形参数组可以指定大小也可以不指定大小。,返回本讲目录,练一练,【练习5-1】有一个34的矩阵,调用函数求所有元素中的
11、最大值。解:定义一个子函数fmax,在子函数fmax中设一个最大值max,并赋初值为arr00,然后将arrij与max进行比较,如果arrijmax,则将arrij赋给max,最后返回max值即为该数组中元素的最大值。注意在调用该函数时是将数组名作为函数参数传递的,此时是将实参数组名a(数组首地址)传给形参数组名arr,即两个数组是同一个数组。,点击打开【练习5-1】源程序。,程序运行结果如下:,返回本讲目录,第十二讲 指针基础知识,一、指针的定义、初始化、运算及const指针二、一维、二维数组中的指针使用三、指向一维数组的指针 练一练,返回本章目录,一、指针的定义、初始化、运算及const
12、指针,【实例5-4】阅读下面程序,分析并写出程序的运行结果。点击打开【实例5-4】源程序。程序运行结果如下:,返回本讲目录,程序分析:程序中首先定义了一个整型变量i并初始化为10,接着定义了一个整型指针ip,然后用取地址操作符“&”求出i的地址并赋给指针ip。此时,变量i中存放的是整数10,指针ip中存放的是地址3000,如图5-1所示。(这里假设整型变量i和整型指针ip在内存中的地址分别为3000和2000。)输出流中的*ip即指针ip所指的变量i的值(为10)。这时,输出的i值和*ip都是10。前者是直接访问,后者是通过指针的间接访问。直接输出ip的值表示指针ip所指的变量i所在的内存地址
13、值。,图5-1【实例5-4】内存变量地址及指针示意图,返回本讲目录,1指针定义,当定义一个变量后,内存中将会划出一块由若干个存储单元组成的区域,用于保存该变量的数据。在内存里每个存储单元都有各自的编号,称为地址。在C+中,提供了指针类型,它是一种用于存放内存单元地址的变量类型,地址就存储在这种指针类型的变量中。由于指针变量存储的是地址,用它来指明内存单元,所以形象地称这种地址变量为指针。,返回本讲目录,返回本讲目录,指针定义的一般格式:说明:数据类型是指针变量所指向对象的数据类型,它可以是基本数据类型,也可以是构造数据类型以及void类型。指针变量名是用户自定义的标志符。星号“*”表示定义的变
14、量是一个指针变量,而不是普通变量。,数据类型*指针变量名;,如果指针指向的是一种不确定的数据类型,则可以用void进行定义。,返回本讲目录,2指针的初始化,(1)在定义指针的同时进行初始化:例如:int i=10;/定义一个整型变量i int*ip1=/将变量i的地址赋值给指针变量ip1由于ip1是一个指针,所以不能将变量i的值直接赋值给ip1,只能将变量i的地址赋值给ip1。符号“&”是一个取地址运算符,可以得到变量的内存地址。,返回本讲目录,数据类型 幕*指针名=初始地址;,返回本讲目录,(2)在定义指针变量之后,单独使用赋值语句进行赋值:,指针名=地址;,例如:int*ip2=ip1;此
15、时,这两个指针指向同一存储空间,如图5-2所示。,图5-2 两个指针指向同一个存储空间示意图,返回本讲目录,对于指针的几点说明:(1)指针赋值时类型必须一致,如果不一致要进行强制转换。例如:inta=10;int*p1=/正确,将整型指针强制转换成字符型后赋给字符指针p3(2)void类型的指针可以存储任何类型的地址,但是与其他类型进行赋值时要使用强制类型进行转换。例如:void*p1;int*p2=(int*)p1;,返回本讲目录,3指针运算,(1)“*”和“&”运算“*”称为指针运算符。它有两种含义:在定义指针变量时,例如:int*p;中的“*”起到说明作用,说明p是一个指针变量;当“*”
16、出现在指针变量表达式左边时,表示访问指针所指对象的内容。其书写格式如下:,*指针变量表达式,返回本讲目录,(2)指针与整数的加、减运算指针的加、减运算与普通变量的加、减运算有所区别,指针变量中存放的是变量的内存地址,指针加上或减去一个整数n,表示指针从当前位置向后或向前移动n个sizeof(数据类型)长度的存储单元,如图5-3所示。例如:int*p,*q,a=5;p=/相当于*q=*p,q+,p+,返回本讲目录,(3)两指针相减当两个指针指向同一数组时,两个指针相减才有意义。两个指针相减表示两个指针之间数组元素的个数,结果为一个整数。(4)两个指针的比较运算主要进行以下处理:比较两个指针所指向
17、的对象在内存中的位置关系。判断指针是否为空。,返回本讲目录,4const指针,(1)指针常量如果在定义指针变量时,指针变量前用const修饰,被定义的指针变量就变成了一个指针类型的常变量,指针类型的常变量简称为指针常量。格式如下:修饰符const与指针变量紧邻,说明指针变量不允许修改。既然指针变量的值不能修改,所以一定要在定义时给出初值。,数据类型*const 指针变量=变量名;,返回本讲目录,(2)常指针如果在定义指针变量时,数据类型前用const修饰,被定义的指针变量就是指向常量的指针变量,指向常量的指针变量称为常指针。格式如下:定义了一个常指针后,指针指向的值就不能被更改,即不能通过指针
18、变量直接更改指针指向的值。,数据类型 const*指针变量=变量名;或 const 数据类型*指针变量=变量名;,定义常指针时不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外对象。,返回本讲目录,二、一维、二维数组中的指针使用,【实例5-5】分析下面程序,并写出程序的运行结果。点击打开【实例5-5】源程序。程序分析:在前面的章节中我们已经学习过一维数组、二维数组元素的输出,数组名就是数组的首地址,那么数组名就是指向数组第一个元素的指针,而*(a+i)中的a+i为数组首地址a加上i个元素的地址,得到的是数组中第i个元素的地址,再通过取对象运算*,得到对象*(a+i)就是数组a中各
19、元素的值。依次输出数组a的各个元素。同理,当指针p=a;时,p也指向数组a的首地址,这时使用指针p也可以输出数组a中的各元素。使用方法与使用数组名a相同。*(p+i)也表示数组a中下标为i的元素。,返回本讲目录,返回本讲目录,b也是二维数组b的首地址指针,则(b+i)为二维数组的第i行首地址,取对象后*(b+i)得到该行第0个元素的首地址,然后*(b+i)+j再加上j得到该行第j个元素的地址,再取对象*(*(b+i)+j)就得到了该对象,即数组b中的每一个元素bij。依次输出数组b的各个元素。程序运行结果如下:,返回本讲目录,返回本讲目录,5指针与一维数组、二维数组,指针加减运算的特点使得指针
20、特别适合于处理存储在一段连续内存空间中的同类型数据。而数组恰好是具有一定顺序关系的若干同类型变量的集合体,数组元素的存储在物理上也是连续的,数组名就是数组的首地址,这样我们就可以使用指针来对数组及其数据进行方便、快速的操作。,返回本讲目录,(1)一维数组的指针操作 一维数组的数组名实际上就是指向数组下标为0的元素的指针。,则数组a中的元素与数组名a及指针p的关系,如图5-4所示。指向一维数组首元素的任何指针也可以像一维数组名那样使用。由于指针p和数组名a均是指向数组a的首元素的指针,即p和a是完全等价的。因此,访问数组a中下标为i的元素,可以使用如下四种表示形式:ai、pi、*(a+i)、*(
21、p+i)。,图5-4 一维数组元素与元素地址关系示意图,返回本讲目录,(2)二维数组的指针操作,图5-5 数组元素与元素地址关系图,二维数组b中bij的地址可以用以下5种表达式求得:&bij、bi+j、*(b+i)+j、&b00+列数*i+j、b0+列数*i+j。,返回本讲目录,三、指向一维数组的指针,【实例5-6】分析下面的程序,并写出程序的运行结果。程序分析:本程序通过两种指针方式输出一个二维数组。定义一个整型指针p和一个指向一维数组的指针pa。第一个循环使用了指向一维数组的指针pa,在外层循环中首先将二维数组a的首地址赋给指针pa,这时pa就指向了数组a的首地址。然后在内层循环中j为二维
22、数组的列下标,输出对象*(*pa+j)(j从01变化即可输出该行的数组元素值),然后pa自增,相当于移到数组的下一行行首,继续输出,最后输出全部数组元素。,返回本讲目录,然后再将普通指针p指向数组的第0行的首地址,这时相当于p指向了a00元素,然后使用双重循环输出元素*(p+),即数组a的各元素的值(因为数组a中各元素的存储位置是连续的)。,点击打开【实例5-6】源程序。,程序运行结果如下:,返回本讲目录,6指向一维数组指针,数组指针是指向数组的指针。(1)指向一维数组的指针定义的一般格式:其中:类型标识符是说明指针所指向的一维数组中元素的类型,常量表达式说明指针指向的一维数组中元素的个数,例
23、如,【实例5-6】中第7行语句:int(*pa)2;声明了一个指向有2个整型元素的一维数组的指针。,类型名(*指针名)常量表达式;,返回本讲目录,(2)指针赋值。一般都是用一个二维数组名赋值,例如,【实例5-6】中第10行的表达式:pa=a就是使pa指向二维数组a第0行的首地址。(3)指针移动。当使用指向一维数组的指针指向一个二维数组时,该指针移动一位,就相当于移动二维数组的一行。例如,【实例5-6】中第10行语句中的表达式:pa+则相当于pa指针在二维数组a向后移动了一行,pa指向下一行元素的首地址。,返回本讲目录,练一练,【练习5-2】输入一批学生成绩,当输入为负值时结束输入。用指针指向一
24、个学生成绩数组,并求出这些成绩的平均值(要求用指针指向数组元素来实现)。解:(1)程序分析:设一个浮点型数组grade,数组长度为20,一个浮点型指针p,一个浮点型变量sum用于存放成绩之和,一个整型变量num用于存放输入的成绩个数,一个整型变量classes为数组实际下标值。当输入值大于0时用do-while语句循环读入每个成绩gradeclasses,然后将p指针指向该数组grade首地址,令num=classes-1得到数组最大元素下标值,使用for循环语句计算出该数组中各学生成绩的总和存入sum中,在循环体中使用指针p来表示各数组元素。最后输入sum/num的值即为输入各成绩的平均值。
25、,返回本讲目录,返回本讲目录,点击打开【练习5-2】源程序。程序运行结果如下:,返回本讲目录,返回本讲目录,第十三讲 字符指针、指针数组、指向指针的指针和常用字符串处理函数,一、字符指针和字符串二、指针数组和指向指针的指针三、常用字符串处理函数练一练,返回本章目录,一、字符指针和字符串,【实例5-7】阅读下面的程序,分析并写出程序的运行结果。解:程序分析:第6行语句定义了一个字符型数组str,并将该数组赋初值为Hello,第7行语句定义一个字符型指针p,也为其赋初值为people,这时系统会自动为该字符串新开辟一个空间,并将指针p指向该字符串的首地址,即指向字符p。第8、9行语句为两条输出流,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第五 构造 数据类型
链接地址:https://www.31ppt.com/p-5665911.html