全国计算机二级C语言ppt课件-第9章-数组_第1页
全国计算机二级C语言ppt课件-第9章-数组_第2页
全国计算机二级C语言ppt课件-第9章-数组_第3页
全国计算机二级C语言ppt课件-第9章-数组_第4页
全国计算机二级C语言ppt课件-第9章-数组_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

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

文档简介

本章要点:9.1一维数组的定义和一维数组元素的引用9.2一维数组和指针9.3函数之间对一维数组和数组元素的引用

9.4一维数组应用举例9.5二维数组的定义和二维数组元素的引用9.6二维数组和指针9.7二维数组名和指针数组作为实参第9章数组1本章要点:第9章数组19.1一维数组的定义和一维数组元素的引用29.1一维数组的定义和一维数组元素的引用2当数组中每个元素只带有一个下标时,称这样的数组为一维数组。一维数组的定义方式为:类型名数组名[常量表达式];例如:intarray[10];它表示定义了一个名为array的数组,此数组有10个元素,每个元素的数据类型为整型。9.1.1一维数组的定义39.1.1一维数组的定义3一维数组定义的说明:1.类型名用来说明数组元素的数据类型,可以是以前介绍过的任一种数据类型。2.数组名由用户指定,命名规则和变量名相同,遵循标识符定义规则。3.常量表达式规定了数组元素的个数,即数组的长度。整个数组所占字节数=类型长度×数组长度。4.常量表达式中不能包括变量,即C语言不允许定义动态数组。5.常量表达式中可以包括常量和符号常量。4一维数组定义的说明:46.每个数组元素只有一个下标,C语言规定数组第一个元素的下标总为0(称为数组的下界)。7.定义数组后,C编译程序即为该数组在内存中开辟相应个数的存储单元,每个存储单元可以直接用相应的数组元素表示。8.数组定义中,数组长度除多数情况下作显式说明外,有两种情况下不必或不能用长度说明,而用[]代替。(1)给数组全体元素赋初值时,可省去数组长度说明。(2)数组名作为函数的参数,在函数的参数说明部分,当指出参数是数组时,不能用长度说明。56.每个数组元素只有一个下标,C语言规定数组第一个元素的下标除了给指针变量赋地址值外,还可以给指针变量赋NULL值。例如:p=NULL;NULL是在stdio.h头文件中的预定义符。NULL的代码值为0,当p=NULL时,称p为空指针。因为NULL的代码值是0,所以上面语句等价于:p=’\0’;或p=0;这时,指针p并不是指向地址为0的存储单元,而是具有一个确定的值——“空”。企图通过一个空指针去访问一个存储单元时,将会得到一个出错信息。9.1.2一维数组的引用69.1.2一维数组的引用6当系统为所定义的数组在内存中开辟一串连续的存储单元时,这些存储单元中并没有确定的值,数组的初始化就是指在定义数组时给数组元素赋初值。一维数组初始化的定义形式为:类型名数组名[常量表达式或省略]={值0,值1,……};其中,{}中各值是对应的数组元素初值,各值之间用逗号隔开。例如:inta[5]={0,1,2,3,4};也可以省略为:inta[]={0,1,2,3,4};9.1.3一维数组的初始化79.1.3一维数组的初始化7说明:1.可以只给部分数组元素赋初值。当{}中值的个数少于数组元素个数时,则表示初值只赋于数组开始的若干个元素,余下部分元素为相应类型的缺省值,int为整型数0,字符型为空格等。2.{}中值的个数不能超过数组元素的个数。3.只能给数组元素逐个赋值,不能给数组整体赋值。4.对较大数组中的若干不连续的数组元素赋予非零的初值,其余数组元素为0值时,可以用“,”表示对应位置的元素为0值。5.若全部元素均赋为0,可对数组不赋初值。8说明:8C语言中,还可以通过赋初值来定义数组的大小,这时数组说明符的一对方括号中可以不指定数组的大小。例如:inta[]={1,2,3}此时就隐含的定义了a数组含有3个元素。9.1.4通过赋初值定义数组的大小9C语言中,还可以通过赋初值来定义数组的大小,这时数组说明符的9.2一维数组和指针109.2一维数组和指针109.2.1一维数组和数组元素的地址

