南航C语言课设资料讲解.docx
《南航C语言课设资料讲解.docx》由会员分享,可在线阅读,更多相关《南航C语言课设资料讲解.docx(21页珍藏版)》请在冰豆网上搜索。
南航C语言课设资料讲解
南航C语言-课设
C语言课程设计报告
学生成绩简单管理程序二
一
、程序简介:
程序名称:
学生成绩简单管理程序二(StudentScoreManager)
程序功能:
程序主要功能是用于学生成绩的管理,可以帮助统计人员对学生成绩进行简单的管理,程序包括:
10个菜单项,其中9个管理项、1个为退出程序项。
菜单项包括:
1.CreateList:
按学生姓名汉语拼音顺序建立有序列表。
2.DisplayAllRecord:
在屏幕上显示列表记录。
3.InsertaRecord:
向已建立的有序列表中按序添加记录。
4.DeleteaRecord:
在有序列表中查找并删除记录。
5.Query:
给出学生姓名,在有序列表中查找相关记录并在屏幕上显
示该记录。
6.AddRecordsfromaTextFile:
从文本文档输入学生记录并按序插入已有列表。
7.WritetoaTextFile:
将列表写入指定位置的文档。
8.ReverseList:
将现有列表按逆序存放。
9.DeletetheSameRecord:
删除列表中相同姓名的记录。
0.Quit:
退出程序。
二
、题目分析及心得感想
题目分析:
该程序要求9个子程序项,分别实现9个不同的操作。
分析后知:
需建立14个函数才能实现。
函数的具体解析请参见第三部分的源文件中。
编程中所遇到问题及解决:
(1)在程序刚写完时,找出所有错误后,运行程序,但不能完美执行程序的第一项功能:
即在进入1.CreateList程序项后,一次只能输入一个学生的信息。
一旦输入一次后,自动调回到主选单(如上图所示)分析后发现:
{printf("DoYouWantToContinueToInput?
(Y/N)\n");scanf("%s",a);while(strcmp(a,"Y")!
=0&&strcmp(a,"N")!
=0)}其中的a在函数的开头已被定义,且自己下意识的将其赋值为:
a=‘Y’由于这个错误,使a成为了一个该函数中的一个全局变量,而后的对a的输入赋值对其不起任何作用,于是导致了我设计的程序不能循环输入学生成绩。
发现后,我果断将起赋值处给删去,程序完美运行了。
(2)在写Insert函数时,暴露出我写程序时的思想的不全面性。
如下:
在Insert函数的编写中,对于插入节点的情况分析欠缺。
没有完全考虑到:
链表是空链表时情况,链表插入节点在链表的头、链表插入节点在链表的尾等情况。
而后通过于同学讨论,相互帮助,让我想通了所有可能的情况,最后还是成功编写出了。
编程心得体会:
(1)在编写课程设计之前,可以这样说,对C语言的学习对C语言这门学科的整体把握还是不强!
但在课程设计中,各函数的说明,函数的调用,函数的编写,让我真正明白了C语言这门学科,其实是很强的一门学科,它训练我们的思维缜密,训练我对新事物的领悟能力。
(2)
在课程设计中,让我明白了:
也许书上的一个小小的知识点,在实际的编程中还是非常重要的,比如:
全局变量的定义,各种循环(dowhile,for,while)以及函数的嵌套调用等到等等的实现都非常重要!
(3)课程设计我觉得是对书本上所学知识的一个实际运用,在书本上的知识都是死的,只有活学活用才能成功。
课程设计的过程非常辛苦,但也非常充实,它让我复习了课上所学的知识,锻炼了编程的思维。
也为C语言的最终考试做了准备。
新增功能:
(1)ReverseList:
将现有列表按逆序存放:
首先判断链表是否为空,再判断是否为单节点,或为双节点,若为两个节点以上,则定义三个Student指针来循环逆序存放节点,返回头指针。
(2)DeletetheSameRecord:
删除列表中相同姓名的记录:
首先判断链表是否为空,再判断是否为单节点。
若为两节点以上链表则运用两个Student指针循环比较是否有两个相同的节点,若有则调用Delete函数删除其中一个,若无返回头指针。
三
、源文件及函数说明
#include
#include
#include
#include
#include
structstud/*定义结构体*/
{
charName[20];
intScore;
structstud*next;
};
typedefstructstudStudent;/*定义结构体stud替代为Student*/
intmenu_select();
Student*Create(void);/*从键盘输入若干条记录,调用Insert函数建立以学生姓名为序的单向链表,返回链表头指针*/
voidDisplay(Student*head);/*显示所有学生的姓名和成绩,每10条一页,并暂停一下*/
Student*Insert(Student*head,Student*p0);/*按学生姓名序记录s插入链表head,返回链表头指针*/
Student*Insert_a_Record(Student*head);/*输入待插入的学生姓名、成绩,调用Insert函数按姓名作有序插入,输出插入成功信息,返回链表头指针*/
Student*Delete(Student*head,char*name);/*删除姓名为name的记录,输出成功与否的信息。
返回链表头指针*/
Student*Delete_a_Record(Student*head);/*输入待删除的学生记录的姓名,经确认后调用Delete函数删除该姓名记录,返回链表头指针*/
Student*Query(Student*head,char*name);/*查找学生姓名为name的记录,查找成功返回该节点地址;否则,返回空指针*/
voidQuery_a_Record(Student*head);/*输入待查找的学生记录的姓名,调用Query函数查找该姓名的记录,输出查找成功与否的信息和节点信息*/
Student*AddfromText(Student*head,char*fileame);/*从文件filename添加一批记录到链表中,调用Insert函数作有序插入,并显示成功输入的记录,并返回头指针*/
voidWritetoText(Student*head,char*fileame);/*将链表中的节点记录全部写入使用者想输入的文件中*/
Student*Reverse(Student*);/*将现有的链表记录逆序存放,返回逆序后的链表头指针*/
Student*Delete_Same(Student*);/*删除链表中姓名形同的记录,返回链表头指针*/
voidQuit(Student*head);/*释放链表的动态空间,退出程序*/
intn=0;
main()
{Student*head=NULL;
while
(1)/*菜单选择*/
{charfilename[20];
switch(menu_select())
{
case1:
printf("ExecutionofCreateList\n");/*菜单项1.CreateList*/
head=Create();
system("pause");
break;
case2:
printf("ExecutionofDisplayAllRecord\n");/*菜单项2.DisplayAllRecord*/
Display(head);
system("pause");
break;
case3:
printf("ExecutionofInsertaRecord\n");/*菜单项3.InsertaRecord*/
head=Insert_a_Record(head);
system("pause");
break;
case4:
printf("ExecutionofDeleteaRecord\n");/*菜单项4.DeleteaRecord*/
head=Delete_a_Record(head);
system("pause");
break;
case5:
printf("ExecutionofQuery\n");/*菜单项5.Query*/
Query_a_Record(head);
system("pause");
break;
case6:
printf("ExecutionofAddRecordsfromaTextFile\n");/*菜单项6.AddRecordsfromaTextFile*/
printf("PleaseInputTheNameOfTheTextFile!
\n");
gets(filename);
AddfromText(head,filename);
system("pause");
break;
case7:
printf("ExecutionofWritetoaTextFile\n");/*菜单项7.WritetoaTextFile*/
printf("PleaseInputTheNameOfTheTextThatYouWantToOutput\n");
gets(filename);
WritetoText(head,filename);
system("pause");
break;
case8:
printf("ReverseList:
\n");/*菜单项8.ReverseList*/
head=Reverse(head);
system("pause");
break;
case9:
printf("DeletetheSameRecord\n");/*菜单项9.DeletetheSameRecord*/
head=Delete_Same(head);
system("pause");
break;
case0:
printf("ExecutionofQuit\n");/*菜单项0.Quit*/
Quit(head);
system("pause");
exit(0);
}
}
}
intmenu_select()/*菜单选择函数*/
{intc;
do{system("cls");
printf("++++++++++++++++++++++++++++++WELCOMETOTCPROGRAME++++++++++++++++++++++++\n");
printf("ProgrameMaker:
ZHJ060930118\n");
printf("1.CreateList\n");
printf("2.DisplayAllRecord\n");
printf("3.InsertARecord\n");
printf("4.DeleteARecord\n");
printf("5.Query\n");
printf("6.AddRecordsFromATexlFile\n");
printf("7.WriteToATexlFile\n");
printf("8.ReverseList\n");
printf("9.DeleteTheSameRecord\n");
printf("0.Quit\n:
");
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("PleaseChoiceAndInput0~7:
\n");
scanf("%d",&c);
}while(c<0||c>9);
return(c);/*返回菜单选择的输入序号*/
}
Student*Create()/*创建链表函数,函数返回链表头指针*/
{Student*head,*s;
chara[20];
head=NULL;
printf("NowCreateAnIncreasingList:
\n\n");
do/*询问用户循环输入学生成绩*/
{printf("InputAnStudent'sName:
\n");
s=(Student*)malloc(sizeof(Student));
scanf("%s",s->Name);
printf("AndThenInputTheStudent'sScore\n");
scanf("%d",&s->Score);
head=Insert(head,s);
printf("DoYouWantToContinueToInput?
(Y/N)\n");
scanf("%s",a);
while(strcmp(a,"Y")!
=0&&strcmp(a,"N")!
=0)
{printf("(Y/N)");
scanf("%s",a);
}
}while(strcmp(a,"Y")==0);
return(head);/*返回头指针*/
}
voidDisplay(Student*head)/*屏幕输出所有节点函数*/
{
Student*p;
inti=0;
p=head;
if(head==NULL)printf("ThisListisNULL!
\n");/*链表为空链表时情况*/
while(p!
=NULL)
{printf("\n\t\t\tDisplayAllRecords:
\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
Do/*链表不为空时,循环输出所有节点内容*/
{printf("%s\t%d\n",p->Name,p->Score);
p=p->next;
i++;
if(i%10==0&&p!
=NULL)/*控制10行每页,每输出10行暂停*/
{system("pause");system("cls");}
}while(p!
=NULL);
}printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
}
Student*Insert(Student*head,Student*p0)/*有序插入函数,函数返回链表头指针*/
{
Student*p1,*p2;
if(head==NULL)/*链表为空链表时情况*/
{head=p0;p0->next=NULL;return(head);}
p1=head;
while(strcmp(p0->Name,p1->Name)>0&&(p1->next!
=NULL))/*寻找插入点*/
{p2=p1;p1=p1->next;}
if(strcmp(p0->Name,p1->Name)<=0)
{if(head==p1)head=p0;/*插入位置为首节点*/
elsep2->next=p0;
p0->next=p1;
}
else{p1->next=p0;p0->next=NULL;}/*插入位置为末节点*/
return(head);
}
Student*Insert_a_Record(Student*head)/*插入一项新输入学生数据*/
{Student*q;
printf("PleaseInputTheNameOfTheStudent!
\n");
q=(Student*)malloc(sizeof(Student));
scanf("%s",q->Name);
printf("AndThenPleaseInputTheScoreOfTheStudent!
\n");
scanf("%d",&q->Score);
head=Insert(head,q);/*调用Insert函数*/
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("\t\tTheRecordInsertsuccessfully!
\n");
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
return(head);
}
Student*Delete(Student*head,char*name)/*条件删除节点函数,函数返回链表头指针*/
{Student*p3,*p4;
if(head==NULL)
{printf("ThisListisNull!
(Fail..)\n");
return(head);
}
p3=head;
while(p3->next!
=NULL&&strcmp(p3->Name,name)!
=0)/*寻找要删除节点*/
{p4=p3;
p3=p3->next;
}
if(strcmp(p3->Name,name)==0)/*判断要删除节点*/
{if(p3==head)
head=p3->next;
else
p4->next=p3->next;printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("TheRecordWhichYouHaveInput:
NAME:
%s\t\tSCORE:
%d\tIsDeleted!
\n",p3->Name,p3->Score);printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
free(p3);
}
else
{printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("TheRecordWhichYouHaveInput:
NAME:
%s\t\tSCORE:
%d\tIsNotFoundAndDelete!
\n",name);
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");}
return(head);
}
Student*Delete_a_Record(Student*head)/*删除一项纪录函数,函数返回链表头指针*/
{
chart,name[20];
printf("PleaseInputARecord'sNameThatYouWantToDelete:
\n");
scanf("%s",name);
printf("DoYouReallyWantToDeleteThisRecord(Y/N):
");
do
{
t=getchar();
}while(t!
='Y'&&t!
='N'&&t!
='y'&&t!
='n');
if(t=='N'||t=='n')
{
printf("Recordisnotdelete!
");
system("pause");return(head);
}
head=Delete(head,name);/*调用条件删除节点函数Delete删除记录*/
return(head);
}
Student*Query(Student*head,char*name)/*条件查找函数,函数返回查找到节点指针,否则返回空指针*/
{
if(head==NULL)
{printf("ThisListisNull!
\n");
return(NULL);
}
while(head->next!
=NULL&&strcmp(head->Name,name)!
=0)
{
head=head->next;
}
if(strcmp(head->Name,name)==0)
{
return(head);
}
else
return(NULL);
}
voidQuery_a_Record(Student*head)/*查找一项纪录函数并显示*/
{
charname[20];
Student*s;
printf("InputANameOfTheStudentThatYouWantToFind:
\n");
scanf("%s",name);
s=Query(head,name);/*调用Query函数来实现*/
if(s==NULL)
printf("TheRecordof%sisnotfound.\n",name);
else
{
printf("TheRecordof%sisfound:
\n",name);
printf("\TName:
%s\t\tScore:
%d\n",s->Name,s->Score);
}
}
Student*AddfromText(Student*head,char*filename)/*从文件输入记录函数,函数返回链表头指针*/
{FILE*fp;inti,n;Student*p;
printf("Pleaseinputthefilename:
\n");
scanf("%s",filename);/*让用户自主输入想读入文件的文件名*/
fp=fopen(filename,"r");/*打开文件*/
if(fp==NULL)
{printf("Thefilecannotbefound.\n");
return(head);
}
fscanf(f