《C语言学习与应用》教学课件08二维数组操作_第1页
《C语言学习与应用》教学课件08二维数组操作_第2页
《C语言学习与应用》教学课件08二维数组操作_第3页
《C语言学习与应用》教学课件08二维数组操作_第4页
《C语言学习与应用》教学课件08二维数组操作_第5页
已阅读5页,还剩57页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

任务说明

学习二维数组的定义,数组元素的引用、遍历和整齐化输出的方法,在此基础上掌握批量数据的程序设计。

知识要求了解二维数组的定义和下标变量的范围。掌握二维数组元素和地址的多种表示方法。掌握二维数素元素的遍历方法。掌握二维数组输出函数的编写。了解针对二维数组操作的函数的编写。

能力要求能够用宏定义二维数组的范围。能够定使用指针变量遍历二维数组。能够编写对二维数组操作的函数。能够排查有关二维数组程序设计中的物理和逻辑错误。能够自由地书写二维数组操作的函数和主函数。二维数组的定义和初始化1.二维数组的定义

二维数组就是若干个一维数组,对二维数组的操作就是多次对一维数组的操作,一维数组的遍历是一层循环,二维数组的操作就是循环的嵌套了。01定义了一个名为a的二维数组,在内存中占有12个连续的存储单元,顺序是a[0][0],a[0][1],a[0][2],a[0][3],a[1][0],a[1][1]…a[2][3],如图8-1所示。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]可以将二维数组理解为一个矩阵,本例是3行4列的矩阵,行下标的变化范围是0~2,列下标的变化范围是0~3。1.二维数组的定义图8-1二维数组存储示意图微课二维数组的定义2.二维数组元素的引用

如有定义“doublew[4][2];”,则w[1][0]、w[i][j]、w[i+j][k]等均是合法的引用,只要有两个方括号,方括号中的表达式值为整数且在允许的范围内即可。

3.二维数组的初始化inta[3][3]={{1,2},{4,2}};只给前两行的前两个元素赋值,其余元素均为0。inta[4][3]={1,2,4,5};按存储顺序给a[0][0],a[0][1],a[0][2],a[1][0]分别赋值1、2、4、5,其余元素值均为0。inta[][3]={{1,2,3},{4,5}};可以省略第一个方括号中的常量表达式,不能省略第二个方括号中的常量表达式,本例中第一个方括号中的隐含值是2。应用举例8-1:二维数组的基本操作:输入和输出。#include"stdio.h"#include"stdlib.h"#defineM3//用宏定义二维数组的行数#defineN4

//用宏定义二维数组的列数voidmain(){

inta[M][N],i,j;

for(i=0;i<M;i++)//对二维数组搜一遍,是两层循环

for(j=0;j<N;j++)

a[i][j]=rand(

)%100;//为二维数组元素赋0~99的随机值

for(i=0;i<M;i++){

for(j=0;j<N;j++)

printf("%3d",a[i][j]);

printf("\n");//每输出一行换一行

}getchar();}应用举例8-1:二维数组的基本操作:输入和输出。程序输出:4167340

69247858

6264545课堂思考问题8-1将程序代码补充完整,输出3行3列的方阵。#include“stdio.h”#defineM3voidmain(){inti,j,a[…][…]={4,9,2,3,7,8,1,6};

…………………..

…………………..

…………………..

…………………..}课堂思考:问题8-1二维数组的地址和指针1.二维数组元素和地址的表示若有定义“inta[3][4];”,则数组元素a[i][j]的地址有以下几种表示方法。

&a[i][j]。这种表示方法是最直接的表示。

(1)a[i]+j。这种表示方法是将a[i]理解为一维数组的数组名,a[i]+j就是a[i][j]的地址。(2)02*(a+i)+j。这种表示方法将上面的a[i]表示为*(a+i)。(3)&a[0][0]+4*i+j。二维数组是连续存储,从起始位置&a[0][0]向后移4*i+j就是&a[i][j]。

(4)a[0]+4*i+j。在这种表示方法中,&a[0][0]就是a[0]。(5)1.二维数组元素和地址的表示

数组元素a[i][j]有以下几种表示方法。a[i][j]。这种表示方法是最直接的表示。(1)*(a[i]+j)。这种表示方法由地址的第二种表示方法演变而来。

(2)*(*(a+i)+j)。这种表示方法由地址的第三种表示方法演变而来。(3)*(&a[0][0]+4*i+j)。这种表示方法由地址的第四种表示方法演变而来。

(4)*(a[0]+4*i+j)。这种表示方法由地址的第五种表示方法演变而来。(5)(*(a+i))[j]。这种表示方法将a[i][j]中的a[i]表示为*(a+i),考虑到优先问题加上括号。(6)