一维数组在主存中占连续的存储空间,数组名代表的是数组的首地址。可定义一个指针变量,通过赋值或赋初值的形式,把数组名或数组的第一个元素的地址赋值该指针变量,该指针变量就指向了该数组。值得注意的是,这个指针变量中的地址值不可改变,也就是说,不可以给数组名重新赋值,因而数组名也可以认为是一个地址常量。119.2.1一维数组和数组元素的地址11例如:inta[5],*pa=a;/*数组名赋初值给指针变量名,指针变量指向了数组*/inta[5],*pa=&a[0];/*a[0]的地址赋初值给指针变量名,指针变量指向了数组*/inta[5],*pa;pa=a;/*数组名赋值给指针变量名,指针变量指向了数组*/inta[5],*pa;pa=&a[0];/*a[0]的地址赋值给指针变量名,指针变量指向了数组*/。inta[5],*pa,b;a=&b;a++;/*a=&b;a++;都是非法的,因为不能给a重新赋值,一旦定义,a永远指向a数组的首地址*/另外,我们还可以通过循环和scanf函数,从终端读入数据依次存放到a数组中:for(i=0;i<5;i++)scanf(“%d”,a+i);12例如:12以下语句中,由于进入循环前指针变量pa指向的是数组a的首地址,则pa++使得pa依次指了a数组中的每一个元素:for(pa=a,i=0;i<5;i++)pa++;同样也可以写成:for(pa=a,i=0;i<5;i++){scanf(“%d”,pa);pa++;}或for(pa=a,i=0;i<5;i++)scanf(“%d”,pa++);或for(pa=a;pa-a<5;pa++)scanf(“%d”,pa);13以下语句中,由于进入循环前指针变量pa指向的是数组a的首地址9.2.2通过数组的首地址引用数组元素C语言中,若定义了a[5],则a的值即等于&a[0];依次推出a+1、a+2、…、a+4的值分别等于&a[1]、&a[2]、…、&a[4]。我们可以通过运算符“*”引用地址所在的存储单元,所以数组元素a[0]也可以用*(a+0)来引用,即*a。依次类推,对数组元素a[1]的引用可以是*(a+1)、…、数组元素a[4]可以用*(a+4)引用。因此可以通过以下语句逐个输出a数组中的元素的值:for(i=0;i<4;i++)printf(“%d“,*(a+i));149.2.2通过数组的首地址引用数组元素14在C语言中,有一个等式永远成立,即a[i]无条件等价于*(a+i),此处a和p可以是指针变量名和数组名。因此,当指针变量p指向了数组的首元素后,数组a[i]可表示为下列几种形式:*(a+i)*(p+i)a[i]p[i]注意,圆括号不可少。数组a[i]的地址可表示为下列几种形式:a+ip+i&a[i]&p[i]这里的a和p的区别是,a是不可不变的,而p中的地址值却是可变的。因此,a++、a=p、p=&a等运算都是非法的,而p++、p=a、p=&a[i]则都是合法的表达式。9.2.3通过指针及带下标的指针变量引用一维数组元素159.2.3通过指针及带下标的指针变量引用一维数组元素15指向一维数组的指针变量,可以进行简单的算术运算和关系运算。1.指针变量的算术运算2.指针变量与指针变量的减法运算如果两个指针指向同一个数组,它们可以进行减法运算,运算法则如下:指针变量1-指针变量2注意两个指针变量必须是指向同一数组的数组元素的指针变量,它们的差并不是它们地址值的差,而是它们所指向的数组元素的下标之差。9.2.4指针变量的运算169.2.4指针变量的运算163.指针变量间的关系运算指向某一数组中元素的两个指针变量还可以进行关系运算,其运算规则为:

指针变量1关系运算符指针变量2如果指针变量1中的地址值和指针变量2中的地址值满足关系运算时,式子的值为1(真),否则为0(假)。指针变量间的关系运算在处理数组的循环中常作为循环的控制条件。173.指针变量间的关系运算179.3函数之间对一维数组和数组元素的引用189.3函数之间对一维数组和数组元素的引用189.3.1形参为指针变量时,实参和形参之间的数据传递

调用函数时,数组元素可以作为实参传送给形参,每个数组元素实际上代表内存中的一个存储单元,因此对应的形参必须是类型相同的变量。数组元素的值可以传送给该变量,在函数中只能对该变量进行操作,而不能直接引用对应的数组元素。199.3.1形参为指针变量时,实参和形参之间的数据传递199.3.2数组名作实参数组名作为函数的参数,在函数间传递的并不是整个数组,而是数组的首地址,换句话说,就是形参数组与实参数组指的是同一个数组。因此,在被调函数中改变了形参数组的某元素值,其对应的实参数组元素值也跟着发生改变。当数组名作为形参时,其对应的实参可以是指针变量、数组名、地址表达式。在函数中,可以通过此指针变量来引用调用函数中的对应的数组元素,从而达到对调用函数中对应的数组元素进行操作。209.3.2数组名作实参209.3.3数组元素地址作为实参当使用数组元素地址做实参时,传递的也是一个地址,因此,形参数组中元素值发生改变也会影响到实参数组中元素的值。但与数组名做实参有所不同,形参数组的首地址是传递给它的实参数组元素的地址,而不是实参数组的首地址。实际上,数组名做实参是数组元素地址做实参的一个特例,它是传递第1个元素的地址。219.3.3数组元素地址作为实参219.4一维数组应用举例229.4一维数组应用举例221.输入学生人数与学生成绩,然后计算全班的平均成绩。main(){inti,num;floatscore[20],sum=0.0,average;printf("Pleaseinputnumberofstudents:");

scanf("%d",&num);for(i=0;i<num;i++){printf("Inputscore:");scanf("%f",&score[i]);sum+=score[i];}average=(float)sum/(float)num;printf("Theaveragescoreofthestudentsis:%6.2f\n",average);}231.输入学生人数与学生成绩,然后计算全班的平均成绩。239.5二维数组的定义和二维数组元素的引用249.5二维数组的定义和二维数组元素的引用24先看一个例子:某校近三年招收各专业毕业生情况如下:

计算机电子管理数学20029040803020031005090402004954510050要把这些数据组织起来,可以有两种选择:

⑴按从左到右从上到下的顺序存入一个一维数组中。(查询困难)

⑵每年用一个一维数组,把这些数据分别存入三个数组中。25先看一个例子:计算机当数组元素的下标为两个时,该数组称为二维数组。1.二维数组的定义格式存储类型数据类型数组名[常量表达式1][常量表达式2];功能:定义一个二维数组,有“长度1×长度2”个元素。其元素的存储类型和数据类型分别由定义中的“存储类型”和“数据类型”指定。说明:(1)存储类型、数据类型、数组名和长度的含义和选取方法同一维数组。(2)数组元素的各维下标从0开始,最大下标为“长度1”。9.5.1二维数组的定义269.5.1二维数组的定义262.二维数组的逻辑结构和存储结构二维数组的逻辑结构,可以看成是由若干行,每行由若干列组成。例如有如下数组定义语句:inta[3][4];则其逻辑结构如下:

a[0][0]a[0][1]a[0][2]a[0][3] a[1][0]a[1][1]a[1][2]a[1][3] a[2][0]a[2][1]a[2][2]a[2][3]二维数组存储结构是“按行存放,先行后列”

