一. 實驗任務
某班有最多不超過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\n", 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\n", 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\t%-15s%5d\n", 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\n", 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\t%lf%%\n", 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