基于C语言实现(控制台)体育项目管理系统

体育竞赛项目管理

一、概述

1.1 目的

程序设计能力是当代理工类大学生的必备能力,当学生学习了C语言之后,编程能力远远不能达到开发实际应用程序的要求,特备是对其中的指针、结构体、链表和文件部分的理解和应用都比较弱。程序设计的目的是通过对面向过程的学习,将C语言的主要知识点进行综合,针对提高学生C语言程序设计能力,通过调试典型例题或习题积累调试C程序的经验;通过完成辅导教材中的编程题,逐渐培养学生的编程能力、用计算机解决实际问题的能力,强化编写较大的应用软件能力,熟练运用已掌握的知识解决实际需要解决的问题,以达到更加熟知指针、链表、结构体、文件读取、标准库的使用。

主要目的为以下几点:

  • 熟练掌握面向过程(结构化)程序设计基本知识;
  • 综合运用所学知识解决实际问题;
  • 受到面向过程(结构化)程序设计的基本训练;
  • 体会面向过程(结构化)开发程序的过程;
  • 进一步掌握和利用C语言进行程设计的能力;
  • 进一步理解和运用结构化程设计的思想和方法;
  • 学会利用流程图或N-S图表示算法;
  • 掌握书写程设计开发文档的能力(书写课程设计报告);

1.2 课程设计的组成部分

  • 由老师补充课程设计中要用到而课堂没有讲授的技能。补充有关链表的实现、C语言工程的创建与管理、头文件和实现代码的分离等编程技能;
  • 公布设计的题目
    体育竞赛项目管理程序,提供记录参赛项目信息、增、删、改、查,分类统计等功能。
    • 数据结构,建立体育项目记录链表(单向/双向),记录项包括:项目序号、项目名称、项目类、参赛人数、竞赛时间等。如果照顾检索速度,也可以建立分类索引表。
    • 增加记录,采用头插法、尾插法或者定点插入。
    • 修改和删除功能,基于查询进行。采用记录遍历即可。
  • 对所公布设计的题目进行需求分析,开始着手编写代码;
  • 撰写课程设计报告,最终提交程序和报告。

二、体育项目管理系统设计的内容

2.1 主函数的结构

2.2 用户的需求分析:

体育竞赛项目管理程序面向的用户群体分为项目管理者对于管理者,由于工作上的需求,系统对管理者开放全部功能,包括“添加数据”、“查找数据”、“删除数据”、“修改信息”、“输出数据”、“简略信息”等全部版块的功能。

2.3 版块设计:

  1. 系统用户选择界面:因为是对管理者直系使用,所以在主页面开放全部功能。

管理者页面

(管理者页面)

流程图解析:在用户成功进入到“用户页面”后,会有8项功能可以选择:

1>. 录入运动会项目信息

2>. 查找某个运动会项目信息

3>. 修改某个运动会项目信息

4>. 删除某个运动会项目信息

5>. 添加某个运动会项目信息

6>. 输出运动会项目信息

7>. 输出运动会简略项目信息

0>. 退出管理系统 。

在管理者进行“添加数据、删除数据”的操作后,系统会自动进行“项目号排序”操作,目的是为了方便用户对项目的进一步管理;但是在进行“修改项目号”后,不会进行“成绩排序”操作, 2.用户在进行完对“项目管理”的相关工作后,要及时进行“保存信息”操作,否则系统默认“不保存”。

页面代码:

printf("\n\n");
printf("===================校运动会项目管理系统==================\n");
printf("* 作者:孙某 班级:自动化201 学号:202002070115            *\n");
printf("*                                                       *\n");
printf("*          1>. 录入运动会项目信息                       *\n");
printf("*          2>. 查找某个运动会项目信息                   *\n");
printf("*          3>. 修改某个运动会项目信息                   *\n");
printf("*          4>. 删除某个运动会项目信息                   *\n");
printf("*          5>. 添加某个运动会项目信息                   *\n");
printf("*          6>. 输出运动会项目信息                       *\n");
printf("*          7>. 输出运动会简略项目信息                   *\n");
printf("*          0>. 退出管理系统                             *\n");
printf("*                                        欢迎使用本系统!*\n");
printf("=========================================================\n");
printf("输入选项,按回车进入选项:                                \n");