272.二维数组的逻辑结构和存储结构27二维数组元素的引用方法也有两种,分别是“指针法”和“下标法”。这里只讨论“下标法”。假设定义了一个二维数组:inta[N1][N2],其引用形式为: 数组名[下标表达式1][下标表达式2]二维数组元素的引用时注意事项:(1)二维数组各维的下标也是从0开始(2)下标表达式的值必须是整数,且不得超越数组定义的上、下界。(3)引用二维数组元素时,一定要把两个下标分别放在两个括号内。

9.5.2二维数组元素的引用289.5.2二维数组元素的引用28二维数组初始化的方法有以下几种。(1)分行给二维数组所有元素赋初值。例如:inta[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};初始化后,a[1][2]的值即是6。(2)不分行给二维数组所有元素赋初值。例如:inta[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};初始化后,a[2][1]的值即是9。注意:如果对所有元素赋初值,其第1维的长度可以省去,所以(1)和(2)中的inta[3][4]可以写成a[][4]。9.5.3二维数组的初始化299.5.3二维数组的初始化29(3)只对每行或前若干行的前若干个元素赋初值。例如:inta[3][4]={{0,1},{4},{8,9,10}};初始化后,问a[0][1]和a[2][3]的值即为1和0。注意:如果给数组中的某些元素赋初值,没有赋初值的元素也有初值,对于数值型数组,其值为0,对于字符型数组,其值为'\0'。(4)若数组的存储类为auto,如果不进行初始化,则其元素初值不确定。若数组的存储类型为static,若没有进行初始化,其元素均有初值。对于数值类型是0,对于字符型则是'\0'。注意:给二维数组赋初值时,行数不能超过定义的行数,每行的初值个数不能超过定义时的列数。下列的定义是错误的:30(3)只对每行或前若干行的前若干个元素赋初值。309.5.4通过赋值定义二维数组的大小在定义一个二维数组时,可以通过赋初值的个数来确定数组的大小,但只可以省略第1个方括号的常量表达式,而不能省略第2个括号的常量表达式。例如:inta[][2]={{1,2},{3},{4},{5}};以上语句中,a数组中的第一维的常量表达式省略,在所赋初值中,有4对行向量,则第一维的大小可由所赋初值的行数来确定。即等价于:inta[4][2]={{1,2},{3},{4},{5}};319.5.4通过赋值定义二维数组的大小31当使用行花括号赋初值时,第1维的大小由赋初值的行数来决定。当省略行花括号时,第1维的大小按以下规则来决定:(1)当初值的个数能被第2维的常量表达的值除尽时,所得商数就是第1维的大小;(2)当初值的个数不能被第2维的常量表达的值除尽时,则: 第1维的大小=所得商数+1例如:inta[][2]={1,2,3,4};按此规则,a数组的第一维大小应该是2,即inta[2][2]={{1,2},{3,4}};32当使用行花括号赋初值时,第1维的大小由赋初值的行数来决定。当9.6二维数组和指针339.6二维数组和指针339.6.1二维数组和数组元素的地址当指针变量指向二维数组的某个元素后,就可以象处理一维数组元素那样来处理二维数组元素了。指针变量指向二维数组某元素的方法有两种,分别如下:赋初值:数据类型符*指针变量名=&数组名[下标1][下标2]赋值方式:指针变量=&数组名[下标1][下标2]指针变量指向二维数组某元素后,引用该数组元素的方法是:*指针变量。例如:inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},*p=&a[1][2],k;349.6.1二维数组和数组元素的地址当指针变量指向二维数组的9.6.2通过地址来引用二维数组元素二维数组在内存中是按行连续存放的,当用指针变量指向二维数组的首地址后,利用该指针变量就可以处理二维数组的任一个元素。1.让指针变量指向二维数组首地址,可采用赋初值和赋值两种方式使指针变量指向二维数组的首元素。赋初值的方法有两种,格式如下:数据类型符*指针变量=&二维数组名[0][0];或数据类型符*指针变量=*数组名

