C语言课程设计报告书罗靖.docx
- 文档编号:25956516
- 上传时间:2023-06-16
- 格式:DOCX
- 页数:42
- 大小:90.13KB
C语言课程设计报告书罗靖.docx
《C语言课程设计报告书罗靖.docx》由会员分享,可在线阅读,更多相关《C语言课程设计报告书罗靖.docx(42页珍藏版)》请在冰豆网上搜索。
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*h,*p,*q;
charname[11];
intk;
LINE;
printf("当前输入的人数序号(输入0结束输入):
\n\n");
scanf("%d",&k);
LINE;
h=NULL;
while(k>0)
{
p=NEW;/*用动态存储分配来实现创建一个新的结点*/
…………………/*这部分,是给创建结点中的值域赋值*/
p->next=NULL;/*给P的下一个结点赋值为0*/
if(h==NULL)/*这个部分的执行顺序是①③②③②③…,所以给h一开始赋值为
①h=p;NULL为这个用意,这样h空间就存有创建的链表的首地址*/
else
②q->next=p;/*一开始先执行①③,所以q一开始指向链表的头结点,之后执
③q=p;②③②③这样,就让头结点与第二个结点之间的链域连接,再后让q指
LINE;向改变,直到第二个结点,依次连接新的结点,直至循环条件结束。
*/
printf("当前输入的人数序号(输入0结束输入):
\n\n");
scanf("%d",&k);
LINE;
}
returnh;
}
⑶输出函数
设计过程
输出函数和输入函数大致设计过程有相似之处,输出函数也比较简单,就是给输出函数中的形参传递链表的首地址,将h指向头结点,当h不为0时,即还没有到最后一个结点,每次输出对应结点内值域的内容后,再将h指向移到下一个结点,又因为形参在h在输出函数调用后就会被释放,所以并没有改变链表的头结点的地址。
for(;h;h=h->next,i++)/*h=h->next是当前结点的值域的内容输出完毕后用来使h的指向指向下一
{个结点,再输出这个结点值域的内容,循环直至尾结点输出完毕*/
………/*输出值域的内容*/
}
⑷更新函数
这个函数包含了三个模块,插入,删除,修改,因为更新函数与主函数的程序设计一样都是利用switch语句,所以这里只看这三个模块的程序设计。
一、插入
红色线修改后的链表情况,这使用了Find这个函数,所以根据Find函数有三种情况:
①成功找到相关结点的前驱结点,则返回值p不为NULL且p->next也不为NULL;
1p不为NULL但p->next=NULL表明所查找得点不存在,则插在最后一个结点处;
2若返回值p为NULL,所查找的结点就是头结点。
因为第二种情况不影响,所以可以将函数设计为
if(q)
{
p->next=q->next;
q->next=p;
}
else
{
p->next=*h;
*h=p;
}
其中p指向创建的新结点,q指向相关结点的前驱结点。
二、删除
红色线修改后的链表情况,同样的这也因为Find函数分为了三种情况,为找到相关结点的情况就不予考虑了,这两种情况的方法都是一样的:
找到了相关结点,想用temp指向要释放的结点,再越过其指向下一个结点,再释放temp指向的空间。
只是第二种还要修改链表的首地址,要不则删除不成功。
三、修改
修改函数中比较简单,没有像前二个函数那样还有可能修改头地址。
修改函数只要利用Find函数来查找到相关的结点,来对应的修改其值域即可。
⑸查询函数
查询函数分为了两个模块,按姓名查询和按学号查询。
同样的也是利用Find函数来查找相关结点,输出此结点值域的内容。
程序设计
部分相关程序:
printf("请输入要查询的学号:
");
LINE;
scanf("%ld",&num);
p=Find(h,num);
if(p&&(p->next))
{
p=p->next;
Output_student(p);
}
elseif(p==NULL)
Output_student(h);
else
printf("不存在该学生!
");
同样的根据Find函数分为了两种情况:
一是未找到相关结点,则不输出,二、找到了相关结点,输出相关结点的值域内容。
⑹排序函数
此部分也分为了两个模块,但是程序设计思想基本一致,故只说明其中的一个模块。
分为了两种情况:
第一是头结点与第二个结点作比较,若头结点内值域中指定的成员值大于第二个结点,则需交换。
因为涉及到头结点地址的改变,所以将其单独作为一种情况来讨论。
p=(*h)->next;
if((p->score)>((*h)->score))
{
(*h)->next=p->next;
p->next=(*h);
(*h)=p;
根据这个过程可以将其交换。
第二种情况:
无需改变到头结点的地址,所以这个情况和上述情况的只有稍微差别。
for(t=(*h),p=(*h)->next,q=p->next;q&&p;t=t->next)
{
if((q->num)<(p->num))
{
p->next=q->next;/*这部分若条件为真,则进行交换。
*/
q->next=p;
t->next=q;
q=p->next;
}
else
{
p=p->next;/*条件为假,无需交换,继续下个结点与其后驱结点的比较*/
q=q->next;
}
这部分的程序设计时,有点类似与冒泡的方法。
因为这两种情况执行后相当于用一个结点依次与其后驱结点比较,故再用一个循环,循环次数为最大结点数,这样就可以完成了排序这部分功能的实现。
⑺统计函数
这个部分分为了四个部分,但是程序设计思想基本一致,故只说明其中的一个模块。
统计学生人数模块中,考虑调用Output函数输出,输出一个学生的信息,总和数加一。
程序设计
voidSum_people(structStudent*h)
{
inti;
printf("学生信息:
\n");
LINE;
i=Output(h);
LINE;
printf("有%d个学生\n",i);
printf("按任意键继续!
\n");
bioskey(0);
}
调用Output函数,以完成统计的功能。
⒉运行结果
输入的数据:
插入函数的运行:
输入个新的学生信息:
name:
ljnnum:
7sex:
myear:
1988maonth:
3day:
13age:
19score:
70tel:
335
统计函数:
统计人数函数的运行(注此时数据有些不同,因为有过修改、删除等操作)
查询函数的运行:
排序函数的运行:
六、调试情况,设计技巧及体会
1调试中的主要问题
调试中主要出现的问题:
⑴经常遇到程序执行到某部分就不运行,而编译和链接都成功,说明程序设计上有些问题,语法等并未出错,这时就要去再行考虑设计的程序哪部分考虑不周全。
⑵因为这次使用链表来设计程序,就牵扯到形参和实参的问题。
曾经因为考虑不周全,在自定义函数前的基类出错,导致相关的值未改变,这里就要考虑好形参和实参的问题。
2程序的不足和改进之处
因为用链表来设计一个程序,较复杂,最后没来得及,设计相关的文件存储来实现将数据保存,以致每次运行程序都要重新输入新的数据
改进之处:
可以再考虑编写一个函数,这个函数的功能是将数据写入文件中并保存。
3在设计过程中的感受
万事开头难,编写一个自定义函数时,要先界定好函数的功能,要有几个形参,返回值是什么类型等问题,还是形参和实参的问题,如果不考虑清楚则自定义函数就很难编写出来。
在设计过程中可以帮助自己的编程能力,也可以在一些平时没有考虑甚至考虑不周全的问题上认真的考虑,总的来说,两周的实习是有很大收获的。
七、源程序清单
#include
#include
#include
#defineLINEprintf("--\n");
#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**h)
{
structStudent*p;
while(*h)
{
p=*h;
*h=p->next;
free(p);
}
LINE;
printf("删除成功!
");
LINE;
bioskey(0);
}
voidSum(structStudent*h)
{
intchoice;
do
{
system("cls");
LINE;
printf("\n\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(h);break;
case2:
Sum_sex(h);break;
case3:
Sum_pass(h);break;
case4:
Sum_no(h);break;
case0:
break;
}
}
while(choice!
=0);
}
voidSum_no(structStud
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 课程设计 报告书
