前言
事先声明:本文章中编写的代码仅用于初学者用于加深巩固c语言的基础语法和扩展能力,并未进行太多的代码优化,因此,若需要对代码进行优化以及异常处理的小伙伴们,可自行添加相关操作,谢谢!
一、题目描述
比赛规则
1 学校举行一场比赛,共有n个人参加
2 将选手信息录入后,整体按照选手进行随机抽签后产生上场顺序
3 五个评委分别给每名选手打分,去除最高分和最低分,求的平均分为该选手的成绩
4 前三名胜出,比赛过后需要显示晋级选手的信息
二、需求分析
一、问题概述
本系统设计旨在模拟学校举办的各种比赛流程,实现一个基于C语言的比赛流程管理系统。系统需要处理包括选手学号、评分、淘汰和晋级在内的各个环节,并能够在比赛结束后显示获胜选手的信息。
二、系统目标
1.实现选手信息管理:系统应能够存储和检索选手的信息。
2.实现抽签:系统能随机决定选手上场顺序。
3.实现评分机制:系统应能接收评委的评分,并自动计算选手的最终成绩。
4.实现信息显示功能:系统应能在每次比赛后显示晋级选手的信息和成绩。
5.实现最终信息存取功能:系统应能在每届比赛后保存该节比赛记录,并可查看往届记录。
6.代码可维护性:系统应具有良好的代码结构,方便后续维护和扩展。
三、总体设计
一、设计目标分析
本次课程设计的目标是开发一个基于C语言的比赛流程管理系统。该系统需要模拟学校比赛的流程,包括选手信息管理、随机排序、评分计算、淘汰晋级以及信息显示等功能。
二、基本思路
1.信息管理
1.使用结构体Student来存储每个选手的学号、姓名、电话以及评分。
2.定义一个Inf来封装选手信息,方便后续排序、保存以及展示。
3.定义一个Ed_data来封装最终获胜信息,方便后续保存并展示。
2.随机排序
1.应用洗牌算法对选手进行随机排序,确定选手比赛顺序。
2.然后按照抽签后的顺序,显示选手的信息。
3.评分计算
1.评委打的分数存储到结构体Student中的记录分数的数组中。
2.去除最高分和最低分,将平均分存储到结构体Student中的最终得分中。
4.淘汰晋级:
1.根据选手最终得分利用<stdlib.h>中的qsort(快速排序)函数进行排序。
2.前三名获得比赛胜利。
5.信息显示:
1.在比赛结束后,显示晋级选手的信息和成绩。
6.记录存取:
1.在每届比赛完后,将最终获胜选手的信息和成绩以文件的形式保存。
2.且想要查看时,也可调用文件进行查看往届比赛记录。
三、完成本次设计的完整过程
需求分析:明确系统需求,分析需要实现的功能。
总体设计:确定基本思路,规划程序结构,设计数据结构和算法。
详细设计:编写代码实现各个功能模块,包括选手信息管理、随机排序、评分计算、淘汰晋级和信息显示等。
代码实现:按照详细设计编写代码,并进行单元测试,确保每个模块的正确性。
系统集成:将各个模块集成到系统中,进行整体测试,确保系统能够正常运行。
四、详细设计
1、需要包含的头文件如下
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <assert.h>
2、涉及的功能函数的参数、功能以及返回值
void ShowScore(Inf* pc); //展示各参赛选手比赛分数
void LoadScore(Inf* pc); //录入各参赛选手比赛分数
void Loadpeople(Inf* pc); //加载成员信息至Student* data
void Destroypeople(Inf* pc); //释放Inf* pc中所开辟的动态内存
void Compmenu(); //比赛系统的菜单
void Membermenu(); //成员录入的菜单
void Initpeople(Inf* pc); //初始化(动态顺序表)成员信息
void Addpeople(Inf* pc); //增加成员信息
void Showpeople(Inf* pc); //展示成员信息
static int FindByName(Inf* pc, char name[]); //查找成员信息(用于删除 修改)
void Searchpeople(Inf* pc); //查找成员并展示信息
void Delpeople(Inf* pc); //删除成员信息
void Modifypeople(Inf* pc); //修改成员信息
void Savepeople(const Inf* pc); //保存本次参赛成员信息至文件
void randomSort(Inf* pc, int count); //对成员进行随机排序
void Checkscore(Inf* pc); //确认录入分数是否无误
void ComResult(const Inf* pc); //比较成员最终分数
void LoadRecord(Ed_data* pd); //加载成员信息至Student* record
int InitRecord(Ed_data* pd); //对比赛记录初始化
void SaveRecord(const Inf* pc); //保存比赛获胜记录至文件
void ShowRecord(const Ed_data* pd); //展示比赛获胜信息
void DestroyRecord(Ed_data* pd); //释放Ed_data* pd中所开辟的动态内存(后续可进行修改进而保存前m名成员的分数和信息)
void Competition(); //完整的比赛流程
void InitfRecord(Ed_data* pd); //创建文件并以写的形式打开来保存本次比赛获胜信息记录
void Openpeople(Inf* pc); //查看往届比赛参赛人员的信息
3、主要模块的功能实现
1.主函数框架的创建
int main()
{
Ed_data pt;
Inf pd;
int input1 = 0;
do
{
Compmenu();
printf("请选择->");
scanf("%d",&input1);
switch (input1)
{
case 1:
Competition();
printf("\n");
break;
case 2://查看往届比赛记录
InitfRecord(&pt);
ShowRecord(&pt);
break;
case 3://查看往届成员信息
Opendata(&pd);
Showpeople(&pd);
break;
case 0://退出比赛系统 (exit)
DestroyRecord(&pt);
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input1);
return 0;
}
2.随机排序
void randomSort(Inf* pc, int count) {
srand(time(0));
for (int i = count-1;i>=0;i--)
{
int j = rand()%(i+1);//生成随即交换位置
Student temp=pc->data[i];
pc->data[i]=pc->data[j];
pc->data[j]=temp;
}
Showpeople(pc);
return;
}
3.评分计算
void LoadScore(Inf* pc)
{
assert(pc);
int i = 0;
int j = 0;
int ret = 0;
for (i = 0; i < pc->count; i++)
{
float max = 0; float min = 100; float sum = 0;
printf("%s的分数为:>", pc->data[i].name);
for (j = 0; j < Judge; j++)
{
scanf("%f",&(pc->data[i].score[j]));
sum += (pc->data[i].score[j]);
if (max < (pc->data[i].score[j]))max = (pc->data[i].score[j]);
if (min > (pc->data[i].score[j]))min = (pc->data[i].score[j]);
if (j == Judge - 1)sum = sum - min - max;
}//去掉最高分最低分求平均分
float temp = sum / (Judge - 2);
pc->data[i].average = temp;
printf("学生分数录入成功\n");
printf("-----------------------------------------------\n");
}
printf("若成绩全部录入正确则输入: 1 否则输入: 0\n");
scanf("%d", &ret);
while (ret == 0)
{
Checkscore(pc);
printf("是否需要继续修改成绩 若需要则输入: 1 否则输入: 0\n");
scanf("%d",&ret);
}
}
4.淘汰晋级
int Cmpscore(const void* e1, const void* e2)
{
return (((((Student*)e2)->average) - (((Student*)e1)->average)) > 0);
}
qsort((&con)->data, (&con)->count, sizeof(Student), Cmpscore);
5.信息显示
void ShowScore(Inf* pc)
{
assert(pc);
int i = 0;
printf("%11s\t%20s\t%12s\t\n", "学号", "姓名", "分数");
for (i = 0; i < pc->count; i++)
{
printf("%9s\t%19s\t%12.2f\t\n",
pc->data[i].stuID,
pc->data[i].name,
pc->data[i].average);
}
}
6.记录存取
void Opendata(Inf* pc)
{
assert(pc);
pc->count = 0;
pc->data = (Student*)calloc(2 * pc->count, sizeof(Student));
if (pc->data == NULL)
{
printf("Initpeople::%s\n", strerror(errno));
return;
}
pc->capacity = 2 * pc->count;
Openpeople(pc);
}
void Openpeople(Inf* pc)
{
FILE* pfRead;
printf("输入您要打开的文件名:");
scanf("%s", yourfile_data);
pfRead = fopen(yourfile_data, "rb");
if (pfRead == NULL)
{
printf("创建文件成功。\n");
return;
}
Student tmp = { 0 };
while (fread(&tmp, sizeof(Student), 1, pfRead) == 1)
{
CheckCapacity(pc);
pc->data[pc->count] = tmp;
pc->count++;
}
fclose(pfRead);
pfRead = NULL;
}
总结
通过编写这个项目,我不仅学会了更多关于C语言知识,还提高了解决问题的能力、团队合作能力以及项目管理技能。