板块:

(用户页面)

2.4 查找函数

流程图说明:在用户选择“查找项目号”后,会先要求“输入项目号”操作,然后程序进行循环判断,“学号是否存在”,若存在则打印用户查找的项目号的全部数据,如学号不存在,则返回不存在,之后会返回至“应用主页面”。

查找代码:

void find(node *head,int a)
{
	int i=2;
	node *p=head;
	while(i>0 && p->num!='\0')
	{		
		if(p->num == a)
		{
			i-=2;
			printf("项目序号\t项目名称\t项目类  \t参赛人数\t竞赛时间\n");
			printf("%d\t\t",p->num);
			printf("%s\t\t",p->ming);
			printf("%c\t\t",p->lei);
			printf("%d\t\t",p->renshu);
			printf("%s\t\t\n",p->shijian);
		}
		else
		{
			if(p->next!=NULL)
				p=p->next;
			else
			{
				printf("未查找到");
				goto end;
			}
		}
	}
end:
	system("pause");
}

2.5 修改函数

流程图说明:在用户选择“查找项目号”后,会先要求“输入项目号”操作,然后程序进行循环判断,“学号是否存在”,若存在则选择修改的内选项,选项有项目序号、项目名称、项目类、参赛人数、竞赛时间。然后输入修改内容,修改成功后打印用户修改后项目号的全部数据,如学号不存在,则返回不存在,之后会返回至“应用主页面”。

修改代码:

node *xiugai(node *head,int a)
{	
	int i=2,j;
	node *p=head;
	while(i>0 && p->num!='\0')
	{		
		if(p->num == a)
		{
			printf("已经找到位置,选择修改项,\n1.项目序号\n2.项目名称\n3.项目类  \n4.参赛人数\n5.竞赛时间");
			scanf("%d",&j);
			switch(j)
			{
				case 1:printf("输入修改内容;"); 
						scanf("%d",&p->num);
						 break;
				case 2:printf("输入修改内容;"); 
						scanf("%s",&p->ming);
						 break;
				case 3:printf("输入修改内容;"); 
						scanf("%s",&p->lei);
						break;
				case 4:printf("输入修改内容;"); 
						scanf("%d",&p->renshu);
						break;
				case 5:printf("输入修改内容;"); 
					scanf("%s",&p->shijian);
					break;
			}
			printf("\n修改完毕\n");
			i-=2;
			printf("项目序号\t项目名称\t项目类  \t参赛人数\t竞赛时间\n");
			printf("%d\t\t",p->num);
			printf("%s\t\t",p->ming);
			printf("%c\t\t",p->lei);
			printf("%d\t\t",p->renshu);
			printf("%s\t\t\n",p->shijian);
		}
		else
		{
			if(p->next!=NULL)
				p=p->next;
			else
			{
				printf("未查找到");
				goto end;
			}
		}
	}
end:
	system("pause");
	return head;
}

2.6 删除函数

流程图说明:在用户选择“删除项目号”后,会先要求“输入项目号”操作,然后程序进行循环判断,如果头结点为空,则链表内无信息,返回空;如不为空判断“学号是否存在”,若存在则删除所选项目号所有内容,删除成功后打印用户修改后项目号的全部数据,如学号不存在,则返回不存在,之后会返回至“应用主页面”。

删除代码:

node  *del(node *head,int a)
{ 
	node *p1,*p2;
   if(head==NULL)
   {
	   printf("\n 空 \n");
	   goto  end; 
   }
   p1=head->next;
   while(a!=p1->num && p1->next!=NULL)
   {
	   p2=p1; p1=p1->next; 
   }
   if(a==p1->num)
   { 
	   if(p1==head) 
		   head=p1->next;
       else p2->next=p1->next;
       printf("已删除的项目号为: %d\n",a);
	   o--;
    }
   else printf("%d 没有被发现 ! \n",a);
    
 end: system("pause");
	  return(head);	   
}

2.7 添加函数