数组元素a[i][j]有以下几种表示方法。微课二维数组元素的地址表示2.二维数组中几个地址的区别

如有定义“inta[3][4];”,则a、a[0]、&a[0][0]都是这些连续存储单元的首地址,但它们的基类型不同,a[0]和&a[0][0]的基类型为1个整型的存储单元,而a的基类型为4个整型的存储单元。

&a[0][0]+1和a[0]+1中的1表示1个存储单元,而a+1中的1表示4个存储单元(4就是a[3][4]中的每行元素个数),如图8-2所示。图8-2二维数组元素的地址3.用一维数组的指针访问二维数组元素

因二维数组元素是连续存储,故可以当一维数组使用。可以用与一维数组对应的指针访问二维数组元素。如有定义“inta[3][4],*p=a[0];”,则p+1是&a[0][1],*(p+5)就是a[1][1]。还可以给p赋&a[0][0]、a[1]、a[2],但不能给p赋a,因为它们的基类型不同。4.专用于二维数组的指针如有定义“inta[3][4],*p[3],(*q)[4];”,则p[0]、p[1]、p[2]和q可理解为是二维数组的指针。

“inta[3][4],*p[3];”中,*p[3]的方括号优先,它定义了一个数组p[3],它的三个数组元素均是指针变量,当执行语句“for(i=0;i<3;i++)p[i]=a[i];”后,p[i][j]就是a[i][j]了

“inta[3][4],(*q)[4];”中,(*q)[4]的小括号优先,它定义了一个指针变量q,其基类型为4个整型的存储单元,当执行语句“q=a;”后,q[i][j]就是a[i][j]了。

二维数组名和指针数组为实参1.二维数组名作为实参对应的fun函数头部的书写形式为:fun(ints[M][N])或fun(ints[][N])或fun(int*s)[N]。三种情况中,遮住最右面的[N],其余部分与一维数组名作为实参时的书写形式一致。无论是哪种方式,形参都需开辟一个存储单元用来接收传来的二维数组的首地址。inta[M][N];fun(a);//调用函数时,指针数组做实参03微课二维数组名作为实参2.指针数组作为实参对应的fun函数头部的书写形式为:fun(int**a)或fun(int*a[M])或fun(int*a[])上述三种情况,遮住最左面的*号,其余部分与一维数组名做实参时的书写形式一致,不论哪种写法,都处理成第一种情况,既开辟一个存储单元,用于接收指针的地址。inta[M][N],*p[M];for(i=0;i<M;i++)p[i]=a[i];fun(p);//调用函数时,指针数组做实参1.二维数组中一些元素的表示

二维数组搜索一遍要使用两个下标变量,输出时注意每输出一行后换一行。对M行N列的二维数组,如用i表示行下标,j表示列下标,则二维数组周边元素下标的特征是i==0||j==0||i==M-1||j==N-1。对M行M列的方阵,左下三角(包括对角线)元素下标的特征是j<=i,右上三角元素特征是j>=i,从左上到右下的对角线的元素下标是i==j,从右上到左下的对角线特征是i+j==M-1。

二维数组应用举例04微课二维数组中一些元素的表示2.针对二维数组的操作应用举例8-2:求二维数组周边元素的平均值。对数组元素搜一遍,遇到周边元素累加并计算。#include"stdio.h"#include"stdlib.h"#defineM3#defineN4doublefun(intw[][N]){

int

i,j,k=0;

doubleave=0;

for(i=0;i<M;i++)

//对二维数组搜一遍,遇到周边元素累加并计数for(j=0;j<N;j++)

if(i==0||i==M-1||j==0||j==N-1)

{

ave+=w[i][j];

k++;

returnave/k;//返回平均值}voidmain(){

inta[M][N],i,j;

for(i=0;i<M;i++)

//为二维数组元素赋值

for(j=0;j<N;j++)

a[i][j]=rand(

)%50;

for(i=0;i<M;i++)

//输出数组

{

for(j=0;j<N;j++)

printf("%3d",a[i][j]);

printf("\n");

}

printf("ave=%f\n",fun(a));

getchar();}输出:41173402428814545ave=19.500000课堂思考问题8-2将N行N列的方阵左下三角元素置0,请将程序代码补充完整。#include"stdio.h"#include"stdlib.h"#defineN5voidfun(intw[][N])

//为数组左下三角元素置0{

…….........…………….

……........……………..

………........…………..

………........…………...}voidout(intw[][N])//输出数组