赋值的方式也有两种,格式如下:指针变量=&二维数组名[0][0];指针变量=*数组名359.6.2通过地址来引用二维数组元素352.二维数组元素的引用方法当p指向二维数组的首元素后,p+1将指向元素第二个元素,p+2将指向第三个元素……以此类推。由此可以得到这样的结论:假设指针变量p已经指向M行N列的数组A的首元素(0<=i<M,0<=j<N),则:A[i][j]的地址为:p+i*N+jA[i][j]可表示为:*(p+i*N+j)362.二维数组元素的引用方法369.6.3通过建立一个指针数组来引用二维数组元素指针数组也是一种数组,所有有关数组的概念都适用于它。但它与普通的数组又有区别,它的数组元素是指针类型的,只能用来存放地址值。其定义形式如下:[格式]存储类型数据类型*指针数组名[长度]={初值列表};例如:int*p[3],a[3][2],i,j;for(i=0;i<3;i++)p[i]=a[i];379.6.3通过建立一个指针数组来引用二维数组元素379.6.4通过建立一个行指针来引用二维数组元素可以先定义一个指向一维数组的指针变量,它指向的一维数组的元素个数与二维数组的列数一致,然后可以通过赋初值或赋值的方式来使指针变量指向二维数组的首行,形式如下:赋初值:数据类型符(*指针变量)[m]=二维数组名赋值:指针变量=二维数组名例如:inta[3][4],(*p)[4]=a;/*赋初值使指针变量p指向a数组的首行*/inta[3][4],(*p)[4];p=a;/*赋值使指针变量p指向a数组的首行*/389.6.4通过建立一个行指针来引用二维数组元素389.7二维数组名和指针数组作为实参399.7二维数组名和指针数组作为实参399.7.1二维数组名作为实参时,实参和形参之间的数据传递当二维数组名作为实参时,对应的形参必须是一个指针变量。例如:#defineM5#defineN3main(){doubles[M][N];…fun(s);…}409.7.1二维数组名作为实参时,实参和形参之间的数据传递4则fun函数的首部可以是以下三种形式之一:(1)fun(double(*a)[N])(2)fun(doublea[][N])(3)fun(doublea[M][N])无论哪种方式,系统都将把a处理成一个行指针。数组名传递给函数的是一个地址值,因此,对应的形参也必定是一个类型相同的指针变量,在函数中引用的将是主函数中的数组元素,系统只为形参开辟一个存放地址的存储单元,而不可能在调用函数时为形参开辟一系列存放数组的存储单元。41则fun函数的首部可以是以下三种形式之一:419.7.2指针数组作为实参时,实参和行参之间的数据传递当指针数组作为实参时,对应的形参应当是一个指向指针的指针。例如:#defineM5#defineN3main(){doubles[M][N],*ps[M];…for(i=0;i<M;i++)ps[i]=s[i];fun(s);…}429.7.2指针数组作为实参时,实参和行参之间的数据传递42则fun函数的首部可以是以下三种形式之一:(1)fun(double*a[M])(2)fun(double*a[])(3)fun(double**a)因为传送的是一维指针数组,所以形参的定义形式与一维数组名作实参的形式类似。43则fun函数的首部可以是以下三种形式之一:43考题讲解1、有以下程序#include<stdio.h>main(){inta[]={2,3,5,4},i;for(i=0;i<4;i++)switch(i%2){case0:switch(a[i]%2){case0:a[i]++;break;case1:a[i]--;}break;case1:a[i]=0;}for(i=0;i<4;i++)printf("%d",a[i]);printf("\n");}程序运行后的输出结果是()。(2009.9)A)3344B)2050C)3040D)0304答案:C44考题讲解1、有以下程序442、以下函数按每行8个输出数组中的数据voidfun(int*w,intn){inti;for(i=0;i<n;i++){___________printf("%d",w[i]);}printf("\n");}下划线处应填入的语句是()。(2009.3)A)if(i/8==0)printf("\n");B)if(i/8=0)continue;C)if(i%8==0)printf("\n");D)if(i%8==0)continue;答案:C3、若有定义语句:intm[]={5,4,3,2,1},i=4;,则下面对m数组元素的引用中错误的是()。(2008.9)A)m[--i]B)m[2*2]C)m[m[0]]D)m[m[i]]答案:C4、若有以下定义intx[10],*pt=x;则对x数组元素的正确引用是()。(2009.3)A)*&x[10]B)*(x+3)C)*(pt+10)D)pt+3答案:B452、以下函数按每行8个输出数组中的数据455、有以下程序#include<stdio.h>main(){char*a[]={"abcd","ef","gh","ijk"};inti;for(i=0;i<4;i++)printf("%c",*a[i]);}程序运行后的输出结果是()。(2009.3)A)aegiB)dfhkC)abcdD)abcdefghijk答案:A6、有以下程序#include<stdio.h>main(){inta[]={1,2,3,4},y,*p=&a[3];--p;y=*p;printf("y=%d\n",y);}程序的运行结果是()。(2008.4)A)y=0B)y=1C)y=2D)y=3答案:D465、有以下程序#include<stdio.h>467、以下程序的定义语句中,x[1]的初值是【1】,程序运行后输出的内容是【2】。(2008.4)#include<stdio.h>main(){intx[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},*p[4],i;for(i=0;i<4;i++){p[i]=&x[2*i+1];printf("%d",p[i][0]);}printf("\n");}答案:1、22、24688、以下程序的输出结果是【】。(2008.4)#include<stdio.h>main(){inta[5]={2,4,6,8,10},*p;p=a;p++;printf("%d",*p);}答案:4477、以下程序的定义语句中,x[1]的初值是【1】9、若有定义语句:doublex[5]={1.0,2.0,3.0,4.0,5.0},*p=x;则错误引用x数组元素的是()。(2008.4)A)*pB)x[5]C)*(p+1)D)*x答案:B10、有以下程序#include<stdio.h>voidfun(int*s,intn1,intn2){inti,j,t;i=n1;j=n2;while(i<j){t=s[i];s[i]=s[j];s[j]=t;i++;j--;}}main(){inta[10]={1,2,3,4,5,6,7,8,9,0},k;fun(a,0,3);fun(a,4,9);fun(a,0,9);for(k=0;k<10;k++)printf("%d",a[k]);printf("\n");}程序的运行结果是()。(2008.4)A)0987654321B)4321098765C)5678901234D)0987651234答案:C489、若有定义语句:doublex[5]={1.0,211、有以下程序#include<stdio.h>voidfun(inta[],intn){inti,t;for(i=0;i<n/2;i++){t=a[i];a[i]=a[n-1-i];a[n-1-i]=t;}}main(){intk[10]={1,2,3,4,5,6,7,8,9,10},i;fun(k,5);for(i=2;i<8;i++)printf("%d",k[i]);printf("\n");}程序的运行结果是()。(2008.9)A)345678B)876543C)1098765D)321678答案:D4911、有以下程序4912、以下程序的输出结果是【】(2008.9)#include<stdio.h>#defineN5intfun(int*s,inta,intn){intj;*s=a;j=n;while(a!=s[j])j--;returnj;}main(){ints[N+1];intk;for(k=1;k<=N;k++)s[k]=k+1;printf("%d\n",fun(s,4,N));}答案:35012、以下程序的输出结果是【】(2008.13、以下程序按下面指定的数据给x数组的下三角置数,并按如下形式输出,请填空。(2008.9)43726915810#include<stdio.h>main(){intx[4][4],n=0,i,j;for(j=0;j<4;j++)for(i=3;i>=j;【1】){n++;x[i][j]=【2】;}

温馨提示

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

评论

0/150

提交评论