流程图说明:在用户选择“添加项目号”后,会先要求“输入项目号以及项目号的全部信息”操作,然后程序进行循环判断,如果头结点为空,则链表内无信息,将输入的信息插入第一个位置;如不为空判断“项目号的大小”,进行循环判断,将数据插入p指针的前面,如果p指针的next指向NULL,则将数据插入最后一个位置,之后会返回至“应用主页面”。

添加代码:

node  *ins(node *head, node *stud)
{ node  *p0, *p1, *p2;
  p1=head;         
  p0=stud;
  o++;
  if(head==NULL)      
    {head=p0; p0->next=NULL; }   
  else
    {
	  while((p0->num>p1->num) && (p1->next!=NULL))
      {
		  p2=p1;                   
           p1=p1->next; 
	  }    
      if(p0->num<=p1->num)
      { 
		  if(head==p1)
		  {
			  head=p0; 
		  }
          else 
			p2->next=p0;   
          p0->next = p1; 
	  }
       else {p1->next=p0; p0->next=NULL; } 
     };           
  return head;
  printf("已添加");
  system("pause");
}

2.8 输出函数

流程图说明:在用户选择“输出项目号”后,系统判断头结点是否为空,不为空则返回链表,每行为一个项目号及其全部信息,若为空,则返回空,告知用户,该链表无数据。

输出代码:

void putlist(node *head)
{
	int i=0;node *p;
	printf("项目序号\t项目名称\t项目类  \t参赛人数\t竞赛时间\n");
	if(head==NULL)
	{
		printf("空");
		return;
	}
	p=head->next;
	do
	{
		printf("%d\t\t",p->num);
		printf("%s\t\t",p->ming);
		printf("%c\t\t",p->lei);
		printf("%d\t\t",p->renshu);
		printf("%s\t\t\n",p->shijian);

		p=p->next;
	}while(p!=NULL);
	printf("输出完毕");
	system("pause");
}

2.9 输出运动会的简略信息

流程图说明:在用户选择“输出简略信息”后,循环对每个节点的人数进行相加,输出sum总人数,同时调取全局变量o记录的头结点数,打印到用户页面上。

输出简略信息代码:

int numb(node *head)
{
	node *p=head;
	int sum=0;
	while(p->next)
	{
		p=p->next;
		sum+=p->renshu;
	}
	return sum;
}

三、总结

3.1 课程设计进行过程及步骤

选择编译环境

选择的是开发工具:Microsoft  Visual  C++  6.0

分析题目

体育竞赛项目管理程序,提供记录参赛项目信息、增、删、改、查,分类统计等功能。

  • 数据结构,建立体育项目记录链表(单向/双向),记录项包括:项目序号、项目名称、项目类、参赛人数、竞赛时间等。如果照顾检索速度,也可以建立分类索引表。
  • 增加记录,采用头插法、尾插法或者定点插入。
  • 修改和删除功能,基于查询进行。采用记录遍历即可。

题目分析结果:

首先要建立结构体,包含(项目序号、项目名称、项目类、参赛人数、竞赛时间)的信息,在结构体内项目序号使用int型、项目名称使用字符串char[]型、项目类使用char型、参赛人数int型、竞赛时间char[]。

分析所需要调用的子函数:

node *creatlist();     	创建链表
void putlist();		  	输出链表
node *del();  			删除节点
void find();		   	查找节点
node *ins();		 	添加节点
node *xiugai();		修改节点数据
int numb();			返回总人数

而后分析所需要写的代码:

开始写创建链表和输出链表(node *creatlist();和void putlist();))部分的内容,创建和输出作为整个程序的基础,在书写完创建和输出函数之后进行调试,调试成功之后再继续写下面的子函数,以防止最后的时候出现大量错误,无从下手去改。

在创建和输出写完之后,就开始写查找函数,节点修改函数,删除节点函数(node *del();  void find();  void find(); ),这三个相对于添加函数,逻辑简单,书写完之后不容易报错。

而后书写添加节点(node *ins();),对添加节点先要有逻辑判断,判断节点应该添加的位置,怎么用c语言实现位置的判断,是添加在开始,还是中间,或者是末尾,这三种不同的添加方式有不同的代码要写,逻辑思考完成之后,再开始书写添加节点的代码。

