一. 实验任务
某班有最多不超过30人(具体人数由键盘输入)参加某门课程的考试,参考例题10.4,用二维字符数组作函数参数(存放姓名),编程实现如下学生成绩管理:
-
录入每个学生的学号、姓名和考试成绩
-
计算课程的总分和平均分
-
按成绩由高到低排出名次表
-
按成绩由低到高排出名次表
-
按学号由小到大排出成绩表
-
按姓名的字典顺序排出成绩表
-
按学号查询学生排名及考试成绩
-
按姓名查询学生的排名及考试成绩
-
按优秀(90~100)、良好、中等、及格、不及格5个类别,统计每个类别的人数以及所占的百分比。
- 输出每个学生的学号、姓名、考试成绩,输出课程总分和平均分。
二. 实验分析
- 输入带空格的字符串,采用函数gets(一维字符数组名); 输出字符串,printf(“%s”, 一维字符数组名)或者puts(一维字符数组名);
- 用函数指针来实现功能3、4中成绩的升序和降序排列。
- 如何完成二维数组中行与行的交换?循环?最方便的是采用字符串处理函数strcpy(str1,str2),所以这里还需要一个交换过程中需要的中间数组,char tempary[M]。
- 二维数组的处理
实际上,二维数组在C语言中是当成一维数组来处理的,每一行就是一个元素,特殊的是它的每一个元素又是一个一维数组 。
数组是一个类型,数组类型是一组具有相同类型的变量的集合。例如:int [],表示一组int类型的变量的集合。那么,组成数组的元素同样也可以是数组类型的变量,例如: char a[N][M],首先它是一个名为a,元素个数为N个的一维数组,那么它的基类型是一个:基类型为char类型、元素个数为M个的数组类型,如下图所示:
a[i]是第i个数组元素的元素名,但是第i个元素又是一个数组,所以a[i]也就是这个数组的数组名,它的各个元素分别是a[i][0],a[i][...]。
总结:二维数组char a[N][M]中,a是数组名,a[i]是数组a的第i个元素,但是同时又是另外一个数组的数组名。
所以,如果要输入一个字符串给二维数组的某行,应该这么写:
gets(a[i]); //表示a[i]输入字符串
如果要对二维数组的行进行操作,实际就是对a的各个元素操作,直接用a[i]即可。例如:
strcmp( a[j] , a[k] ); //比较a[j] 行和 a[k] 行的字符串
strcpy( a[i] , a[k] ); //将a[k] 行的字符串复制到a[i]
//假定成绩均为整数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 40
void Swap(int *a, int *b);//交换数据
void StrSwap(char *a, char *b);//交换姓名
double Average(int score[], int n);//求平均数
void Read(char name[][N], int num[], int score[], int n);//输入数据
void Print(char name[][N], int num[], int score[], int n);//输出数据
int Ascending(int a, int b);//升序排列
int Descending(int a, int b);//降序排列
int Alphabetical(char *a, char *b);//按姓名字典序排列
void Find(char name[][N], int num[], int score[], int n, int id, char na[]);//检索,id为检索学号,na[]为检索姓名
void Sort(char name[][N], int num[], int score[], int n, int (*compare)(), int cmp[], int op);
//排序,用无函数参数的指针以便名字字典序排序也在这里搞定
//cmp记录现在是要按哪个数组排序
//op为1表示现在要按名字字典序排序
void Account(int score[], int n);//统计分析
int main(void)
{
int choice, n = 0, i;
int num[N], id, score[N];
char name[N][N], na[N];
double sum = 0, aver;
do{
puts("");
puts("1.Input score, ID and name");
puts("2.Caculate total and average score of course");
puts("3.Sort in descending order by score");
puts("4.Sort in ascending order by score");
puts("5.Sort in ascending order by number");
puts("6.Sort in alphabetical order by name");
puts("7.Search by number");
puts("8.Search by name");
puts("9.Statistic analysis");
puts("10.List record");
puts("0.Exit");
printf("Please enter your choice:");
scanf("%d", &choice);
switch(choice)
{
case 0:break;
case 1:
printf("Please enter the number of students:");
scanf("%d", &n);
puts("Please enter student's score, ID and name:");
puts("Attention: Score, ID, Name");
Read(name, num, score, n);
break;
case 2:
sum = Average(score, n);
aver = sum / n;
printf("sum = %lf, aver = %lf
", sum, aver);
break;
case 3:
Sort(name, num, score, n, Descending, score, 0);
Print(name, num, score, n);
break;
case 4:
Sort(name, num, score, n, Ascending, score, 0);
Print(name, num, score, n);
break;
case 5:
Sort(name, num, score, n, Ascending, num, 0);
Print(name, num, score, n);
break;
case 6:
Sort(name, num, score, n, Ascending, num, 1);
Print(name, num, score, n);
break;
case 7:
Sort(name, num, score, n, Descending, score, 0);
printf("Please Input the ID:");
scanf("%d", &id);
Find(name, num, score, n, id, "");
break;
case 8:
Sort(name, num, score, n, Descending, score, 0);
puts("Please Input the name:");
fflush(stdin);//清空缓存区
gets(na);
Find(name, num, score, n, -1, na);
break;
case 9:
Account(score, n);
break;
case 10:
Print(name, num, score, n);
sum = Average(score, n);
aver = sum / n;
printf("sum = %lf, aver = %lf
", sum, aver);
}
}while(choice);
return 0;
}
void Read(char name[][N], int num[], int score[], int n)
{
int i;
for(i = 1; i <= n; ++i)
{
scanf("%d %d", &score[i], &num[i]);
getchar();
gets(name[i]);
}
return ;
}
void Print(char name[][N], int num[], int score[], int n)
{
int i;
for(i = 1; i <= n; ++i)
printf("%d %-15s%5d
", num[i], name[i], score[i]);
return ;
}
double Average(int score[], int n)
{
int i, sum = 0;
for(i = 1; i <= n; ++i)
sum += score[i];
return sum;
}
int Ascending(int a, int b)
{return a < b;}
int Descending(int a, int b)
{return a > b;}
int Alphabetical(char *a, char *b)
{return strcmp(a, b) < 0;}
void Sort(char name[][N], int num[], int score[], int n, int (*compare)(), int cmp[], int op)
{
int i, j, k;
for(i = 1; i < n; ++i)
{
k = i;
for(j = k+1; j <= n; ++j)
if((op && Alphabetical(name[j], name[k])) || (!op && (*compare)(cmp[j], cmp[k])))
k = j;
if(k != i)
{
Swap(num+i, num+k);
Swap(score+i, score+k);
StrSwap(name[i], name[k]);
}
}
return ;
}
void Find(char name[][N], int num[], int score[], int n, int id, char na[])
{
int i;
for(i = 1; i <= n; ++i)
if(!strcmp(name[i], na) || num[i] == id)
break;
if(i == n+1){puts("Not find!");return ;}
printf("The rank is:%d, the score is:%d
", i, score[i]);
return ;
}
void Swap(int *a, int *b)
{
int c;
c = *a;*a = *b;*b = c;
return ;
}
void StrSwap(char a[], char b[])
{
char c[N];
strcpy(c, a);
strcpy(a, b);
strcpy(b, c);
}
void Account(int score[], int n)
{
char grade[5]={'E','D','C','B','A'};
int i,peo[5]={0};//每个类别的人数。0不及格,1及格,
for(i=1; i<=n; ++i)
{
if(score[i] == 100)++peo[4];
if(score[i] >= 60)
++peo[(int)(score[i]/10)-5];
else ++peo[0];
}
for(i=4; i>=0; --i)
printf("grade %c: %d %lf%%
", grade[i], peo[i], 100.0*peo[i]/n);
}
数据
10
85 01 lihua
77 02 yang
87 03 su
66 04 tao
58 05 liang
58 06 gong
70 07 fu
90 08 yan
82 09 he
100 10 nie