7.2 结构体数组的定义和引用 单个的结构体类型变量在解决实际问题时作用不大,一般是以结构体类型数组的形式出现。结构体类型数组的定义形式为: struct stu /*定义学生结构体类型*/ { char name[20]; /*学生姓名*/ char sex; /*性别*/ long num; /*学号*/ float score[3]; /*三科考试成绩*/ }; struct stu stud[20]; /* 定义结构体类型数组stud ,*/ / *该数组有2 0个结构体类型元素* / 其数组元素各成员的引用形式为: stud[0].name 、stud[0].sex、stud[0].score[i]; stud[1].name、stud[1].sex、stud[1].score[i]; . . . . . . stud[19].name、stud[19].sex、stud[19].score[i];
[例7-1] 设某组有4 个人,填写如下的登记表,除姓名、学号外,还有三科成绩,编程实现对表格的计算,求解出每个人的三科平均成绩,求出四个学生的单科平均,并按平均成绩由高分到低分输出。 NumberNameEnglishMathemrPhysicsAverage 1Liping789876. 2Wanglin669086. 3Jiangbo897076. 4Yangming9010067.
题目要求的问题多,采用模块化编程方式,将问题进行分解如下: 1) 结构体类型数组的输入。 2) 求解各学生的三科平均成绩。 3) 按学生的平均成绩排序。 4) 按表格要求输出。 5) 求解组内学生单科平均成绩并输出。 6) 定义m a i n ( )函数,调用各子程序。 第一步,根据具体情况定义结构体类型。 struct stu { char name[20]; /*姓名* / long number; /*学号* / float score[4]; /* 数组依此存放English、Mathema、Physics,及Average*/ } ; 由于该结构体类型会提供给每个子程序使用,是共用的,所以将其定义为外部的结构体类型,放在程序的最前面。 第二步,定义结构体类型数组的输入模块。 void input(arr,n) /*输入结构体类型数组arr 的n个元素*/ struct stu arr[]; int n; { int i,j; char temp[30]; for (i=0;i<n;i++) { printf("\ninput name,number,English,mathema,physic\n"); /*打印提示信息* / gets(arr[i].name); /* 输入姓名*/ gets(temp); /* 输入学号*/ arr[i].number = atol(temp); for(j = 0; j < 3; j++) { gets(temp); /*输入三科成绩* / arr[i].score[j] = atoi(temp); } } } 第三步,求解各学生的三科平均成绩。 在结构体类型数组中第i个元素arr[i]的成员score的前三个元素为已知,第四个Average需计算得到。 void aver(arr,n) struct stu arr[]; int n; { int i,j; for(i=0;i<n;i++) /*n个学生*/ { arr[i].score[3] = 0; for(j=0;j<3;j++) arr[i].score[3]=arr[i].score[3]+arr[i].score[j]; /* 求和*/ arr[i].score[3]=arr[i].score[3] /3; /* 平均成绩* / } } 第四步,按平均成绩排序,排序算法采用冒泡法。 void order(arr,n) struct stu arr[]; int n; { struct stu temp; int i,j,x,y; for(i = 0; i < n - 1; i++) for( j = 0; j < n - 1 - i; j++)
if (arr[j].score[3]>arr[j+1].score[3]) { temp=arr[j]; /* 结构体类型变量不允许以整体输入或输出,但允许相互赋值* / arr[j]=arr[j+1]; /*进行交换* / arr[j + 1] = temp; } } 第五步,按表格要求输出。 void output(arr,n) /*以表格形式输出有n个元素的结构体类型数组各成员*/ int n;struct stu arr[]; { int i,j; printf("********************TABLE********************\n"); /* 打印表头*/ printf("----------------------------------------------------\n"); /*输出一条水平线*/ printf("|%10s|%8s|%7s|%7s|%7s|%7s|\n","Name","Number", "English", "Mathema","physics","average"); /*输出效果为:| Name| Number|English|Mathema|Physics|Average|*/ printf("----------------------------------------------------\n"); for (i=0;i<n;i++) { printf("|%10s|%8ld|",arr[i].name,arr[i].number); /* 输出姓名、学号*/ for(j=0;j<4;j++) printf("%7.2f|",arr[i].score[j]);/*输出三科成绩及三科的平均*/ printf("\n"); printf("---------------------------------------------------\n"); } } 第六步,求解组内学生单科平均成绩并输出。在输出表格的最后一行,输出单科平均成绩及总平均。 void out_row(arr,n) /*对n个元素的结构体类型数组求单项平均*/ int n; struct stu arr[]; { float row[4]={0,0,0,0};/*定义存放单项平均的一维数组*/ int i,j; for( i = 0; i < 4; i++) { for(j=0; j<n; j++) row[i] = row[i] + arr[j].score[i]; /* 计算单项总和*/ row[i]=row[i]/n; /* 计算单项平均*/ } printf("|%19c|",’ ’); /* 按表格形式输出*/ for (i=0;i<4;i++) printf("%7.2f|",row[i]); printf("\n------------------------------------------\n"); } 第七步,定义main( )函数,列出完整的程序清单。 #include <stdlib.h> #include <stdio.h> struct stu { char name[20]; long number; float score[4]; } ; main( ) { void input(); /*函数声明*/ void aver(); void order(); void output(); void out_row(); struct stu stud[4]; /* 定义结构体数组*/ float row[3]; input(stud, 4); /*依此调用自定义函数*/ aver(stud,4); order(stud,4); output(stud, 4); out_row(stud,4); } /****************************/
void input(arr,n) struct stu arr[]; int n; { int i,j; char temp[30]; for (i=0;i<n;i++) { printf("\nInput Name,Number,English,Mathema,Physic\n"); gets(arr[i].name); gets(temp); arr[i].number=atol(temp); for(j=0;j<3;j++) { gets(temp); arr[i].score[j]=atoi(temp); } } } / *****************************************/ void aver(arr,n) struct stu arr[]; int n; { int i,j; for(i=0;i<n;i++) { arr[i].score[3]=0; for(j=0;j<3;j++) arr[i].score[3]=arr[i].score[3]+arr[i].score[j]; arr[i].score[3]=arr[i].score[3]/3; } } /*********************************************/ void order(arr,n) struct stu arr[]; int n; { struct stu temp; int i,j,x,y; for(i=0;i<n-1;i++) for(j=0;j<n-1-i;j++) if (arr[j].score[3]>arr[j+1].score[3]) { temp=arr[j]; arr[j] = arr[j+1]; arr[j+1]=temp; } } /**********************************************/ void output(arr,n) int n; struct stu arr[]; { int i,j; printf("********************TABLE********************\n"); printf("-------------------------------------------------\n"); printf("|%10s|%8s|%7s|%7s|%7s|%7s|\n","Name","Number","English","mathema","physics","average"); printf("-------------------------------------------------\n"); for (i=0;i<n;i++) { printf("|%10s|%8ld|",arr[i].name,arr[i].number); for(j=0;j<4;j++) printf("%7.2f|",arr[i].score[j]); printf("\n"); printf("----------------------------------------------\n"); } } /*********************************************/ void out_row(arr,n) int n; struct stu arr[]; { float row[4]={0,0,0,0}; int i,j; for(i=0;i<4;i++) { for(j=0;j<n;j++) row[i]=row[i]+arr[j].score[i]; row[i]=row[i]/n; }
printf("|%19c|",’ ’); for (i=0;i<4;i++) printf("%7.2f|",row[i]); printf("\n-------------------------------------------------------\n"); } 运行程序: Input Name,Number,English,Mathema,Physic Liping 1 78 98 76 Input Name,Number,English,Mathema,Physic Wangling 2 66 90 86 Input Name,Number,English,Mathema,Physic Jiangbo 3 89 70 76 Input Name,Number,English,Mathema,Physic Yangming 4 90 100
********************* T A B L E ************************ --------------------------------------------- | Number| Name|English| Mathema| Physics| Average| --------------------------------------------- | Yangming| 4| 90.00| 100.00| 67.00| 85.67| --------------------------------------------- | Liping | 1| 78.00| 98.00| 76.00| 84.00| --------------------------------------------- | Wangling| 2| 66.00| 90.00| 86.00| 80.72| --------------------------------------------- | Jiangbo | 3| 89.00| 70.00| 76.00| 78.33| --------------------------------------------- | | 80.75| 89.50| 76.25| 82.18| --------------------------------------------- 程序中要谨慎处理以数组名作函数的参数。由于数组名作为数组的首地址,在形参和实参结合时,传递给子程序的就是数组的首地址。形参数组的大小最好不定义,以表示与调用函数的数组保持一致。在定义的结构体内,成员score [3]用于表示计算的平均成绩,也是我们用于排序的依据。我们无法用数组元素进行相互比较,而只能用数组元素的成员score[3]进行比较。在需要交换的时候,用数组元素的整体包括姓名、学号、三科成绩及平均成绩进行交 换。在程序order()函数中,比较采用: arr[j].score[3]>arr[j+1].score[3],而交换则采用: arr[j] <------> arr[j+1]
|