最后添加一些便携的工具类似于总人数计算(int numb();)和数据条数(全局变量o)。

测试各项功能

对每一个子函数进行测试,包括(node creatlist(); void putlist(); nodedel();void find();node ins(); node xiugai();int numb();) 测试完后修改错误的部分,确保写的代码可以跑起来。

对整个程序的主题进行构建

搭建一个简明的主页和全部的主题页面,我在网上找到了一个比较简洁的页面如下

===================校运动会项目管理系统==================
*                                                    *
*                                                    *
*          1>. 录入运动会项目信息                      *
*          2>. 查找某个运动会项目信息                   *
*          3>. 修改某个运动会项目信息                   *
*          4>. 删除某个运动会项目信息                   *
*          5>. 添加某个运动会项目信息                   *
*          6>. 输出运动会项目信息                      *
*          7>. 输出运动会简略项目信息                   *
*          0>. 退出管理系统                            *
*                                        欢迎使用本系统!*
=========================================================

输入选项,按回车进入选项:

同时为了页面的简洁我还选用了system(“cls”);,这是windows自带的清屏代码

对整体进行白盒和黑盒测试

从正常方式调取每一个函数,对整个程序进行测试,然后从一些不怎么会使用的方式调取,以确保整体的稳定性。

3.2 所遇到的问题与解决

对指针的地址和值的应用错误

在开头定义了node *head=NULL;

在之后调用别的函数想要传递指针head,我使用了head=creatlist(head);,这里的head是已经取了head的值,但是我想调用的是指针head,这个错误在vc++ 6.0中是不会报错的,程序也能运行起来,然而在录入项目的循环中会直接崩溃,如图所示:

在老师的指正下,我意识到了这个问题,并且将调用改为调用head的地址:head=creatlist(head),修改之后就可以运行了,如图所示:

并且在输出链表中也可以输出,如图所示:

查找函数无法查找链表的最后一个

对最后一个位置的判断有问题;最后一个节点p->next=NULL;

一开始错误的代码:

while(p->next!=NULL)
	{		
		if(p->num == a)
		{
			printf("项目序号\t项目名称\t项目类  \t参赛人数\t竞赛时间\n");
			printf("%d\t\t",p->num);
			printf("%s\t\t",p->ming);
			printf("%c\t\t",p->lei);
			printf("%d\t\t",p->renshu);
			printf("%s\t\t\n",p->shijian);
		}
		else
		{
			if(p->next!=NULL)
				p=p->next;
			else
			{
				printf("未查找到");
				goto end;
			}
		}
	}

输出链表中有项目序号2

查找时查询不到项目序号2,如图所示:

这种情况的发生是因为只要p->next不等于NULL,从而 p=p->next=NULL,就不会对最后一个节点的数据进行判断p->num == a,也就不能够查到最后一个节点的项目号。

查找项目序号1时则会无限循环,如图所示:

这种情况的发生因为p->num == a则不会发生p=p->next,从而无限次循环,一直输出项目序号1及其全部数据。

在多次的测试之后,引入了变量i,改变了判断条件,使其不会循环输出,并且能够判断最后一个。代码如下

while(i>0 && p->num!='\0')
	{		
		if(p->num == a)
		{
			i-=2;
			printf("项目序号\t项目名称\t项目类  \t参赛人数\t竞赛时间\n");
			printf("%d\t\t",p->num);
			printf("%s\t\t",p->ming);
			printf("%c\t\t",p->lei);
			printf("%d\t\t",p->renshu);
			printf("%s\t\t\n",p->shijian);
		}
		else
		{
			if(p->next!=NULL)
				p=p->next;
			else
			{
				printf("未查找到");
				goto end;
			}
		}
	}

修改完之后则可以查询到项目序号1不循环,也可以查询到项目序号2并且全部输出。

如下图所示:

3.3 体会收获及建议