{

…………….........………

……………........……….

…………........………….

………………….........….}voidmain(){

inta[N][N],i,j;

for(i=0;i<N;i++)

//为二维数组元素赋值

for(j=0;j<N;j++)

a[i][j]=rand(

)%50;

out(a);

//输出数组元素

fun(a);

//为左下三角数组元素置0

out(a);

//再次输出数组元素

getchar(

);}

应用举例8-3:方阵的转置。搜索不包括对角线元素在内的左下三角元素,与对应元素交换,即a[i][j]与a[j]a[i]交换。#include"stdio.h"#defineM3voidarrout(intarray[][M]){

inti,j;

for(i=0;i<M;i++)

{

for(j=0;j<M;j++)

printf("%3d",array[i][j]);

printf("\n");

}}应用举例8-3:方阵的转置。

voidfun(intarray[M][M]){inti,j,t;

for(i=0;i<M;i++)

for(j=0;j<i;j++)//内层循环次数用i控制

{t=array[i][j];array[i][j]=array[j][i];array[j][i]=t;

}}voidmain(){

inta[M][M]={1,2,3,4,5,6,7,8,9},i,j;

printf("print1:\n");

arrout(a);//输出原数组

fun(a);//调用fun函数实现转置

printf("print2:\n");

arrout(a);//输出转置后的数组

getchar();}应用举例8-3:方阵的转置。3.将二维数组看做若干个一维数组应用举例8-4:将二维数组每行元素的平均值放在b数组中。

将二维数组看做由M个一维数组组成,对每个一维数组做三件事:累加器清零,求和,计算平均值并赋给b数组。#include"stdio.h"#defineM3#defineN4voidfun(inta[][N],floatb[]){

int

i,j;

floats;

for(i=0;i<M;i++)//i是行数

{

s=0;//这两句是一维数组的求和运算

for(j=0;j<N;j++)

s=s+a[i][j];b[i]=s/N;//第i行的平均值赋给b[i]

}}voidmain(){

inta[M][N]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;

floatb[M];

fun(a,b);//调用函数将每行元素的平均值放在b数组中

for(i=0;i<M;i++)//输出数组元素和对应的平均值

{

for(j=0;j<N;j++)

printf("%3d",a[i][j]);

printf("%.2f\n",b[i]);//在每行数组元素后输出平均值

}

getchar();}课堂思考问题8-3将二维数组每列元素的平均值放在b数组中。#include"stdio.h"#defineM3#defineN4voidfun(inta[][N],floatb[N]){………

……….……….……….}voidmain(){inta[M][N]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;floatb[N];fun(a,b);//调用函数将每列元素的平均值放在b数组中for(i=0;i<M;i++)//输出数组元素和对应的平均值{

for(j=0;j<N;j++)

printf("%3d",a[i][j]);

printf("\n");

}for(j=0;j<N;j++)

printf("%.2f",b[j]);getchar();}将二维数组每列元素的平均值放在b数组中。

任务实施

任务多科成绩的统计计算

工作内容及要求:单科成绩的统计计算是一维数组的操作,二维数组就是多个一维数组,将单科成绩的统计计算重复几遍就是对多科成绩的操作,在file1文件(图8-3)中存放了某班学生的三科成绩(算法、JAVA、数据库),每一行的数据是一个学生的三科成绩,在主函数中已将成绩读入二维数组a[100][3]中,学生数小于100,完成以下计算任务。

(1)计算每个人的平均分,将各科成绩和平均分写入f1.txt文件中。(2)计算各科成绩的最高分,将各科成绩和最高分写入f2.txt文件。图8-3file1文件内容编程训练

8-1代码调试。

这个任务涉及文件操作的知识,请先将下面的参考代码在VS环境中调试,调试前要检查在d盘根目录下的file1.txt文件是否存在,数据是否符合要求,程序运行通过后要检查在d盘产生的f1.txt文件内容是否正确。

知识链接:文件读写知识FILE*fp;//定义文件指针

if((fp=fopen(“d:\\file1.txt”,”r”))==NULL)//以“读”方式打开d盘file1.txt文件

{printf(“cannotopenthisfile!\n”);//如打开有误,终止程序

exit(0);/*强行终止程序,须包含“stdlib.h”文件*/

}#include"stdio.h"#include"stdlib.h"//调用exit(0)需包含的文件#defineM100#defineN3intafin(inta[M][N])/*将文件内容读入数组,函数值为记录个数

