资源描述
课程设计(论文)
编 号:
学 号:
201040420120
课 程 设 计
教 学 院
计算机
课程名称
高级语言程序设计Ⅱ
题 目
学生成绩管理系统
专 业
网络工程
班 级
1班
姓 名
曹彦
同组人员
唐舸轩、蔡敏、黄伴、程良康、张雄峰
指导教师
谢晋
2013
年
1
月
7
日
目 录
一 概述 2
1. 课程设计的目 2
2. 课程设计的要求 2
二 总体方案设计 3
三 详细设计 4
3.1 程序功能描述 4
3.2 程序流程图 4
四 程序的调试与运行结果说明 5
4.1 程序源代码 5
4.2 调试并运行程序 18
五 课程设计总结 23
参考文献 24
一 概述
1. 课程设计的目的
1.理解和掌握该课程中的有关基本概念,程序设计思想和方法。
2.培养综合运用所学知识独立完成课题的能力。
3.培养勇于探索、严谨推理、实事求是、有错必改,用实践来检验理论,全方位考虑问题等科学技术人员应具有的素质。
4.掌握从资料文献、科学实验中获得知识的能力,提高学生从别人经验中找到解决问题的新途径的悟性,初步培养工程意识和创新能力。
2. 课程设计的要求
1.界面友好,函数功能要划分好
2.总体设计应画一流程图
3.程序要加必要的注释
4.要提供程序测试方案
5.程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行
的程序是没有价值的。二 总体方案设计
使用面向对象的程序设计方法,程序的功能主要包括:对学生成绩信息的增、删、查、改等基本功能,并能够按照学号或姓名及成绩等进行排序和筛选,使用文件进行数据的存储和维护,能够按照班级或专业进行分类的管理。
程序中使用了双向链表保存数据的底层数据结构,实现起来很简单。C++推荐使用标准库,这也是目前编程的方向,推荐此题目为本课程设计作为选做内容,可以根据实际教学情况决定,目的是使学生熟悉和了解C++的标准库。
本人负责部分:
1.删除一个学生的成绩记录:通过两个结点指针的使用来实现结点的删除,这两个指针分别是pNodepre,pNodeTal,其中pNodepre指针指向前一个结点,pNodeTal指针指向紧接的后一个结点,其中以pNodeTal指向的结点为基准进行比较,刚开始这两个结点分别指向第一个空结点和第一个实结点,若不满足姓名匹配,则两个指针同时向后移动一个单位,知道找到要删除的结点为止,当删除的结点是第一个实结点时,利用语句m_head->next = pNodeTal->next实现,若是最后一个结点用pNodepre->next = NULL语句实现,否则用pNodepre->next = pNodeTal->next语句实现。
2.计算学生成绩总和:每输入一个同学的一科成绩时,程序将这科成绩自动加到totalmark中,直到第五科成绩。
三 详细设计
3.1 程序功能描述
该程序完成的功能如下:
输入学生信息,由addstudent()函数完成
在查找学生信息时按名字查找,由searchbyname()函数完成
将学生成绩信息保存到指定路径的文档中,由save()函数完成
根据学生总成绩按降序排序,,由sortbymark()函数完成
根据学生姓名删除想要删除的学生信息,由Delete()函数完成
可根据姓名更改学生信息,由Change()函数完成
将文件信息保存到链表中,由readfiletolist()函数完成
添加学生信息,由addstudent()函数完成
从文件读取信息,由display()函数完成
10、显示学生信息,由show()函数完成
3.2 程序流程图
程序流程图如下:
保存学生信息在文件中并读取
可实现的功能
根据姓名查找学生信息
保存文件信息到链表中
根据姓名删除学生信息
计算总成绩并按此排序
输入学生信息
根据姓名修改学生信息
四 程序的调试与运行结果说明
4.1 程序源代码
完整的程序如下:
#include "stdafx.h"
#include "Student.h"
#include<iostream>
#include<string>
#include<fstream>
#include<cstdlib>
using namespace std;
enum {SUBJECT=5};//一共五门功课
typedef struct
{
char subject[10];//科目名称
int score;//科目成绩
}markinfo;
typedef struct studentnode
{
markinfo mark[SUBJECT];
int totalmark;
char name[10];//学生姓名
studentnode * next;
}studentnode;
class CStudent
{
public:
CStudent();
virtual ~CStudent();
int addstudent();
int countmark();
int sortbymark();
int save();
int show();
int display();
int readfiletolist();
int searchbyname();
int Delete();
int Change();
private:
studentnode *m_head;
};
CStudent::CStudent()
{
m_head = new studentnode;
m_head->next = NULL;
}
CStudent::~CStudent()
{
studentnode *pHead,*pTail;
pHead=m_head->next;
while(pHead)
{
pTail=pHead->next;
delete pHead;
pHead=pTail;
}
delete m_head;
}
//输入学生姓名,成绩等数据,并保存在链表中
int CStudent::addstudent()
{
studentnode *pStuNode;
int nCount;
char check;
system("cls");
cout<<"**********************"<<endl;
cout<<"请输入学生信息:"<<endl;
do
{
pStuNode=new studentnode;
cin.ignore();
cout<<"姓名:";
gets(pStuNode->name);
nCount=0;
pStuNode->totalmark=0;
do
{
cout<<"科目:";
gets(pStuNode->mark[nCount].subject);
cout<<"成绩(0--100):";
do
{
cin>>pStuNode->mark[nCount].score;
}while(pStuNode->mark[nCount].score > 100 || pStuNode->mark[nCount].score < 0);
pStuNode->totalmark=pStuNode->totalmark+pStuNode->mark[nCount].score;
getchar();
}while(SUBJECT != ++nCount);
//头插法
if(m_head->next==NULL)
{
m_head->next=pStuNode;
pStuNode->next=NULL;
}
else
{
pStuNode->next=m_head->next;
m_head->next=pStuNode;
}
cout<<"继续添加?y or n :";
check=getchar();
}while(check!='n' &&check!='N');
return 0;
}
//计算每位学生的总成绩
int CStudent::countmark()
{
studentnode *pStuNode=m_head->next;
if( pStuNode == NULL )
{
cout<<"没有学生,请重新输入"<<endl;
system("pause");
return 0;
}
else
{
cout<<"***************"<<endl;
cout<<"学生成绩汇总:"<<endl;
while(pStuNode)
{
cout<<"姓名:"<<pStuNode->name<<" 总成绩:"<<pStuNode->totalmark<<endl;
pStuNode=pStuNode->next;
}
}
system("pause");
return 0;
}
//按照总成绩大小对成绩进行排序
int CStudent::sortbymark()
{
studentnode *pmove1=m_head->next;
studentnode *pmove2,*pmax,*ppre1,*ppre2,*pmaxpre,*ps=pmove1;
if(m_head->next==NULL)
{
cout<<"没有记录,请添加"<<endl;system("pause");
return 0;
}
ppre1=m_head;
pmax=pmove1;
pmaxpre=ppre1;
for(;NULL != pmove1->next; ppre1=pmove1,pmaxpre=ppre1,pmove1=pmove1->next,pmax=pmove1)
{
ppre2=pmove1;
pmove2=pmove1->next;
//排序 : pmaxpre指向最大值的前一个元素 pmax总是指向总成绩最大的元素 ppre2总是指向比较的第二个元素
//pmove1总是指向插入点的第一个元素 pmove2总是指向即将成为 第二个比较元素 的元素
for( ; NULL != pmove2; )
{
if(pmove2->totalmark > pmax->totalmark)
{
pmaxpre=ppre2;
pmax=pmove2;
}
ppre2=pmove2;
pmove2=pmove2->next;
}
if(pmove1->next == pmax) //交换max和move1。
{
ppre1->next=pmax;
pmove1->next=pmax->next;
pmax->next=pmove1;
pmove1=pmax;
}
else
{
ps=pmove1->next;
pmove1->next = pmax->next;
pmax->next =ps;
pmaxpre->next = pmove1;
ppre1->next = pmax;
pmove1 = pmax;
}
}
cout<<"已经按照从大到小排序"<<endl;
system("pause");
return 0;
}
//保存学生成绩数据至文件
int CStudent::save()
{
char szaddr[35];
int nCount;
studentnode *pNode=m_head->next;
cout<<"请输入保存的地址"<<endl;
cin.ignore();
gets(szaddr);
FILE *fp;
if((fp=fopen(szaddr,"w"))==NULL) /*打开文件*/
{
cout<<"=====>提示:无法打开这个文件!"<<endl;
system("pause");
return 1;
}
int nNum = 0;
while (pNode)
{
nNum++;
pNode = pNode->next;
}
fprintf(fp,"%d\n",nNum);
pNode=m_head->next;
while(pNode)
{
fprintf(fp,"%-8s",pNode->name);
nCount=0;
while(SUBJECT != nCount)
{
fprintf(fp,"%-6s %-7.1d",pNode->mark[nCount].subject,pNode->mark[nCount].score);
nCount++;
}
fprintf(fp,"\n");
pNode=pNode->next;
}
fclose(fp);
cout<<"已经保存,请查阅"<<endl;
system("pause");
return 0;
}
//输出已经输入的信息
int CStudent::show()
{
studentnode *pNode=m_head->next;
int nCount;
if(m_head->next==NULL)
{
cout<<"没有学生记录,请添加"<<endl;
system("pause");
return 0;
}
else
{
while(pNode)
{
cout<<"姓名:"<<pNode->name;
nCount = 1;
while(SUBJECT+1 != nCount)
{
cout<<"科目:"<<pNode->mark[nCount-1].subject;
cout<<" 成绩:"<<pNode->mark[nCount-1].score;
nCount++;
}
cout<<endl;
pNode=pNode->next;
}
}
system("pause");
return 0;
}
//从文件中读取信息,并显示
int CStudent::display()
{
ifstream fin;
char buf[100];
char str[25];
cout<<"请输入路径及文件名:"<<endl;
cin.ignore();
gets(str);
fin.open(str);
if(!fin)
{
cout<<"没有此文件"<<endl;
system("pause");
return 0;
}
while(fin)
{
fin.getline(buf,sizeof(buf));
cout<<buf<<endl;
}
system("pause");
return 0;
}
//从文件中读取数据,并保存在链表中
int CStudent::readfiletolist()
{
char str[25];
cout<<"请输入路径及文件名:"<<endl;
cin.ignore();
gets(str);
FILE *fp;
fp = fopen(str,"rb");
if(!fp)
{
cout<<"没有此文件"<<endl;
system("pause");
return 0;
}
studentnode *pNode;
int nNum = 0;
fscanf(fp,"%d",&nNum);
for(int i = 0; i<nNum; i++)
{
pNode=new studentnode;
pNode->totalmark=0;
fscanf(fp,"%s",pNode->name);
int nCount=0;
while(SUBJECT != nCount)
{
fscanf(fp,"%s%d",pNode->mark[nCount].subject,&pNode->mark[nCount].score);
pNode->totalmark+=pNode->mark[nCount].score;
nCount++;
}
if(NULL == m_head->next)
{
m_head->next=pNode;
pNode->next=NULL;
}
else
{
pNode->next=m_head->next;
m_head->next=pNode;
}
}
cout<<"信息已经保存在链表中"<<endl;
system("pause");
return 0;
}
int CStudent::searchbyname()
{
if(m_head->next==NULL)
{
cout<<"没有学生,请添加或者从文件中读取"<<endl;
system("pause");
return 0;
}
studentnode * p=m_head->next;
char findname[10];
int i;
cout<<"请输入姓名:";
cin.ignore();
gets(findname);
while(p)
{
if(!strcmp(p->name,findname))
{
cout<<"经查找,找到该生信息如下:"<<endl<<endl;
cout<<"姓名:"<<p->name;
i=1;
while(i!=SUBJECT+1)
{
cout<<"科目:"<<p->mark[i-1].subject;
cout<<" 成绩:"<<p->mark[i-1].score;
i++;
}
cout<<endl;
system("pause");
return 1;
}
p=p->next;
}
cout<<"没有此学生,请添加或者从文件中读取"<<endl;
system("pause");
return 0;
}
//删除学生
int CStudent::Delete()
{
if(m_head->next==NULL)
{
cout<<"没有学生,请添加或者从文件中读取"<<endl;
system("pause");
return 0;
}
char szName[24];
cout<<"请输入要删除的学生姓名:";
cin>>szName;
studentnode *pNodepre = m_head;
studentnode *pNodeTal = m_head->next;
while(NULL != pNodeTal)
{
if(!strcmp(pNodeTal->name,szName))
{
if(pNodepre == m_head)
{
m_head->next = pNodeTal->next;
delete pNodeTal;
cout<<"删除成功!"<<endl;
system("pause");
return 0;
}
else if(NULL == pNodeTal->next)
{
pNodepre->next = NULL;
delete pNodeTal;
cout<<"删除成功!"<<endl;
system("pause");
return 0;
}
else
{
pNodepre->next = pNodeTal->next;
delete pNodeTal;
cout<<"删除成功!"<<endl;
system("pause");
return 0;
}
}
pNodepre = pNodeTal;
pNodeTal = pNodeTal->next;
}
cout<<"没有此学生,请添加或者从文件中读取"<<endl;
system("pause");
return 0;
}
int CStudent::Change()
{
if(m_head->next==NULL)
{
cout<<"没有学生,请添加或者从文件中读取"<<endl;
system("pause");
return 0;
}
char szName[24];
cout<<"请输入要修改信息的学生姓名:";
cin>>szName;
studentnode *pStuNode = m_head->next;
int sorce;
while(NULL != pStuNode)
{
if(!strcmp(pStuNode->name,szName))
{
int nCount = 0;
nCount=0;
pStuNode->totalmark=0;
do
{
cout<<"科目:";
char szBuf[20];
cin>>szBuf;
strcpy(pStuNode->mark[nCount].subject,szBuf);
cout<<"成绩(0--100):";
do
{
cin>>sorce;
pStuNode->mark[nCount].score = sorce;
}while(sorce > 100 || sorce < 0);
pStuNode->totalmark=pStuNode->totalmark+pStuNode->mark[nCount].score;
getchar();
}while(SUBJECT != ++nCount);
cout<<"修改成功!"<<endl;
system("pause");
return 0;
}
pStuNode = pStuNode->next;
}
cout<<"没有此学生,请添加或者从文件中读取"<<endl;
system("pause");
return 0;
}
int showmenu();
int main(int argc, char* argv[])
{
int menuitem,flag=1;
CStudent stu;
while(flag)
{
system("cls");
menuitem=showmenu();
switch(menuitem)
{
case 1:{stu.addstudent();break;}
case 2:{stu.countmark();break;}
case 3:{stu.sortbymark();break;}
case 4:{stu.save();break;}
case 5:{stu.show();break;}
case 6:{stu.display();break;}
case 7:{stu.readfiletolist();break;}
case 8:{stu.searchbyname();break;}
case 9:{stu.Delete();break;}
case 10:{stu.Change();break;}
case 11:{flag=0;break;}
}
}
return 0;
}
int showmenu()
{
int choice;
char * menu[11]={
"1:输入学生成绩保存到链表\n",
"2:计算每位学生总成绩\n",
"3:按照总成绩大小对记录进行排序\n",
"4:输出所有学生成绩到一个文件中\n",
"5:显示新输入的学生信息\n",
"6:从文件中读取信息\n",
"7:将文件信息保存在链表中\n",
"8:根据姓名查找学生记录\n",
"9:根据姓名删除学生记录\n",
"10:根据姓名修改学生记录\n",
"11:结束程序\n"
};
cout<<" "<<"*****************************************************"<<endl;
cout<<" *"<<" "<<"学生成绩管理系统"<<" *"<<endl;
cout<<" "<<"*****************************************************"<<endl;
for(choice=0;choice<11;choice++)
cout<<" "<<menu[choice];
cout<<" "<<"*****************************************************"<<endl;
cout<<"please choose to continue"<<endl;
do
{
cin>>choice;
}
while(choice>11||choice<1); //???当输入不在0与10之间
return choice;
}
4.2 调试并运行程序
结果依次如下所示
初始界面:
输入学生信息
显示学生信息
计算学生总成绩
按总成绩排序
读入文件中
从文件显示
将信息保存在链表中
按姓名查找学生成绩
删除学生信息
修改学生信息
删除学生信息
退出程序
五 课程设计总结
在这次的课程设计当中,我觉得我对C++这门课的理论知识有了更进一步的理解,加强了我们动手、思考和解决问题的能力。巩固和加深了对数据结构的理解,提高综合运用本课程所学知识的能力。培养了我选用参考书,查阅手册及文献资料的能力。培养独立思考,深入研究,分析问题、解决问题的能力。通过实际编译系统的分析设计、编程调试,掌握应用软件的分析方法和工程设计方法。通过课程设计,培养了我严肃认真的工作作风,逐步建立正确的生产观念、经济观念和全局观念。而且做课程设计同时也是对课本知识的巩固和加强,平时看课本时,有些问题就不是很能理解,做完课程设计,那些问题就迎刃而解了。而且还可以记住很多东西。认识来源于实践,实践是认识的动力和最终目的,实践是检验真理的唯一标准。所以这个期末测试之后的课程设计对我们的作用是非常大的。
这次的课程设计使我懂得了理论与实际相结合是很非常重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在整个设计过程中,构思是很花费时间的。调试时经常会遇到这样那样的错误,有的是因为粗心造成的语法错误。当然,很多也时用错了方法,总是实现不了。同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。,我们类的分配不够详细,仅仅只自定义了一个学生类,我们本可以设计更完善的类分配与功能分配。其次,我们的接口讨论得也不够详细,我们应该做更详细的设计。最后,对于数据的存储我们只是选用了文件的形式,用文件进行存储更加的耗费事件与资源,我们还可以用数据库来代替。
通过本次课程设计,我学到了很多,明白编写程序是一个很严谨而需要恒心的东西。我们首先用的C++设计编程,遇到了很多困难,初次运行达到了80余个错误,但是我们硬是一个一个改正,最终执行出来,但是由于才疏学浅在C++有一些函数没做出来,比如删除信息,大量移动数组,还有重载,但是我们查资料还是通过一点点的编写改正学到了很多东西,比如指针的运用,还有一些格式上的要求。后来,我们通过查阅很多资料用C语言实现了程序的大部分功能。
总之这次实验获得了很多知识,感觉很充实,也感觉做一个程序员真的很不易。
参考文献
[1] 谭浩强, C程序设计题解与上机指导(第二版),清华大学出版社,2000年9月。
[2] 陈维兴、林小茶,C++面向对象程序设计(第三版),清华大学出版社,2009年6月。
[3] 严蔚敏、吴伟民,数据结构(C语言版),清华大学出版社,2010年7月。
高级语言程序设计Ⅱ课程设计成绩评定表
1、课程设计答辩或质疑记录
1)
2)
3)
2、答辩情况
a)未能完全理解题目,答辩情况较差 □ c)理解题目较清楚,问题回答基本正确 □
b)部分理解题目,答辩情况较差 □ d)理解题目透彻,问题回答流利 □
3、课程设计报告
a)内容: 不完整 □ 完整 □ 详细 □
b)方案设计: 较 差 □ 合理 □ 非常合理 □
c)实现: 未实现 □ 部分实现 □ 全部实现 □
d)文档格式: 不规范 □ 基本规范 □ 规范 □
考勤成绩: ,
占总成绩比例10%
答辩成绩: ,
占总成绩比例30%
课程设计论文成绩: ,
占总成绩比例60%
课程设计总成绩:
4、课程设计评语
指导教师签字:
年 月 日
29
展开阅读全文