《C语言程序设计-第9章.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计-第9章.ppt(27页珍藏版)》请在三一办公上搜索。
1、C语言程序设计,贵阳市新科电脑培训中心 唐绍国 制作,全国计算机等级考试 二级教程,第九章 数组,本章要点:一维数组的定义和一维数组元素的引用一维数组和指针函数之间对一维数组和数组元素的引用二维数组的定义和二维数组元素的引用二维数组和指针二维数组名和指针数组作为实参,什么是数组?,数组是按次序排列的一组数据,用一个统一的数组名标识这一数组,而用下标来指示数组中元素的序号。在数组中所有的数组元素都具有相同的数据类型。在c语言中,数组属于构造数据类型。一个数组可以分解成多个数组元素,这些数组元素可以是基本数据类型或是构造类型。按数组元素的不同,可分为数值数组、字符数组、指针数组、结构数组等各种类型
2、。,一维数组的定义,当数组中每个元素只带有一个下标时,称这样的数组为一维数组。一维数组的定义形式如下:类型名 数组名常量表达式,;,一维数组说明符,例如:int a8;说明:Int是类型名,a8是一维数组说明符。经过以上定义后,c编译程序将为a数组在内存中开辟8个连续的存储单元。在程序中,我们可以通过数组名加下标的方式去引用每一个存储单元。比如:引用第5个元素的方法为:a4,一维数组元素的引用,一维数组只带有一个下标,它的引用形式如下:数组名下标/*下标可以是表达式*/例如:double x8;/*定义了一个双精度型数组,有8个元素*/则:x3或xi+3都是合法的引用形式。数组概念的相关解释:
3、1、一个数组元素实际上就是一个变量名,代表内存中的一个存储单元。一个数组占有一串连续的存储单元。2、在c语言中,一个数组不能整体引用。在c语言中,数组名中存放的是一个地址常量,它代表整个数组的首地址。3、在引用数组元素时,数组元素中下标表达式的值必须是整数,它的下限为0。在编写程序时保证数组下标不越界是十分重要的。,一维数组的初始化,1、在定义数组的同时为数组元素赋初值例:int a8=0,1,2,3,4,5,6,7;注意:所赋初值放在赋值号后的一对花括号中,数值类型必须与所说明的类型相一致,所赋初值之间用逗号分隔,系统将按这些数值的排列顺序,从a0元素开始依次给a数组中的元素赋初值。以上语句
4、将给a0赋初值0,给a1赋初值1,给a7赋初值7。在指定初值时,第一个初值必定赋给下标为0的元素,因此,不可能跳过前面的元素给后面的元素赋初值。当所赋初值少于所定义的元素的个数时,将自动给后面的元素赋以初值0。例如:int a10=0;该语句将给a数组中的所有元素赋初值0。对于字符型数组同样补以初值0,即0。例如:char c5=;相当于:char c5=,0,0,0,0,通过赋初值确定数组的大小,例如:int a=0,0,0,0,0,0,0,0;以上语句的一对花括号中出现了8个0,它隐含地定义了a数组含有8个元素,此定义语句等价于以下语句:Int a8=0;,通过循环来赋值,例:main()
5、int a10;int i;for(i=0;i10;i+)ai=2*i-1;printf(“%4d”,ai);,一维数组和指针,一维数组和数组元素的地址在c语言中,在函数体中或在函数外部定义的数组名可以认为是一个存放地址值的指针变量名,其中的地址值是数组第一个元素的地址,也就是数组所占一串连续存储单元的起始地址;定义数组时的类型即是此指针变量的基类型数组名所代表的指针变量中的地址是不可改变的,也就是说,不可以给数组名重新赋值。一旦定义,a永远指向a数组的首地址。例:若有以下定义:int a10,*p,x;语句a=或a+都是非法的。,在c语言中,虽然不可以改变数组名a中的内容,但可以通过对数组名
6、加一个整数的办法,来依次表达该数组中不同元素的地址。例如:(假定已定义k为整型变量);for(k=0;k10;K+)p=a+k;在循环中并没有改变a的值,但通过表达式:a+k,逐一给出了a数组中每个元素的地址,使p依次指向a数组中的每一个元素。,由于scanf函数要求给出输入项的地址值,因此,可以通过以下循环从终端读入数据依次放入a数组中:for(k=0;k10;k+)scanf(“%d”,a+k);语句p=都是合法的。这两条语句的功能相同,都是使指针变量p指向了a数组的首地址。,以下循环中,由于在进入循环时使指针变量p指向了a数组的首地址,p+将使指针变量p依次指向a数组中的每一个元素。fo
7、r(p=a,k=0;k10;k+)p+;因此,以下循环也可以将从终端读入的数据依次放入a数组中:for(p=a,k=0;k10;k+)scanf(“%d”,p);p+;)可以进一步简化写成:for(p=a,k=0;k10;k+)scanf(“%d”,p+);还可以进一步简化写成:for(p=a;p-a10;p+)scanf(“%d”,p);,通过数组的首地址引用数组元素,a是a数组元素的首地址,a(即a+0)的值即等于,通过指针来引用一维数组元素,若有以下定义:Int a10,*p;Int k;并执行语句:p=a;或p=,用带下标的指针变量引用一维数组元素,若有以下定义和语句:int*p,s1
8、0,I;p=s,且0i10,我们已经知道,可以使用&si、s+i和p+i三种表达式来表示si的地址。同时可以用si、*(s+i)和*(p+i)三种表达式来表示数组元素si。很明显,si可以用表达式*(s+i)来表示,则同理,*(p+i)也应该可以用pi的形式来表示。事实上,在C语言中,方括号不是仅用来表示数组元素的记号,而是一种运算符。因此,当p指向s数组的首地址时,表示数组元素si的表达式应当有:(1)si(2)*(s+i)(3)*(p+i)(4)pi共四种形式。但在这里,s和p有着明显的区别,s是不可变的,而p中的地址值却是可变的。因此,s+、s=p,p=&s等都是非法的。而p+、p=s、
9、p=&si则都是合法的表达式。,函数之间对一维数组和数组元素的引用,数组元素作实参当调用函数时,数组元素可以作为实参传递给形参,每个数组元素实际上代表内存中的一个存储单元,故和普通变量一样,对应的形参必须是类型相同的变量。数组元素的值可以传送给该变量,在函数中只能对该变量进行操作,而不能直接引用对应数组元素。数组名作实参数组名也可以作为实参传送,但数组名本身是一个地址值,因此,对应的形参就就应当是一个指针变量,此指针变量的基类型必须与数组的类型一致。在函数中,可以通过此指针变量来引用调用函数中对应的数组元素,从而达到对调用函数中对应的数组元素进行操作。,形参的几种写法,当数组名作为实参时,对应
10、的形参除了应该是指针外,形参还可以用另外两种形式。(1)arrin(int*a);(2)arrin(int aM);(3)arrin(int a);虽然说明的形式不一样,但C编译程序都将把a处理成指针。,函数的指针形参和函数体中数组的区别,(1)指针形参:程序只为指针形参分配一个存储单元;却要为数组分配多个连续的存储单元。(2)指针形参是一个指针变量,可以重新改变它的指向,而数组名是一个指针常量,一旦定义,它就永远指向了该数组的首地址。(3)指针形参和数组都是函数中的内部变量,使用到的时候才为它们临时开辟存储单元,使用完后要释放掉其所占用的存储空间.,二维数组的定义和二维数组元素的引用,当二维
11、数组中每个元素带有两个下标时,称这样的数组为二维数组。在逻辑上,可以把二维数组看成是一个具有行和列的表格或一个矩阵。二维数组的定义:类型名 数组名常量表达式1常量表达式2;二维数组说明符中必须有用两个方括号括起来的常量表达式,常量表达式的值只能是正整数。可以把“常量表达式1”看成是矩阵(或表格)的行数,它决定了第一维下标值的上限为“常量表达式1”-1;可以把常量表达式2看成是矩阵(或表格)的列数,它决定了第二维下标值的上限为:“常量表达式2”-1。例如有以下定义:Int a34;在这里,int 是类型名,a34是一个二维数组说明符。可以认为此语句说明了:(1)定义了一个名为a 的二维数组。(2
12、)a数组中每个元素都是整型。(3)a数组中共有34个元素。(4)a数组的逻辑结构是一个具有3行4列的矩阵(或表格)。,二维数组的引用,引用二维数组时必须带有两个下标。引用形式如下:数组名下标表达式1下标表达式2例:double w42;则w01、wij、wi+ki+k都是合法的数组元素引用形式,只是每个下标表达式的值必须是整数,且不得超过数组定义中的上、下界。注意:引用二维数组时,一定要把两个下标分别放在两个方括号内。例如,引用以上w数组时,不可以写成:w0,1、wi,j、wi+k,j+k,这都是不合法的。,二维数组的初始化,1、所赋初值个数与数组元素的个数相同,按对应关系存放2、每行所赋初值
13、个数少于数组元素个数时,系统自动给后面的元素赋初值03、所赋初值行数少于数组行数,系统自动给后面各行补初值04、赋初值时省略行花括号,系统将按数组元素在内存中的排列顺序,将花括号中的数据一一对应地赋给各个元素,若数不足,系统将给后面的元素补以初值0,通过赋初值确定数组的大小,对于一维数组,可以在数组定义语句中省略方括号中的常量表达式,通过所赋初值的个数来确定数组的大小;对于二维数组,只可以省略第一个方括号中的常量表达式,而不能省略第二个括号中的常量表达式。这时,第一维的大小按以下规则决定:1)当初值的个数能被第二维的常量表达式的值除尽时,所得商 数就是第一维的大小。2)当初值的个数不能被第二维
14、的常量表达式值除尽时,则:第一维的大小=所得的商数+1。,通过地址来引用二维数组元素,若有以下定义:int a34,i,j;且0i3;0j4则数组元素可用以下五种表达式来引用。(1)aij(2)*(ai+j)(3)*(*(a+i)+j)(4)(*(a+i)j(5)*(&a00+4*i+j),通过建立一个指针数组来引用二维数组元素,若有以下定义:int*p3,a32,I,j;则可以通过以下形式引用aIj:(1)*(pI+j)/*与*(aI+j)对应*/(2)*(*(p+I)+j)/*与*(*(a+I)+j)对应*/(3)(*(p+I)j/*与(*(a+j)j对应*/(4)pIj/*与aIj对应*
15、/,通过建立一个行指针来引用二维数组,若有以下定义:int a32,(*prt)2;在这里,说明符(*prt)2中,由于一对圆括号的存在,所以*号首先与prt 结合,说明prt是一个指针变量,然后再与说明符2结合,说明指针变量prt的基类型是一个包含有两个int元素的数组。在这里,prt的基类型与a的相同,因此prt=a;是合法的赋值语句。prt+1等价于a+1、等价于a1。当prt指向数组的开头时,可以通过以下形式来引用aIj:(1)*(prtI+j)/*与*(aI+j)对应*/(2)*(*(prt+I)+j)/*与*(*(a+I)+j)对应*/(3)(*(prt+I)j/*与(*(a+I)j对应*/(4)prtIj/*与aIj对应*/在这里,prt是个指针变量,它的值可变,而a是一个指针常量。,二维数组和指针,1、二维数组实际上是一个一维数组,这个一维数组的每一个成员又是一个一维数组。2、二维数组名是一个地址常量,其值为二维数组中第一个元素的地址。注意:二维数组名表示的指针,它的基类型并不是数组本身的类型,而应该是数组类型。所以,二维数组名应理解为行指针。3、二维数组元素的地址可用以下五种表达式来得到:(1)&aij(2)ai+j(3)*(a+i)+j(4)&a00+4*i+j(5)a0+4*i+j,本章完祝大家学有所成!Thanks!,