C语言程序设计课件第10章myself
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
部分联合表示 此处的括号 因此,接受二维数组指针的指针变量,其基类型也应 对应于二维数 一定要有! 对应于二维 组元素类型 该由两部分联合表示,而且对应的部分完全一致,这 数组的列数 样的指针变量称为行指针变量
•还可以:p=a+i或p=&a[i],保证p 例:int (*p)[3]; //二级指针变量p 得到的是行指针都是正确的 • int a[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; • p=a; //将二维数组指针赋值给行指针变量 • 此时行指针变量p等价于二维数组指针a,有以下等价式: • p+i= =a+i p[i]= =a[i] p[i][j]= =a[i][j]
2013-9-3 19
一维指针数组与二维数组
一维指针数组是元素为一级指针变量的一维数组。每
一个一级指针变量可以分别指向长度不同、且彼此空 间不相邻的一维数组。 二维数组是元素为一级指针常量的一维数组。每一个 指针常量分别指向长度相同、彼此空间相邻的一维数 组,例:
• char cColor[4][7]={“white”,”red”,”orange”,”pink”}; • char *pColor[4]= {“white”,”red”,”orange”,”pink”}; • cColor是二维数组,其元素为cColor[0]~cColor[3],它们 都是长度为7的字符型一维数组,且在内存中连续存放 • pColor是一维指针数组,其元素为pColor[0]~pColor[3], 它们都是一级指针变量,可以指向各独立存放的串首地址
C语言程序设计
1 2013-9-3
第十章 二维数组与指针
主讲: 计算机学院 俞琼
2 2013-9-3
内容提要
本章介绍二维数组的有关知识: • 二维数组的定义,其中涉及的3种类型 • 二维数组的初始化 • 二维数组的元素访问方式 与二维数组相关的各类指针: • 行指针 • 列指针 • 二级指针 • 一维指针数组 动态二维数组空间的申请与释放(选讲) • 如何利用二级指针申请动态二维数组空间 • 如何依次释放申请的所有动态空间
2013-9-3 16
寻找矩阵中的马鞍点。一个矩阵中的元素, 若在它所在的行中最小,在它所在的列中最大,则称 为马鞍点。求一个n*m阶矩阵的所有马鞍点。
动 过 演示 态 程
一维指针数组与二级指针
如果指针变量中保存的是另一个指针变量的地址,这 样的指针变量就称为指向指针的指针(Point to Pointer),指向指针的指针实际上是一种多级指针, 实质就是多级间接寻址。 指向指针的指针的定义格式:
2013-9-3
5
二维数组的定义
二维数组定义中的常量与变量: • 例:int a[2][3]; • (1)二维数组a和行一维数组a[0]~a[3]均为指针常量 • (2)二维数组元素a[0][0]~a[1][2]是int型的变量
2013-9-3
6
二维数组的初始化
二维数组在定义的同时可为其元素赋值,称为初始化, 每行单独用一 共有两层大括号 对大括号括起 原则:行从左到右依次,每行中列从左到右依次 • (1)逐行初始化: • 行数计算出来为4,不初始化时不能缺少行数 int a[4][3]={{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 a[4][3]={1,2,3,4,5,6,7,8,9,10,11,12}; • (4)初始化数据不足,系统用0补充: • int a[4][3]={{1,2},{4,5},{7,8,9},{10,11,12}}; • (5)最简单的初始化: int a[4][3]={0}; 等效于int a[4][3]={{1,2,0},{4,5,0},{7,8,9},{10,11,12}}; 第1个元素初始化为0,其余未 7 初始化的元素值自动为0 2013-9-3
2013-9-3 3
二维数组的定义
二维数组的定义形式: 类型 数组名[整型常量表达式1][整型常量表达式2];
例:int a[2][3];//定义2行3列的整型二维数组,数组名为 a a[0]--- a[0][0]、a[0][1]、a[0][2]
a
a[1]--- a[1][0]、a[1][1]、a[1][2]
2013-9-3
4
二维数组的定义
二维数组的实质分析: • (1)这里,a是二维数组名,也可以理解成是一维数组名a, 它有2个元素,分别为a[0]、a[1] • (2)a的2个元素不是普通的变量,而是都分别是一维数组, 称为行一维数组,每一个都有3个int型元素,例:a[0]的3 个元素为:a[0][0]、a[0][1]、a[0][2] • (3)因此,二维数组a中共有6( 2*3 )个int型的元素: • (4)存放顺序:以行优先方式存放。先顺序存放第0行的元 素再存放第1行的元素,以此类推。
2013-9-3 14
动 过 演示 态 程
二维数组与列指针
二维数组的列指针——普通的一级指针
int a[2][3],*p; p = *a; /*用列地址初始化
等价于p=a[0];
列下标 行下标 列数 • p[i*3+j]=a[i][j]
*/
这样,二维数组也可以通过将其起始列地址传给一个 一级指针变量来访问所有的元素
程序10.1 将如下所示的矩阵存入二维数组,然后照 原样输出,最后按转置形式输出。
• 算法提示:转置输出不需要另外定义二维数组,只是在控制循 环时先控制列下标再控制行下标
2013-9-3 11
动 过 演示 态 程
二维数组与行指针
二维数组要传址,可以传递二维数组指针
二维数组指针的基类型由二维数组元素类型和列数两
&a[1][0] a[1]+0 &a[1][1] a[1]+1 &a[1][2] a[1]+2
a+1
a[1][1]
a[1][2]
二维数组元素可随机访问,因为每个元素地址可计算 Loc(a[i][j])=a+(i*m+j)*sizeof(二维数组元素类型)
2013-9-3 9
数组元素的几种等价引用形式 一维int a[2]
变量c
&b
变量b &b
&a
变量a
&a
5
*c
*b **c
printf(“a=%d,*b=%d,**c=%d\n”,a,*b,**c); *b=10; printf(“a=%d,*b=%d,**c=%d\n”,a,*b,**c); **c=100; printf(“a=%d,*b=%d,**c=%d\n”,a,*b,**c); 18 }2013-9-3
一维指针数组与二级指针
元素均为指针类型数据的数组,称为指针数组 定义形式为: 类型标识符 *数组名[数组长度]; 例:char* a[5];
• a是长度为5的一维字符型指针数组,a是指针常量,一维数 组元素a[0]、a[1]、a[2]、a[3]、a[4]都是一级字符型指 针变量,它们各自可以指向一维字符数组,特别是字符串 • 对每个元素(一级指针变量)都可以赋值:a[0]="File"; a[1]="Edit"; a[2]="Compile"; a[3]="Run"; a[4]="Tools"; • 也可以在定义一维指针数组时进行初始化,如普通一维数组 • char* a[5]={"File","Edit","Compile","Run","Tools"}; • 或char* a[]={"File","Edit","Compile","Run","Tools"};
行变列,加*号; 列变行,加&号; 只在0列可变行
2013-9-3
10
二维数组元素的访问
一般要对所有的数组元素执行同样的操作,与一维数
组类似,用循环结构控制,二维数组需用两层循环
• 例:int a[4][3],n=1;
• for(int i=0;i<4;i++) • for(int j=0;j<3;j++) • a[i][j]=n++;
注意:此题的函数原型可以有以下三种等效表示: • (1)void Display( int (*pa)[3],int row); • (2)void Display( int pa[][3],int row); • (3)void Display( int pa[4][3],int row); • 后两种本质上就是第一种形式,且后两种形式只能出现在形 参表中,不能作为行指针变量的定义(或声明)形式
2013-9-3 12
二维数组的行指针表示指向的一 括号不能少
二维数组的行指针定义方法 类型关键字 (*行指针名)[常量N]; 例:int a[2][3],(*p)[3];
维数组的长度
p = a; /*用行地址初始化 */ p 先逐行查找元素所在行, p+1则使p 指针向下移动一行int型数据占用的字节数,此 例中为3*sizeof(int) 再在行内逐列查找元素所在位置, P+1 *(p+1)+1&a[1][1]
• 元素地址(a+i),&a[i] • • • • 元素 a[i] •
0≤i 二维数组元素的访问0 ≤j <2 <3
二维int a[2][3];
行地址 (a+i),&a[i] 列地址 *(a+i),a[i] 元素地址 *(a+i)+j a[i]+j a[i][j], *(*(a+i)+j), *(a[i]+j),(*(a+i))[j]
2013-9-3
15
二维数组与列指针
程序10.6
• 算法思想:用一个 n行m列二维数组a来存储矩阵,一个长 度为n的一维数组min存储每行中的最小元素,一个长度为m 的一维数组max存储每列中的最大元素。 • 寻找马鞍点的具体方法是:用行控制外层循环,在i行其行 中最小元素为min [i],在行固定的情况下,用列控制内层 循环,用每一列的最大元素值max[j]与当前行的min[i]去 比较,如果二者相等,则说明一个二维数组元素a[i][j]就 是马鞍点。 • 显然,一个矩阵中可能不止一个马鞍点,也有可能没有马鞍 点。马鞍点元素加括号输出。
2013-9-3 8
二维数组元素的访问
a[0]
a[1]
a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]
a[0]+0 &a[0][1] a[0]+1 &a[0][2] a[0]+2
&a[0][0]
a
a[0][0] a[0][1] a[0][2] a[1][0]
• 类型关键字 **指针变量名; • 以上定义可理解为: 类型关键字 *(*指针变量名);
通过指向指针的指针访问目标值时,必须用双星号**。
2013-9-3
17
一维指针数组与二级指针
#include <stdio.h> void main( ) { int a=5; int *b=&a; int **c=&b;
二维数组的初始化
第1行没有初始化,后 错误的初始化示例: 面行就不能初始化 第1行第2列没有初始化, 第2行第1列没有初始化,第 • (1)未遵守行从左至右依次初始化原则: 第3列就不能初始化 2、3列就不能初始化 • int a[4][3]={ ,{4,5,6},{7,8,9},{10,11,12}}; 中间缺少两个元素,不符合 • (2)同一行中未遵守列从左至右依次初始化原则: 从左到右依次的原则 • int a[4][3]={{1, ,3},{4,5,6},{7,8,9},{10,11,12}}; 二维数组初始化中列 • int a[4][3]={{1,2,3},{,5,6},{7,8,9},{10,11,12}}; 号一定不能省略 • (3)不分行,用类似一维数组的方式初始化,未按顺序: • int a[4][3]={1,2, ,4, ,6,7,8,9,10,11,12} ; • (4)省略列号: • int a[4][ ]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
a[0][0] a[0][1]
a[பைடு நூலகம்][2]
a[1][0] a[1][1]
a[1][2]
2013-9-3 13
二维数组与行指针
程序10.5 将给定矩阵按转置形式输出。 • 本程序与程序10.2功能类似,但作了简化,二维数组元素 初始化给定,不需要输出原始矩阵。 • 本程序用Display函数实现矩阵转置输出 • 重点理解如何用行指针变量作为形参接受二维数组实参。