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