*/{FILE*fp;//定义文件指针变量inti=0,n;

if((fp=fopen(“d:\\file1.txt”,“r”))==NULL)/*以读方式打开d盘根目录file1.txt文件*/ {

printf(“文件打开错误!\n”);//若打开有误,终止程序

exit(0);

//强行终止程序 } while(!feof(fp))//文件指针没到尾 {

fscanf(fp,"%d%d%d",&a[i][0],&a[i][1],&a[i][2]);//从文件读数i++; }

fclose(fp);//关闭文件

n=i;

returnn;//n表示读入的记录个数}voidafout(inta[M][N],intn)//将数组内容写入文件的函数{FILE*fp;inti;if((fp=fopen(“d:\\f1.txt”,“w”))==NULL)/*写方式打开d盘根目录下的f1.txt文件*/

{

printf("文件写入错误!\n");exit(0);}for(i=0;i<n;i++)fprintf(fp,"%4d%4d%4d\n",a[i][0],a[i][1],a[i][2]);//向文件写数

fclose(fp);}voidaout(inta[M][N],intn)//显示数组内容{inti;for(i=0;i<n;i++)printf("%4d%4d%4d\n",a[i][0],a[i][1],a[i][2]);}voidmain(){

inta[M][N],n;//定义数组和中间变量

n=afin(a);

//将文件内容读入数组

aout(a,n);//显示数组内容

afout(a,n);

//将数组内容写入文件

getchar();}

编程训练

8-2

计算各科成绩的平均分。

计算各科成绩的平均分是一维数组计算平均值的问题,计算所有人的平均分是二维数组的操作,就是对一维数组操作的重复,写出fun1函数,计算a数组中n个人的平均分,并将平均分依次存入b数组中。程序的输出结果如图8-4所示。

图8-4编程训练8-2程序的显示结果

#include"stdio.h"#include"stdlib.h"#defineM100#defineN3intafin(inta[M][N])//将文件内容读入数组,函数值为记录个数

{略}voidafout(inta[M][N],intn,doubleb[])//将数组内容写入文件的函数{

………//请参考编程训练8-1的内容fprintf(fp,"算法Java数据结构平均分\n");for(i=0;i<n;i++)fprintf(fp,"%4d%4d%4d%.2f\n",a[i][0],a[i][1],a[i][2],b[i]);fclose(fp);}voidaout(inta[M][N],intn,doubleb[])//显示数组内容{inti;printf(“算法Java数据结构平均分\n”);for(i=0;i<n;i++)printf("%4d%4d%4d%.2f\n",a[i][0],a[i][1],a[i][2],b[i]);}voidfun1(inta[][3],intn,double*b){...............................................................................................................................................................................................................................................................}voidmain(){inta[M][N],n;//定义数组和中间变量

doubleb[M];

//定义存放平均值的数组n=afin(a);//将文件内容读入数组

fun1(a,n,b);//计算a数组n行元素的平均值,放在b数组中aout(a,n,b);//显示数组内容afout(a,n,b);//将数组内容写入文件

getchar();}

编程训练

8-3计算各科成绩的最高分。

这是对三个数组最大值的问题,请写出fun2函数并调试程序,参考输出如图8-5所示。图8-5编程训练8-3程序运行后f2.txt文件的内容

#include"stdio.h"#include"stdlib.h"#defineM100#defineN3intafin(inta[M][N])//将文件内容读入数组,函数值为记录个数

{略}voidafout(inta[M][N],intn,int*c)//将数组内容写入文件的函数{

…………………fprintf(fp,“算法Java数据结构\n”);

for(i=0;i<n;i++)

fprintf(fp,“%4d%4d%4d\n”,a[i][0],a[i][1],a[i][2]);

fprint(fp,“最高分:\n”);

for(i=0;i<N;i++)fprint(fp,“%4d”,c[i]);

fclose(fp);}voidaout(inta[M][N],intn,int*c)//显示数组内容{inti;

printf(“算法Java数据结构平均分\n”);for(i=0;i<n;i++)printf(“%4d%4d%4d\n",a[i][0],a[i][1],a[i][2]);printf("最高分:\n");

for(i=0;i<N;i++)printf("%4d",c[i]);}voidfun2(inta[][N],intn,int*c){

………………….

………………….

…………………..}voidmain(){inta[M][N],n;//定义数组和中间变量

intc[N];

//定义存放最高分的数组n=afin(a);

//将文件内容读入数组

fun2(a,n,c);//将a数组记录的n个最高分放入c数组

aout(a,n,c);

//显示数组内容

afout(a,n,c);

//将数组内容写入文件

getchar()}

编程训练

8-4程序挑错。

下面这段程序代码是计算最高分的,编译没错,但是结果不对,显示如图8-6所示,请指出其中的错误。

图8-6编程训练8-4程序的执行结果

#include"stdio.h"#include"stdlib.h"#defineM100#define

温馨提示

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

最新文档

评论

0/150

提交评论