5.4.1 二维数组 (一) 二维数组的定义 1. 二维数组定义的一般形式 类型说明符 数组名[常量表达式][ 常量表达式] 类型说明符 数组名[常量表达式][ 常量表达式] 例如:int a[3][4] 定义了一个3×4(3行4列)的整型数组a 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
5.4.1 二维数组 2. 二维数组的理解 二维数组是一种特殊的一维数组 例如 int a[3][4]; 三个元素分别为a[0],a[1],a[2]。 再看第二维,表明每个元素又是一个包含4个元素的一维数组, 如a[0]这个元素包含4个元素:a[0][0],a[0][1],a[0][2],a[0][3] 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
5.4.1 二维数组 ( 二) 二维数组的使用 二维数组元素的表示形式: 数组名[下标][下标] 例:int a[3][4], 表示行下标值最小从0开始,最大为3-1=2; 列下标值最小为0,最大为4-1=3, 即: 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] 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
5.2 项目相关知识 (三) 二维数组的初始化 二维数组初始化的方法如下。 (1) 分行给二维数组赋初值(推荐使用) int a[3][4]={{1,2,3,4},{4,5,6,7},{6,7,8,9}}; (2) 将所有数据写在一个花括弧内,按数值排列的顺序对各元素赋初值。 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12} (3) 可以对部分元素赋初值。 int a[3][4]={{1,2},{4},{6,7,8}}; a数组分布如图所示。 (4) 如果对全部数组元素赋值,则第一维的长度可以不指定, 但必须指定第二维的长度,全部数据写在一个大括号内。 如: int a[][3]={1,2,3,4,5,6,7,8,9,10,11,12}; 第一维长度4省略。 1 2 0 0 4 0 0 0 6 7 8 0 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
(四) 二维数组的应用 【例5-11】输入五个同学三门课的成绩并输出。 #include "stdio.h" #define N 5 main() {int i,j; int score [N][3]; printf("请输入五个同学三门课的成绩:\n"); for (i=0;i<N;i++) for(j=0;j<3;j++) scanf("%d",&score[i][j]); printf("输出五个同学三门课的成绩:\n"); for (i=0;i<N;i++) { printf("第%d位同学:",i+1); for(j=0;j<3;j++) printf("%5d",score[i][j]); printf("\n"); } 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
【例】有3*3的方阵,其中的元素由键盘输入。 求出(1)主对角线上元素之积; (2)辅对角线上元素之和; 5 6 7 9 10 11 (四) 二维数组的应用 【例】有3*3的方阵,其中的元素由键盘输入。 求出(1)主对角线上元素之积; (2)辅对角线上元素之和; 5 6 7 9 10 11 13 14 15 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
zdjx*=a[i][j]; if(i+j==N-1) fdjx+=a[i][j]; 浙江长征职业技术学院—计算机与信息技术系—相方莉制作 #include <stdio.h> #define N 3 main() { int a[N][N],zdjx=1,fdjx=0,i,j; //zdjx代表主对角线之积,fdjx代表辅对角线之和 printf("请输入%d行%d列的数据!\n",N,N); for(i=0; i<N; i++) for(j=0; j<N; j++) scanf("%d",&a[i][j]); if(i==j) zdjx*=a[i][j]; if(i+j==N-1) fdjx+=a[i][j]; } printf("主对角线之积为=%d,辅对角线之和为=%d\n",zdjx,fdjx ); 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
【例5-12】输出如下的杨辉三角形,要求一共有10行10列。 /*给每一列及主对角元素赋值*/ for(i=0;i<10;i++) {a[i][0]=1; a[i][i]=1;} /*计算其它列的值*/ for(i=2;i<10;i++) for(j=1;j<i;j++) a[i][j]=a[i-1][j-1]+a[i-1][j]; #include "stdio.h" main() {int a[10][10],i,j; /*给每一列及主对角元素赋值*/ for(i=0;i<10;i++) { a[i][0]=1; a[i][i]=1; } /*计算其它列的值*/ for(i=2;i<10;i++) f or(j=1;j<i;j++) a[i][j]=a[i-1][j-1]+a[i-1][j]; printf("杨辉三角形的图形为:\n"); for(i=0;i<10;i++) {for(j=0;j<=i;j++) printf("%5d",a[i][j]); printf("\n");} } 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
练一练 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
浙江长征职业技术学院—计算机与信息技术系—相方莉制作
冒泡排序 输入6个数,用“冒泡法”对6个数排序(由小到大)。 冒泡法的基本思想: 通过相邻两个数之间的比较和交换, 使排序码(数值)较小的数逐渐从底部移向顶部, 排序码较大的数逐渐从顶部移向底部。 就像水底的气泡一样逐渐向上冒,故而得名。 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
冒泡排序 第1趟比较(下图1 ) 第2趟比较(下图2) 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
冒泡排序 第1趟,两两比较5次,剩5个数未排好序; 第2趟,两两比较4次,剩4个数未排好序; 第3趟,两两比较3次,剩3个数未排好序; 第4趟,两两比较2次,剩2个数未排好序; 第5趟,两两比较1次,全部排好序; 算法结论:对于n个数的排序,需进行n-1趟比较, 第j趟比较需进行n-j次两两比较。 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
{t=a[j];a[j]=a[j+1];a[j+1]=t;} #include <stdio.h> void main() { int a[10]; int i,j,t; printf(“请输入10个整数:\n”); for(i=0;i<=9;i++) scanf((“%d”,&a[i]); printf(“\n”); for(i=1;i<=9;i++) for(j=0;j<10-i;j++) if(a[j]>a[j+1]) {t=a[j];a[j]=a[j+1];a[j+1]=t;} printf(“冒泡排序后10个整数:\n”); for(i=0;i<10;i++) printf(“%4d“,a[i]); } 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
选择排序 选择排序的基本思想: 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
if(math[j]<math[i]) t=math[j]; math[j]=math[i]; math[i]=t; } 【例5-14】用选择法对10个同学的成绩进行排序(由高到低)。 #include "stdio.h" main( ) { int i,math[10],t,j; printf(" 请输入10个同学的成绩:"); for(i=0;i<10;i++) scanf("%d",&math[i]); for(j=0;j<9;j++) for(i=j+1;i<10;i++) if(math[j]<math[i]) t=math[j]; math[j]=math[i]; math[i]=t; } printf("10个同学的成绩排序为:"); printf("%3d", math[i]); printf("\n"); 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
浙江长征职业技术学院—计算机与信息技术系—相方莉制作
知识扩展 【例5-7】有二个学生A,B合力完成下面一个问题:求20个学生的平均成绩。他们的分工是这样的: 使用数组名作为函数参数时,实参与形参都应使用数组名(或指针变量,见项目六)。当数组名作为函数实参时,不是把数组的值传递给形参,而是把实参数组的起始地址传递给形参数组,实参和形参的地址是相同的,即当形参的值发生变化时,实参的值也发生了变化。 【例5-7】有二个学生A,B合力完成下面一个问题:求20个学生的平均成绩。他们的分工是这样的: B完成20个数的平均值,不负责数据的输入; A完成20个数的输入,然后问B要20个数的平均值后输出。 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
(三)相关知识 #include "stdio.h" /*B所完成的程序*/ float average(int b[20]) { int i,s; float avg; s=0; for (i=0;i<20;i++) s=s+b[i]; avg=s/20.0; return avg; } /*A所完成的程序*/ main() { int i,a[20]; float avg; printf("请输入20个同学的成绩\n"); for (i=0;i<20;i++) scanf("%d",&a[i]); avg=average(a); printf("这些同学的平均分为%.1f\n",avg); } 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
注 意 (4)形参数组也可不指定大小,或者在被调函数中另设一个参数,来传递数组的大小。如上面的程序可改为: (1)数组名作为函数参数,应该在主调函数和被调函数中分别定义数组, 如上面程序中的b是形参数组,a是实参数组,分别在其所在的函数中定义。 #include "stdio.h" float average(int b[ ],int n) {int i,s; float avg; s=0; for (i=0;i<n;i++) s=s+b[i]; avg=(float)s/n; return avg; } (2)实参数组与形参数组类型应当相同,如果不同,将会出错,如上面程序中的形参数组b是整型,实参数组a也是整型。 (3) 实参数组与形参数组大小可以不同也可以相同,C编译器对形参数组大小不做检查,只是将实参数组的首地址传递给形参数组。 如上面程序中的float average(int b[20])改为float average(int b[10]),并不影响程序的正常运行,最后的结果也是相同的,我们甚至可以写成float average(int b[ ]),即只要b是数组即可。 (4)形参数组也可不指定大小,或者在被调函数中另设一个参数,来传递数组的大小。如上面的程序可改为: (5)形参数组与实参数组是占用同一个地址,所以是地址传递,即当形参的值发生变化时,实参的值也会跟着变化。 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
【例5-8】输入十个同学的成绩,要求用函数进行排序(降序)。 即有二个学生A,B合力完成下面一个问题:将10个学生的成绩排序(降序)。他们的分工是这样的:A是完成主函数的编写:也就是完成10个数的输入,调用B编写的函数sort( ),就得到排序完的10个数,然后进行输出。B所编写的函数sort( )的功能是完成10个数的排序,不负责数据的输入。 main( ) {int a[10],i; printf("请输入十个同学的成绩\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); sort(a); printf("排序后的成绩为:\n"); printf("%3d",a[i]); printf("\n"); } #include "stdio.h" void sort(int b[ ]) { int i,j,t; for (i=0;i<9;i++) for(j=i+1;j<10;j++) if(b[i]<b[j]) {t=b[i];b[i]=b[j];b[j]=t;} } 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
浙江长征职业技术学院—计算机与信息技术系—相方莉制作 【例5-13】在函数中进行 n个学生成绩从高到低排名。即有二个学生A,B合力完成下面一个问题:将n个学生的成绩进行排序(降序)。他们的分工是这样的:A是完全成主函数的编写:也就是完成n个数的输入,调用B编写的函数sort(),就得到排序后的n个数,然后进行输出。B所编写的函数sort()的功能是完成n个数的排序,不负责数据的输入。 #include "stdio.h" void sort(int b[],int n) { int i,j,t; for (i=0;i<n-1;i++) for(j=i+1;j<n;j++) if(b[i]<b[j]) t=b[i]; b[i]=b[j]; b[j]=t; } main() { int a[100],i,n; printf("请输入参加排序的学生数n="); scanf("%d",&n); printf("请输入%d个同学的成绩\n",n); for(i=0;i<n;i++) scanf("%d",&a[i]); sort(a,n); printf("排序后的成绩为:\n"); printf("%3d",a[i]); printf("\n"); } 浙江长征职业技术学院—计算机与信息技术系—相方莉制作
练一练 浙江长征职业技术学院—计算机与信息技术系—相方莉制作