学习C程序这门课一年了,这是我们学的第一门专业课,在大学里C语言不但是自动化专业的必修课程而且也是一些非计算机专业学习计算机基础的一门必修课程。所以作为我这个自动化专业的学生来说当然十分重要。C语言是计算机的基础,大多数软件都需要用C语言来编写,通过上个学期的学习,使我由初步掌握简单的应试知识到完成高难度的深入编程,课程设计便是一个完成c语言高级一些的编程,在这个课程中,我认识到我们在编写一个较大的程序时应该把它分开成几个小程序来看,这样会容易得多。同时,我觉得C语言应该是操作和理论相结合的课程,在不断地编写中去思考,两者是不可分割的。

要了解C语言就要从语法基础来学习起,首先要是要了解它的结构,比如变量,首先要了解变量的定义方式,其意义是什么;其次就是要我要怎么去运用它。在C语言的命令行中所有的语句都是有它自己的一定格式和形式出现在我们面前,所以我们在学习某种语句或命令时你首先要了解的就是它的规则是什么、有什么用、怎么实现等。这些都是语法基础也是C语言的基础。

在这次的课程设计中我多次使用 p 和 p 这两种条件语句都是指针的一种形式,什么时侯用 p 什么时侯用 p 是一个我原来不掌握的知识,*p是取p的值,p是p的地址,在调用的时候如果选择错了,则vc++ 6.0的运行环境编译的时候不会报错,在运行的时候却会因为调用错误而导致程序崩溃,所以在使用指针调用的时候要注意这一点。

课程设计的主要特点是“综合性强”,这使得我对之前学过的知识进行了一次完美的复习,应用最多的是“模块化函数”和“单链表”,同时,也将之前学过的一些知识进行“串联”,各个子函数之间,子函数与主函数之间的连接问题,我采取“switch--case”将各子函数与主函数相连接,某些存在“顺序结构”的子函数让我更加熟练地掌握了以前所学的知识,尤其是单链表方面的知识。

其次,课程设计的另一个特点“实践性强”,这一点对于我来说尤其重要,古话常说“纸上得来终觉浅,绝知此事要躬行。”,平时理论知识的学习固然重要,但是将理论知识应用于实际程序中,这是更加重要的,尤其是对于C语言的初学者来说,是至关重要的。通过本次的课程设计,可以说,我将之前的一些知识,包括“文件、单链表、结构体等等”,实际运用在设计程序上,这使得我对理论知识有了更加深刻的印象。

最后,课程设计的过程中还一直体现着“逻辑性强”,这一点体现在课程设计中的方方面面,小到“子函数的功能”,例如排序函数,查找函数的子函数,大到“功能主函数之间的连接”,功能主函数之间的连接,以及顺序结构,都需要及其严谨,倘若出现问题,虽然在语法上没有错误,但是“不能满足用户的需求”。通过这次的课程设计,我深刻的体会到“我的逻辑能力得到了很大的提高”。

内容概要:本文介绍了利用Matlab代码实现处理IMU、GPS传感器数据的多种姿态解算算法,重点包括卡尔曼滤波和扩展卡尔曼滤波等技术,旨在提升导航系统的精度与稳定性。通过对传感器数据进行融合与滤波处理,有效解决了惯性导航系统中存在的累积误差问题,提高了动态环境下的姿态估计准确性。文章还提供了完整的算法实现流程和仿真验证,展示了不同滤波方法在实际应用场景中的性能对比。; 适合人群:具备一定Matlab编程基础,从事导航、控制、机器人或自动驾驶等相关领域研究的科研人员及工程技术人员,尤其适合研究生及以上学历或有相关项目经验的研发人员。; 使用场景及目标:①应用于无人机、无人车、机器人等自主导航系统中的姿态估计;②用于教学与科研中对滤波算法的理解与改进;③帮助开发者掌握IMU【处理IMU、GPS传感器】现了多种姿态解算算法,如卡尔曼滤波、扩展卡尔曼滤波等,以提高导航系统的精度和稳定性(Matlab代码实现)/GPS融合算法的设计思路与实现技巧,提升系统鲁棒性与定位精度。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,逐步调试并理解各算法模块的作用,重点关注传感器数据预处理、状态方程构建、噪声协方差调节及滤波结果分析等关键环节,以达到深入掌握姿态解算核心技术的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神仙别闹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值