// Written by Harry
最近学习了郝斌老师的C语言课程,2009年的视频,共180节课,视频虽早,但使我获益匪浅,学生成绩管理系统是老师在十一年前课堂上留的一个作业,让同学们在家自己复现成绩管理系统,于是就想自己动手来完成它,并记录在CSDN中,代码间穿插了自己的理解注释,方便未来回顾。
功能介绍:利用结构体完成学生信息的录入 - 排序 - 输出
一、第一种方式
在主函数实现全部功能,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct student //定义结构体
{
char name[100]; //定义一个长度为100的数组,数组中每个空间存放一个char字符,整体数组要形成字符串,形成学生的完整名字
float score;
};
int main()
{
int i,j,len;
struct student *pArr; //定义一个结构体指针,只用来存放结构体的数组
struct student tem;
//学生信息输入
printf("请输入学生的个数:len = "); //读取学生个数
scanf("%d",&len);
pArr = (struct student *)malloc(len*sizeof(struct student)); //构造动态一维数组,空间大小为(学生人数 * 单个结构体大小)
//注意:pArr是指针,指向以pArr为名字的一个数组首元素地址,pArr[i]表示数组中的元素,每个元素是一个结构体,每个结构体变量名为pArr[i]
printf("\n");
for(i=0;i<len;i++)
{
printf("请输入第%d个学生的姓名:",i+1);
scanf("%s",pArr[i].name);
/* 上面语句中pArr[i].name前不加取地址符,因为先前定义结构体时,已经将name定义为其中的数组类型,
用来存放该数组中的字符以致整体数组最后要形成字符串,name已经是首元素地址。
该语句表示给pArr数组中的i结构体中的name变量赋值,实际上计算机内部是一个char一个char进入name数组空位中的 */
printf("\n");
printf("请输入第%d个学生的分数:",i+1);
scanf("%f",&pArr[i].score); //表示给 p数组 中的 i结构体 中的 score变量 赋值
printf("\n");
}
//学生信息排序(这里使用冒泡排序)
for(i=0;i<len-1;i++)
{
for(j=0;j<len-1-i;j++)
{
if(pArr[j].score < pArr[j+1].score)
{
tem = pArr[j];
pArr[j] = pArr[j+1];
pArr[j+1] = tem;
}
}
}
//学生信息输出
printf("--------------------------------------\n");
printf("学生成绩排名为:\n\n");
for(i=0;i<len;i++)
{
printf("第%d名 姓名:%s 分数:%.1f\n", i+1, pArr[i].name, pArr[i].score);
}
printf("--------------------------------------\n");
free(pArr); //释放动态内存
return 0;
}
运行结果如下:
二、第二种方式
定义功能不同的函数,利用指针传递实参解决问题,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct student //定义结构体
{
char name[100];
float score;
};
void student_input(struct student *pArr, int len) //定义学生信息输入函数
{
int i;
for(i=0;i<len;i++)
{
printf("请输入第%d个学生的姓名:",i+1);
scanf("%s",pArr[i].name);
printf("\n");
printf("请输入第%d个学生的分数:",i+1);
scanf("%f",&pArr[i].score);
printf("\n");
}
}
void bubble_sort(struct student *pArr, int len) //定义学生信息排序函数,这里使用冒泡排序
{
int i,j;
struct student tem;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-1-i;j++)
{
if(pArr[j].score < pArr[j+1].score)
{
tem = pArr[j];
pArr[j] = pArr[j+1];
pArr[j+1] = tem;
}
}
}
}
void student_output(struct student *pArr,int len) //定义学生信息输出函数
{
int i;
printf("------------------------------------\n");
printf("学生成绩排名为:\n\n");
for(i=0;i<len;i++)
{
printf("第%d名 姓名:%s 分数:%.1f\n", i+1, pArr[i].name, pArr[i].score);
}
printf("------------------------------------\n");
}
int main()
{
int len;
struct student *pArr; //定义一个结构体指针,只用来存放结构体的数组
printf("请输入学生的个数:len = "); //读取学生个数
scanf("%d",&len);
pArr = (struct student *)malloc(len*sizeof(struct student)); //构造一维动态数组
printf("\n");
student_input(pArr,len); //学生信息输入
bubble_sort(pArr,len); //学生信息排序
student_output(pArr,len); //学生信息输出
free(pArr); //释放动态内存
return 0;
}
运行结果如下:
三、总结
最后一种方式好,利用各部分函数分块实现功能使代码清晰易懂,可读性更强,也有利于程序的模块化调试。