C语言课程设计报告书罗靖.docx
《C语言课程设计报告书罗靖.docx》由会员分享,可在线阅读,更多相关《C语言课程设计报告书罗靖.docx(21页珍藏版)》请在冰豆网上搜索。
![C语言课程设计报告书罗靖.docx](https://file1.bdocx.com/fileroot1/2022-12/15/ad444639-0207-458a-955d-22c0684e7193/ad444639-0207-458a-955d-22c0684e71931.gif)
C语言课程设计报告书罗靖
(此文档为word格式,下载后您可任意编辑修改!
)
西安郵電學院
高级语言程序设计课程设计报告
系部名称
电子与信息工程系
学生姓名
罗靖
专业名称
电子信息工程
班级
电子0701
学号
指导教师
衡霞
时间
2008年06月09日至
2008年06月20日
实验题目学生信息管理系统
一、实验目的
1.熟悉C语言程序的编辑、编译链接和运行的过程,至少能够用一种编译器较熟练地编辑、编译及调试程序。
2.掌握C语言数据类型,如何定义一个整型、字符型和实型的变量,以及对它们赋值的方法。
3.熟练运用if语句和switch语句以及嵌套应用。
涉及循环调用的,了解并掌握三种控制语句while、do-while和for语句。
4.学习并掌握C语言定义函数的基本方法、声明函数及调用函数的方法和过程。
5.掌握文件和文件指针的概念以及文件的定义方法,认识文件打开、关闭、读、写等文件基本操作函数。
6.掌握结构体类型变量、数组的定义和使用。
7.了解指针和链表的概念,掌握指针的定义和使用指针变量的方法以及链表的正确用法。
灵活使用链表来储存学生信息。
8.掌握数组的定义、引用以及输入输出的方法、通过字符数组存储字符串,进一步使用字符串
二、实验内容
学生管理程序具有下列功能:
一、输入部分
通过键盘输入多位学生的学生信息。
学生的信息包含有:
学生姓名、性别、学号、出生年月日、年龄、成绩。
二、输出部分
输出当前已存储的学生信息
三、更新部分
此部分分为了三个目录:
①插入让用户自定义在哪个学生的左侧插入一个新的学生的信息
②删除删除用户指定的学生信息
③修改修改用户指定的学生信息
四、查询部分
分为两个目录
①按名字查询输出用户查询的学生信息
②按学号查询输出用户查询的学生信息
查询用户指定的学生信息
五、排序
此部分分为了两个目录:
①按学号排序
②按成绩排序
六、统计
此部分也分为了两个目录:
①统计当前一共存储了多少个学生的信息
②统计当前存储的学生信息中的男生或女生的人数
③统计及格人数
④统计不及格人数
七、释放
开发工具—-Win-TC
运行平台——中文DOS运行环境
三、需求分析
一、函数功能描述
⑴输入部分
通过键盘输入多位学生的学生信息。
学生的信息包含有:
学生姓名、性别、学号、出生年月日、年龄、成绩。
*此次做的学生管理系统是利用链表而完成的程序,故第一部分想要实现建立链表*
⑵、输出部分
输出当前已存储的学生信息*通过链表的头结点的地址来依次输出每个结点中的值域中的内容,直至尾结点来实现输出学生信息*
⑶、更新部分
此部分分为了三个目录:
①插入让用户自定义在哪个学生的左侧插入一个新的学生的信息*这部分的功能是让用户自定义插在哪个个学生左边,并输入该学生的学号,找到其在链表中存储的结点处插入一个新的结点,而这个新的结点的中的值域存储的是一个新的学生信息,从而实现插入一个新的学生信息*
②删除删除用户指定的学生信息*这部分的功能是输入学生的学号,找到其在链表中存储的结点处,并将这整个结点删除,再把该结点的前驱结点和后驱节点连接,来实现这个学生信息的删除*
③修改修改用户指定的学生信息*这部分是利用输入学生的学号,来找到存储该学生信息的结点,通过该结点的链域来修改其中的值域,来实现对学生信息的修改*
⑷、查询部分
查询用户指定的学生信息
①按名字查询输出用户查询的学生信息*这部分是利用输入学生的姓名,来找到存储该学生信息的结点,输出该结点的值域中的内容,来实现对学生信息的查询功能*
②按学号查询输出用户查询的学生信息*同上,只是查询条件为学号*
⑸、排序
此部分分为了两个目录:
①按学号排序*此部分程序设计较为复杂,但大致是通过对链表中个结点的值域比较,按小到大的顺序排序,但必须要修改相应的链域,才能实现排序的功能*
②按成绩排序*此部分和大致内容和按学号排序一样,但不同的是,此处是按大到小的顺序排序*
⑹、统计
此部分也分为了两个目录:
①统计当前一共存储了多少个学生的信息*通过输出学生的信息,每输入一个总和数加一,最后输出总和数来实现统计人数*
②统计当前存储的学生信息中的男生或女生的人数*从头结点开始,一个一个结点的去查看其值域,若性别为男生或女生,总和数加一,最后输出总和数来实现统计男生或女生的人数*
③统计及格人数*从头结点开始,一个一个结点的去查看其值域,若成绩大于60,总和数加一,最后输出总和数来实现统计及格的人数*
④统计不及格人数*从头结点开始,一个一个结点的去查看其值域,若成绩小于60,总和数加一,最后输出总和数来实现统计不及格的人数*
⑺、释放
这个部分和动态存储分配中的释放空间有着类似的概念,即所建立的链表所申请的存储空间全部释放,也就是说把当前录入的所有学生信息全部删除,本着申请动态存储空间最后要释放的原则,设计了这个部分
二、问题的提出
如何完成排序部分这个功能的呢?
因为使用链表,感觉上排序似乎是整个程序设计中最难的部分,因为要根据结点中值域的内容来对应的修改链域,而链域中的指针问题若不考虑清楚,则很有可能造成链表的混乱,造成某些结点没有连接上或等其他情况,因此本人将排序这部分作为整个程序设计的重点。
三.程序可以满足以下功能:
1.各模块间通过菜单切换和调用
2.主函数通过调用菜单函数实现对各功能模块的调用,各功能模块间根据需要可相互调用。
3.程序能够保证各模块功能的独立和数据共享。
*不使用全局变量则能保证函数之间的独立性,利用形参与实参之间的数值传递来实现数据共享*
4.相近功能以级联菜单的形式集成。
四、概要设计
1.方案设计
2.数据结构说明
structdate
{
intyear,month,day;*这个结构体的成员代表的是学生的出生年月日*
};
structStudent*这个结构体的成员分别代表了学生的学号、电话、名字、性别、年龄、
{成绩、出生年月日*
longnum,tel;
charname[11],sex[2];
intage,score;
structdateBirth;
structStudent*next;*这个是在链表中建立起连接各个结点的链域的一个指向这个
};structStudent结构体的指针*
3.模块功能说明
在设计的程序中,共设计了
intOutput(structStudent*);*输出当前存储的所有学生信息*
voidOutput_student(structStudent*);*在查询中显示所查询的学生信息*
structStudent*Find(structStudent*,long);*在查询、插入、修改函数中使用来寻找到相关的存储了相关的学生信息的结点的前驱结点地址*
structStudent*Creat(long);*在插入函数中调用,创建一个新的结点,其值域存储一个新的学生信息,并返回指向这个结点的指针,用于插入时与其前驱和后驱结点的链域连接*
voidInsert(structStudent**,long,long);*在用户指定的结点左边插入一个新的结点,既是把Creat这个函数传递过来的的新结点的指针与其前驱和后驱结点的链域连接*
intInsertNode(structStudent**);*输出些提示用户操作的语句,只要想要插入的那个学生的学号不为0,则提示插入成功,否则插入失败*
intDelete(structStudent**);*找到存储了用户指定的学生信息的结点,将其删除*
intRevise(structStudent*);*找到存储了用户指定的学生信息的结点,修改其值域的内容*
voidRenew(structStudent**);*建立个子菜单,菜单内有三个目录:
一、插入二、删除三、修改四、退出让用户选择*
voidInquire_name(structStudent*);*输入想查询的学生姓名,从头结点开始,一个一个结点的去查看其值域,若相同,则输出这个结点的值域内的内容*
voidInquire_num(structStudent*);*输入想查询的学生学号,从头结点开始,一个一个结点的去查看其值域,若相同,则输出这个结点的值域内的内容*
voidInquire(structStudent*);*建立个子菜单,菜单内有三个目录:
一、按姓名查询二、按学号查询三、退出让用户选择*
voidPaixu_num(structStudent**);*按照学生的学号排序*
voidPaixu_score(structStudent**);*按照学生的成绩排序*
voidPaixu(structStudent**);*建立个子菜单,菜单内有三个目录:
一、按学号排序二、按成绩排序三、退出让用户选择*
voidSum_people(structStudent*);*统计学生的个数*
voidSum_sex(structStudent*);*统计学生中男女生的个数*
voidSum_pass(structStudent*);*统计及格人数*
voidSum_no(structStudent*);*统计不及格人数*
voidSum(structStudent*);*建立个子菜单,菜单内有三个目录:
一、统计学生个数二、统计学生中男女生的个数三、*统计及格人数四、统计不及格人数五、退出让用户选择*
voidFree(structStudent**);*删除所有学生的信息,采用不断删除头结点的方式来依次删除所有的结点*
五、详细设计
1.主要功能模块的流程图如下:
⑴主函数
设计过程
主函数中因为要建立主菜单
所有主函数中并没有什么复杂的的设计过程,较简单。
密码部分稍微复杂。
而菜单部分只需用switch语句来建立主菜单,以供用户选择。
密码部分:
使用了一个while循环来判断用户输入的密码是否正确,若正确,则继续执行下面的语句,否则就要不断的输入密码,直至正确,确保了用户资料的保密性。
部分源程序如下:
voidmain(void)
{
intchoice,code;
system("cls");
printf("请输入密码:
");
scanf("%d",&choice);
while(choice!
=123)*利用while循环的来实现密码功能*
{
printf("\n密码错误!
\n");
printf("请再输入密码!
");
scanf("%d",&choice);
}
printf("\n密码正确!
\n");
printf("按任意键继续!
");
bioskey(0);
}
⑵输入函数
设计过程
输入部分因为牵扯到链表的建立,所以输入函数比主函数复杂。
下面是建立链表的详细过程设计。
structStudent*Input1(void)
{
structStudent*\n");
scanf("%d",&k);
LINE;
\n");
scanf("%d",&k);
LINE;
}
return");
LINE;
i=Output(",i);
printf("按任意键继续!
\n");
bioskey(0);
}
调用Output函数,以完成统计的功能。
⒉运行结果
输入的数据:
插入函数的运行:
输入个新的学生信息:
name:
ljnnum:
7sex:
myear:
1988maonth:
3day:
13age:
19score:
70tel:
335
统计函数:
统计人数函数的运行(注此时数据有些不同,因为有过修改、删除等操作)
查询函数的运行:
排序函数的运行:
六、调试情况,设计技巧及体会
1调试中的主要问题
调试中主要出现的问题:
⑴经常遇到程序执行到某部分就不运行,而编译和链接都成功,说明程序设计上有些问题,语法等并未出错,这时就要去再行考虑设计的程序哪部分考虑不周全。
⑵因为这次使用链表来设计程序,就牵扯到形参和实参的问题。
曾经因为考虑不周全,在自定义函数前的基类出错,导致相关的值未改变,这里就要考虑好形参和实参的问题。
2程序的不足和改进之处
因为用链表来设计一个程序,较复杂,最后没来得及,设计相关的文件存储来实现将数据保存,以致每次运行程序都要重新输入新的数据
改进之处:
可以再考虑编写一个函数,这个函数的功能是将数据写入文件中并保存。
3在设计过程中的感受
万事开头难,编写一个自定义函数时,要先界定好函数的功能,要有几个形参,返回值是什么类型等问题,还是形参和实参的问题,如果不考虑清楚则自定义函数就很难编写出来。
在设计过程中可以帮助自己的编程能力,也可以在一些平时没有考虑甚至考虑不周全的问题上认真的考虑,总的来说,两周的实习是有很大收获的。
七、源程序清单
#include#defineNEW(structStudent*)malloc(sizeof(structStudent))
#defineOK1
#defineFALSE0
structdate
{
intyear,month,day;
};
structStudent
{
longnum,tel;
charname[11],sex[2];
intage,score;
structdateBirth;
structStudent*next;
};
structStudent*Input();
intOutput(structStudent*);*这部分是所有函数的声明*
voidOutput_student(structStudent*);
structStudent*Find(structStudent*,long);
structStudent*Creat(long);
voidInsert(structStudent**,long,long);
intInsertNode(structStudent**);
intDelete(structStudent**);
intRevise(structStudent*);
voidRenew(structStudent**);
voidInquire_name(structStudent*);
voidInquire_num(structStudent*);
voidInquire(structStudent*);
voidPaixu_num(structStudent**);
voidPaixu_score(structStudent**);
voidPaixu(structStudent**);
voidSum_people(structStudent*);
voidSum_sex(structStudent*);
voidSum_pass(structStudent*);
voidSum_no(structStudent*);
voidSum(structStudent*);
voidFree(structStudent**);
voidFree(structStudent**\n****统计******\n\n");
LINE;
printf("1.人数\n\n");
printf("2.男女生人数\n\n");
printf("3.及格人数\n\n");
printf("4.不及格人数\n\n");
printf("0.、退出\n\n");
printf("请输入(0_4):
\n\n");
scanf("%d",&choice);
switch(choice)
{
case1:
Sum_people(");
LINE;
Output(",i);
printf("按任意键继续!
\n");
bioskey(0);
}
voidSum_pass(structStudent*");
LINE;
Output(",i);
printf("按任意键继续!
\n");
bioskey(0);
}
voidSum_people(structStudent*");
LINE;
i=Output(",i);
printf("按任意键继续!
\n");
bioskey(0);
}
voidSum_sex(structStudent*");
LINE;
Output(");
scanf("%s",sex);
for(i=0;",sex,i);
printf("按任意键继续!
\n");
bioskey(0);
}
voidPaixu(structStudent**\n****排序******\n\n");
LINE;
printf("1.按学号排序\n\n");
printf("2.按成绩排序n\n");
printf("0.退出\n\n");
printf("请输入(0_2):
\n\n");
scanf("%d",&choice);
switch(choice)
{
case1:
Paixu_num(\n****查询******\n\n");
LINE;
printf("1.按名字查询\n\n");
printf("2.按学号查询\n\n");
printf("0.退出\n\n");
printf("请输入(0_2):
\n\n");
scanf("%d",&choice);
switch(choice)
{
case1:
Inquire_name(\n******更新学生信息******\n\n");
LINE;
printf("1.插入\n\n");
printf("2.删除\n\n");
printf("3.修改\n\n");
printf("0.Exit\n\n");
printf("请输入(0_2):
\n");
scanf("%d",&choice);
switch(choice)
{
case1:
if(InsertNode(=OK;
system("cls");
LINE;
printf("请输入要修改的学生学号:
");
LINE;
scanf("%ld",&num);
p=Find(");
scanf("%s",p->name);
printf("newnum:
\n");
scanf("%ld",&p->num);
printf("newsex(morf)");
scanf("%s",p->sex);
printf("newyear:
\n");
scanf("%d",&(p->Birth.year));
printf("newmonth:
\n");
scanf("%d",&(p->Birth.month));
printf("newday:
\n");
scanf("%d",&(p->Birth.day));
printf("newage:
\n");
scanf("%d",&p->age);
printf("newscore:
\n");
scanf("%d",&p->score);
printf("newtel:
\n");
scanf("%ld",&p->tel);
}
elseif(p==NULL)
{
printf("newname:
\n");
scanf("%s",");
scanf("%ld",&");
scanf("%d",&(");
scanf("%d",&(");
scanf("%d",&(");
scanf("%d",&");
scanf("%d",&");
scanf("%ld",&=FALSE;
Output(Action;
bioskey(0);
}
intDelete(structStudent**p)
{
longnum;
structStudent*q,*temp;
intAction=OK;
system("cls");
LINE;
printf("请输入要删除的学生的学号:
");
LINE;
scanf("%ld",&num);
q=Find(*p,num);
if(q&&q->next)
{
temp=q->next;
q->next=temp->next;
free(temp);
}
elseif(q==NULL)
{
temp=*p;
*p=temp->next;
free(temp);
}
elseif(q!
=NULL&&q->next==NULL)
Action=FALSE;
Output(*p);
returnAction;
bioskey(0);
}
intInsertNode(structStudent**=OK;
system("cls");
LINE;
printf("插入的功能是:
");
LINE;
Output(*");
printf("若找不到该学生,则自动插入到最后一个学生处!
\n");
scanf("%ld",&Oldnum);
LINE;
printf("请输入要新的学生的学号");
scanf("%ld",&Newnum);
if(Newnum>0)
Insert(=FALSE;
Output(*Action;
bioskey(0);
}
voidInsert(structStudent**");
scanf("%s",p->name);
printf("性别(morf):
");
scanf("%s",p->sex);
printf("出生的年份:
\n");
scanf("%d",&(p->Birth.year));
printf("出生的月份:
\n");
scanf("%d",&(p->Birth.month));
printf("出生的天数:
\n");
scanf("%d",&(p->Birth.day));
printf("年龄:
\n");
scanf("%d",&p->age);
printf("成绩:
\n");
scanf("%d",&p->score);
printf("电话l:
\n");
scanf("%ld",&p->tel);
p->next=NULL;
returnp;
}
structStudent*Find(structS