c语言程序设计课件第10章-二维数组的地址和指针_第1页
c语言程序设计课件第10章-二维数组的地址和指针_第2页
c语言程序设计课件第10章-二维数组的地址和指针_第3页
c语言程序设计课件第10章-二维数组的地址和指针_第4页
c语言程序设计课件第10章-二维数组的地址和指针_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

高级 语言程序设计 *1*2第 十 章 二维数组与指针主讲 : 计算机学院 朱立华内容提要n 本章介绍二维数组的有关知识: 二维数组的定义 ,其中涉及的 3种类型 二维数组的初始化 二维数 组的元素访问方式n 与二维数组相关的各类指针: 行指针 列指针 二级指针 一维指针数组n 动态二维数组空间的申请与释放 (选讲 ) 如何利用二级指针申请动态二维数组空间 如何依次释放申请的所有动态空间Date 3二维数组的定义n 哪里需要二维数组? 类型相同的一组数 ,如果在序列中 只受一种序号标明 其在整个序列中的顺序 ,用 一维数组 ,例如 :1门课各个同学的成绩 类型相同的一组数 ,如果在序列中需要用 两种序号标明 其在整个序列中的顺序 ,则要用 二维数组 ,例如 :3门课各个同学的成绩 矩阵问题强调元素所在的行、列位置 ,必须用 二维数组n 二维数组的定义形式: 类型标识符 数组名 整型常量表达式 1 整型常量表达式 2; 例: int a43; /定义 4行 3列的整型二维数组,数组名为 a 二维数组的元素类型二维数组名是一个用户自定义标识符指明二维数组的行数指明二维数组的列数Date 4二维数组的定义n 二维数组的实质分析: 二维数组是 一维数组的一维数组(递归定义) 例: int a43; (1)这里, a是二维数组名 ,也可以理解成是 一维数组名 a,它有 4个元素,分别为 a0、 a1、 a2、 a3 (2)a的 4个元素不是普通的变量,而是都分别是一维数组,称为 行一维数组 ,每一个都有 3个 int型元素 ,例: a0的 3个元素为 :a00、 a01、 a02 (3)因此,二维数组 a中共有 12( 4*3) 个 int型的元素: a00、 a01、 a02 a10、 a11、 a12 a20、 a21、 a22 a30、 a31、 a32它们 4个称为行一维数组第 1个下标称为行下标第 2个下标称为列下标这 12个元素称为二维数组元素行数 列数Date 5二维数组的定义n 二维数组定义中含有 3种类型 : 例: int a43; ( 1) int 43:是二维数组 a的类型标识 ( 2) int 3: 是行一维数组 a0a3的类型标识,也是二维数组的基类型 ( 3) int:是二维数组元素 a00a32的类型,也是行一维数组的基类型n 二维数组定义中的 常量与变量 : 例: int a43; ( 1)二维数组 a和行一维数组 a0a3均为 指针常量 ( 2)二维数组元素 a00a32是 int型的 变量Date 6二维数组的初始化n 二维数组在定义的同时可为其元素赋值,称为初始化,原则:行从左到右依次,每行中列从左到右依次 ( 1) 逐行初始化 : int a43=1,2,3,4,5,6,7,8,9,10,11,12; ( 2) 行数可以缺省,列数不能省,自动算行 : int a 3=1,2,3,4,5,6,7,8,9,10,11,12; ( 3) 不分行,用类似一维数组的方式初始化 : int a43=1,2,3,4,5,6,7,8,9,10,11,12; ( 4) 初始化数据不足,系统用 0补充: int a43=1,2,4,5,7,8,9,10,11,12; ( 5) 最简单的初始化 : int a43=0; 每行单独用一对大括号括起 共有两层大括号只有一层大括号等效于 int a43=1,2,0,4,5,0,7,8,9,10,11,12;第 1个元素初始化为 0,其余未初始化的元素值自动为 0行数计算出来为 4,不初始化时不能缺少行数Date 7二维数组的初始化n 错误的初始化示例 : ( 1) 未遵守行从左至右依次初始化原则 : int a43= ,4,5,6,7,8,9,10,11,12; ( 2) 同一行中未遵守列从左至右依次初始化原则 : int a43=1, ,3,4,5,6,7,8,9,10,11,12; int a43=1,2,3,5,6,7,8,9,10,11,12; ( 3) 不分行,用类似一维数组的方式初始化,未按顺序 : int a43=1,2, ,4, ,6,7,8,9,10,11,12 ; ( 4) 省略列号 : int a4 =1,2,3,4,5,6,7,8,9,10,11,12;中间缺少两个元素,不符合从左到右依次的原则第 1行没有初始化,后面行就不能初始化 第 1行第 2列没有初始化,第 3列就不能初始化第 2行第 1列没有初始化,第2、 3列就不能初始化二维数组初始化中列号一定不能省略Date 8二维数组元素的访问a00 a01 a02 a10 a11 a12 a20 a21 a22 a30 a31 a320i 30 j 2a0 a1 a2 a3 二 维 数 组 元素可随机 访问 ,因 为 每个元素地址可 计 算Loc(aij)=a+(i*m+j)*sizeof(二 维 数 组 元素 类 型)n 数组元素的表示形式: 例: int a43; ( 1)最常用的是下标(行、列)法 : aij ( 2)间接引用法与下标法结合 : *(ai+j)、 ( *(a+i))j ( 3)间接引用法 : *(*(a+i)+j)n 二维数组元素在内存中的存储形式 :先行后列依次行下标 列数 列下标Date 9二维数组元素的访问n 一般要对所有的数组元素执行同样的操作,与一维数组类似,用循环结构控制,二维数组需用两层循环 例: int a43,n=1,i,j; for(i=0;i4;i+) for(j=0;j3;j+) aij=n+;n 程序 10.1 将如下所示的矩阵存入二维数组,然后照原样输出,最后按转置形式输出。 算法提示 :转置输出不需要另外定义二维数组 ,只是在控制循环时先控制列下标再控制行下标动态 演示过程Date 10二维数组与一维数组n 二维数组名 是 二维数组指针 常量n 如果按照递归的概念 ,它也是特殊的一维数组指针 例: int a43; (1)指针 a的基类型为 int3,a指向 a0,即 a= =n 这里指针 d的基类型为 double,而指针 ( /行指针变量 p int a43=1,2,3,4,5,6,7,8,9,10,11,12; p=a; /将二维数组指针赋值给行指针变量 此时行指针变量 p等价于二维数组指针 a, 有以下等价式: p+i= =a+i pi= =ai pij= =aij 对应于二维数组元素类型 对应于二维数组的列数还可以: p=a+i或 p= ( 2) void Display( int pa3,int row); ( 3) void Display( int pa43,int row); 后两种本质上就是第一种形式,且后两种形式只能出现在形参表中,不能作为 行指针变量 的定义(或声明)形式 动态 演示过程Date 16二维数组与列指针n 一个 m行 n列二维数组,可以看作是长度为 m*n的一维数组 ,因此二维数组可以 传址给列指针 例: int a43; 则 a0(或 *a或 则 pi*3+j=aij n 这样, 二维数组也可以通过将其起始列地址传给一个一级指针变量来访问所有的元素行下标 列数 列下标Date 17二维数组与列指针n 程序 10.6 寻找矩阵中的马鞍点。一个矩阵中的元素,若在它所在的 行中最小 ,在它所在的 列中最大 ,则称为马鞍点。求一个 n*m阶矩阵的所有马鞍点。 算法思想: 用一个 n行 m列二维数组 a来存储矩阵,一个长度为 n的一维数组 min存储每行中的最小元素,一个长度为 m的一维数组 max存储每列中的最大元素。 寻找马鞍点的具体方法是: 用行控制外层循环,在 i行其行中最小元素为 min i,在行固定的情况下,用列控制内层循环,用每一列的最大元素值 maxj与当前行的 mini去比较,如果二者相等,则说明一个二维数组元素 aij就是马鞍点。 显然, 一个矩阵中可能不止一个马鞍点,也有可能没有马鞍点。马鞍点元素加括号输出。动态 演示过程Date 18一维指针数组与二级指针n 所谓 一维指针数组, 就是数组元素为 一级指针变量 的一维数组。 例: char* a5; a是长度为 5的一维字符型指针数组, a是指针常量 ,一维数组元素 a0、 a1、 a2、 a3、 a4都是一级字符型指针变量,它们各自可以指向一维字符数组,特别是字符串 对每个元素(一级指针变量)都可以赋值 : a0=“File“; a1=“Edit“; a2=“Compile“; a3=“Run“; a4=“Tools“; 也可以在定义一维指针数组时进行初始化,如普通一维数组 char* a5=“File“,“Edit“,“Compile“,“Run“,“Tools“; 或 char* a=“File“,“Edit“,“Compile“,“Run“,“Tools“;注意: 此处不能加括号:而char(*a)5是 1个行指针定义Date 19一维指针数组与二级指针n 一维指针数组名可以赋值给何种类型的变量? 回顾: 一级指针变量与一维数组的关系 Type arraysize; /数组 array的元素类型为 Type ,即数组指针的基类型为 Type Type* p; /指针变量 p的基类型为 Type 因此: p=array; /指针变量 p指向数组 array 如果有指针数组定义 : char* a5,则数组 a的元素类型是char*,即数组指针常量 a的基类型是 char*, 则接受 a值的指针变量的基类型也应该是 char*, 故该指针变量类型是char*,称为(字符型) 指针的指针 ,也称 二级指针 于是: char *pa=a; 这时, pai与 ai等效 ,都是指向某一个字符串的首地址pa为二级指针变量a为一维指针数组名Date 20一维指针数组与二级指针n 程序 10.7 主函数中定义指针数组处理多个字符串,函数以 指针的指针为形参 输出所有字符串的值。 输出函数原型 : void Display( char* pa,int n); 另一种形式 : void Display(char* pa ,int n);n 二级指针、一级指针与普通变量的关系: 例 : char ch=A; /定义一个普通字符型变量 char* p= /一级指针变量 p指向了变量 ch char* q= /二级指针变量 q指向了一级指针 p 则对字符值的访问形式有等效的 3种形式: ch、 *p、 *q,如下图所示动态 演示过程这种形式的形参本质上就是 char* paq p ch0x12ff78 0x12ff7c A char *pColor4= “ white”,”red”,”orange”,”pink ”; cColor是二维数组,其元素为 cColor0cColor3,它们都是 长度为 7的字符型一维数组 ,且在内存中连续存放 pColor是一维指针数组,其元素为 pColor0pColor3,它们都是 一级指针变量 ,可以指向各独立存放的串首地址Date 22一维指针数组与二维数组w h i t e 0r e d 0o r a n g e 0p i n k 0cColorcColor0cColor1cColor2cColor3pColorpColor0pColor1pColor2pColor3white0red0orange0pink0这 4个字符串长度相等地址相邻这 4个字符串长度不相等地址不一定相邻多个字符串的处理,既可以用二维字符数组,又可以用一维指针数组,后者是更常用的处理方式。 Date 23一维指针数组与二维数组 n 指针数组的每一个元素作为指针变量,可以指向二维数组的行数组,当然,要保证基类型的一致性。n 前面的例示中,可以用以下循环实现赋值:n for (i=0;i4;i+)n pColori=cColori; n 程序 10.8 指针数组和二维数组。 用二维整型数组存储一个矩阵,通过一维指针数组输出矩阵n 指针数组的元素是指针变量,不仅可以指向静态数组n 也可以指向动态数组 例: int* p4, i; for (i=0;i4;i+) pi=(int*)malloc(3*sizeof(int); 动态 演示过程Date 24二维动态空间的申请与释放( 选讲 )n 一级指针可以申请动态一维数组空间,同理, 二级指针可以申请动态二维数组空间 ,需要分两步走:n 用二级指针申请动态二维数组的方法是: ( 1)首先用二级指针申请一维指针数组空间,指针数组的长度就是动态二维数组的行数; ( 2)接着用这些一级指针变量分别申请动态一维数组空间,其元素个数就是动态二维数组的列数。n 释放动态二维数组空间的方法是 (与申请顺序相反 ): ( 1)用一层循环首先释放所有由一级指针所申请的动态空间 先释放二维数组元素空间 ( 2)再直接通过二级指针变量释放一维指针数组空间 后释放一维指针数组的空间Date 25array00 array01 array02二维动态空间的申请与释放( 选讲 ) n 程序 10.9 通过二级指针变量 array申请了 row行 col列的动态二维数组空间,二维数组的元素为 099之间的随机数。最后以矩阵形式输出该动态二维数组。 关键语句: int *array, row,col; array=(int *)malloc(row*sizeof(int *); for (i=0;irow;i+) arrayi=(int *)malloc(col*sizeof(int); 现在: arrayij就与静态数组元素一样进行访问了动态 演示过程申请一维指针数组空间 ,该数组含 row个元素再用这 row个一级指针分别申请col个二维数组元素空间arrayarray0array1array10 array11 array12若 row=2,一维指针数组空间 ,该数组含 2个一级指针元素若 col=3,这是 array0申请的一维整型数组 ,该数组含 3个 int型元素若 col=3,这是 array1申请的一维整型数组 ,该数组含 3个 int型元素这 6个便是用二级指针申请的动态二维数组元素Date 26二维(数组)指针和一维(数组)指针的相互转化 下表总结了第 5章所讲的一级指针与一维数组、本章所讲的行列指针与二维数组,指针数组及指针的指针之间的关系。指 针 名称 指 针 定 义举 例 数 组 定 义举例可 进 行的 赋值 基 类 型一 级 指 针(列指 针 )int *p; int a10;int m=2;int a43;p=a; p=a+i; p=p=p= p=ai;p=*(a+i);int行指 针 int (*p)3; int a43;int arr3;p=a; p=a+i; p=p=int3二 级 指 针 int *p; int *a3; p=a; p=a+i; p= int *指 针 数 组 int *p

温馨提示

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

评论

0/150

提交评论