《《C程序设计》课程设计指导书.doc》由会员分享,可在线阅读,更多相关《《C程序设计》课程设计指导书.doc(9页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、长春理工大学光电信息学院C程序设计课程设计指导书信息工程分院计算机实验室一、 课程设计的目的采用结构化程序设计方法,综合运用C语言的基本知识,尤其是数组、函数、指针及流程控制等,并补充课程中虽未涉及但实用中必要的其他内容,实现一个功能较为齐全的程序实例。二、 设计题目学生成绩管理系统。程序的主要功能如下:1、按学号记录一个班M名学生N门课程的期末考试成绩;2、逐一显示M个学生的有关数据;3、实现查找、删除;4、能统计出补考学生及其相应科目。三、 设计的方法步骤1、 自愿结合,每23名同学为一组,选组长一名。2、 由组长主持,全组一起消化理解整个程序的基本功能。在此基础上,明确每一名同学所承担的
2、具体模块(函数)。3、 尽可能独立地实现系统的功能(组内同学可一起讨论),确有困难,可参照本指导书中所附的示范案例。4、 应认真研读本指导书中示范案例中的思考题,为答辩做准备。四、 课程设计报告的内容1、 课程设计目的;2、 课程设计题目及主要功能;3、 程序中用到的主要数据结构及程序的总体功能框图;4、 所实现的模块(函数)功能及源程序;5、 所实现的模块(函数)中最能代表你设计水平的算法框图;(可选)6、 程设计的心得体会。(可选)五、答辩要求1、以组为单位答辩,答辩时应提供能运行的完整程序及课程设计报告(每人1份)。2、 组长概述程序的总体功能及总的设计思路后,逐个同学上机演示你本人承担
3、的模块功能并回答老师的提问。3、 提问问题中除指导书上列出的思考题,还包括老师随时针对你的源代码、框图等以及设计中涉及到的基本知识所提出的问题。附1:设计参考案例a) 设计的基本思路依据N.Wirth的著名公式:程序=数据结构+算法其中数据结构要解决两个问题:表示一个学生的属性及M个学生的集合;算法则应实现程序的功能。二、数据结构用一个结构体类型表示一个学生的属性:typedef struct student long num; /*学号*/ char name20; /*姓名*/ int scoteN; /*N门功课考试成绩*/ struct student* next; /*为构成链表而设
4、*/Student;我们采用单链表表示M个学生的集合,这主要是为了熟悉链表的操作。所以在Student类型中事先已设置了next域。我们也可以采用结构体数组表示M个学生的集合(当然应去掉Student中的next域)。三、系统的功能框图主模块统 计单删 除菜 单单显 示单录 入显示单个节点查 找四、系统各功能模块(函数)的实现1、主模块(main()函数)主模块的主要功能是反复显示菜单,根据用户的选项,调用相应的功能模块,直到用户选择退出。参考程序如下:#includemy.hchar courseN20;void main() Student* head;Student* p;char ch
5、;long num;/* number of students */int i;clrscr();printf(nEnter %d course names:n,N);for(i=0;inumber=0;p-next=NULL;strcpy(p-name,head node);for(i=0;iscorei=0;head=p;do ch=menu();switch(ch) case 1:input(head); break;case 2:display(head); printf(nEnter any key to continue,please:); getche(); break;case
6、 3:delete(head); printf(nEnter any key to continue,please:); getche(); break;case 4:printf(nEnter the number of student:); scanf(%ld,&num); p=search(head,num); if(p=NULL) printf(n%ld number student is not found.,num); elsedispnode(p-next); printf(nEnter any key to continue,please:); getche(); break;
7、case 5:reexamine(head); printf(nEnter any key to continue,please:); getche(); break;case 6:printf(nExit the program now,bye_bye!); exit(0); break;default:printf(nYou should press - );if(ch=n | ch=t | ch= )printf(nch is white character.n);elseprintf(nch=%cn,&ch); break; while(1); 思考题:(1)main()函数中的循环怎
8、样才能结束?(2)除了用do-while,还可用什么循环语句?(3)head所指的空节点的num域可用于表示什么信息?2、显示菜单模块显示一个字符界面的菜单,返回代表用户选项的一个数字字符。参考程序如下:#includemy.hchar menu() char ch;int i;clrscr();printf(nnt1 - Inputn);printf(nt2 - Displayn);printf(nt3 - deleten);printf(nt4 - Searchn);printf(nt5 - Reexaminen);printf(nnt6 - Exitn);printf(nntt Ente
9、r your choice:);fflush(stdin);ch=getche();getche();/* wait for */return ch;思考题:(1)你能自己设计一个更美观好用的字符用户界面吗?(2)用单个字符代表用户的选项,如,I代表input,,则菜单程序应如何修改?(3)函数中的 fflush() getche() 起什么作用?3、录入模块录入学生的数据,以学号从小到大的顺序插入到链表中。如果链表中已存在该学生,则给出提示信息,不重复录入。一次可录入0n名学生数据,当输入学号为负时,结束录入。参考程序如下:#includemy.hextern char courseN20;
10、void input(Student* h) long num;Student *p,*q,*r;int i,n=0;/* n is number of inserted in one calling */char ch;clrscr();printf(nEnter data for a student:n);printf(nNumber:);scanf(%ld,&num);while(num0) p=search(h,num);if(p!=NULL) printf(n%ld number student has been existed.,num);printf(nReenter numbe
11、r for a student,please:);fflush(stdin);scanf(%ld,&num);else p=(Student*)malloc(sizeof(Student);if(p=NULL)printf(nMemory allocation error.);exit(1);elsen+;/* increments number of students */p-number=num;printf(nName:);fflush(stdin);gets(p-name);printf(nEnter %d examine scores:,N);for(i=0;iscorei); r=
12、h;q=r-next;while(q!=NULL & numq-number) r=q;q=q-next;r-next=p;p-next=q;clrscr();printf(nEnter data for a student:n);printf(nNumber:);scanf(%ld,&num); h-number +=n; printf(n There are(is) %d student(s) were(was) inserted.,n); printf(n There are(is) total %ld student(s).,h-number);思考题:(1)在录入模块中,为什么要调用
13、查找模块?(2)为什么在接收输入的学号时,另设一个变量num,而不直接使用pnum?(定p指向新近成功申请的节点)(3)插入新节点时,如何在原附加在表头,而与其它情况同样处理可以吗?(4)在此模块内,表头指针所指的空的头节点起到了什么作用?(5)在接收学生姓名时,用了库函数gets(name);比运用scanf(%s”,name)好处在哪儿?(6)不调用search(),代码应如何修改?(7)果用程序保证每门课的成绩在0,100范围内,怎样实现?4、查找模块在给定的链表中查找给定学号的学生。找到则返回给定节点前驱节点的指针,找不到返回null. 这里所以要返回前驱节点的指针,而不是待查节点的指
14、针,原因在于删除模块想调用查找模块,插入节点时要用到待删节点的前驱节点的指针。这是本查找模块与一般查找不同的一个创意。参考程序如下:#includemy.hStudent* search(Student* h,long num)Student *p,*q;q=h;p=h-next;if(p=NULL)return NULL;else while(p!=NULL & p-number!=num) q=p;p=p-next;if(p!=NULL & p-number=num)return q;elsereturn NULL;思考题:(1)此search()模块为何返回所查节点前驱的指针?(2)如果
15、不考虑插入的需要,本模块应如何修改?5输出补考名单遍历整个链表,输出需补考的学生名单及补考课目。这一功能很有实际意义。它是在遍历链表的基础上进行筛选。附带求出全班的不及格率。参考程序如下:#includemy.hvoid reexamine(Student* h) Student *p;int pass;/* logic var. */int i;int nopass=0;/* number of no-pass student */clrscr();if(h-number=0)printf(nThere is no student in the list.);else p=h-next;wh
16、ile(p!=NULL) pass=1;for(i=0;iscoreinext;printf(nnThere %s total %ld student(s),h-number1?are:is,h-number);printf(nincluded %d student%c no-pass.,nopass,nopass1?s: );printf(nNo-pass percentage is %.2f%.n,(float)(nopass)/h-number *100);思考题:(1)能设计一个更好的输出格式;(2)int型变量pass的作用是什么?while循环中为什么有pass=1;这条语句7、显
17、示模块遍历链表,逐个显示学生的数据。此模块功能与输出补考名单类似,只是不必筛选,因此更简单一些。参考程序如下:#includemy.hvoid display(Student* h) Student* p;clrscr();if(h-number=0)printf(nThere is no student in the list.n);elsep=h-next;while(p!=NULL) dispnode(p);printf(nEnter any to continue,please:);getche();p=p-next; int many;/* indicate number of st
18、udent 1 ? */many=h-number1;printf(There %s %ld student(s),many?are:is,h-number);思考题:(1)显示与输出补考名单模块有何相似之处?(2)自己设计一个更好的输出格式。6、删除模块:由用户指定待删除学生的学号,调用search()模块,若找到则删除,否则返回,一次只删除一个学生。参考程序如下:#includemy.hvoid delete(Student *h) Student *p,*q;int num;char answer;clrscr();printf(nEnter number of the student
19、being deleted:);scanf(%ld,&num);q=search(h,num);if(q!=NULL) p=q-next;dispnode(p);printf(nDelete the student,are you sure?(Y/N):);fflush(stdin);answer=getche();answer=tolower(answer);if(answer=y) q-next=p-next;free(p);h-number-;else printf(n You change your idea,bye_bye.);else printf(nThe student to
20、be deleted is not found.); 思考题:(1)如果想一次可删除多个学生,此模块的程序代码应怎样修改?(2)free(p);起什么作用?(3)实际删除节点前,显示一下待删节点包含的信息,然后再次要求用户确认要删除此节点,你认为是否有必要?程序如何实现的? 附2:程序的调试: 一位著名的编程大师曾说过:“程序就是10的灵感和90的调试。所有的编程高手都是调试的能手。 调试可分单模块调试和多模块联调。关于调试的基本原则和方法以后在软件工程等相关课程中会深入探讨,我们在在此仅就以上案例说说具体作法。 为了调试每个模块,首先要对该模块单独编译,以便让编译器为我们尽可能地发现语法方面
21、的错误,然后加以改正,直至编译成功。然后,我们需要编写一个main()函数,调用该模块,以发现逻辑上的错误,并进一步分析对代码进行优化。当可以正常执行后再仔细划分程序所能处理数据的各种情况,特别是边界上的数据,能否被正确处理;异常或错误的数据能否被程序所发现并剔除,例如,对menu()函数,就须反复调用,以验证在多次调用时是否每次都能按预期的方式工作。案例中的fflush()就是在调试中发现问题后,通过查找资料而填加上的。 另外,各模块虽然相互独立,但逻辑上的有一定的先后次序。建议调试次序先调menu(),search(),input(),然后调其它模块。 联调要建立项目文件(或称工程文件)。
22、具体操作方法是:在Turbo C 2.0的集成开发环境下,用编辑器建一个一个项目文件,(.prj是必须的,文件名可选)内容如下:main.cmenu.cinput.cdisplay.cdispnode.csearch.cdelete.creexam.c命名为student.prj然后在project下拉菜单,的Prject Name项下,注册上述项目文件名。再接ctrl-F9菜单就自动对项目文件中所列的C源文件进行编译连接并加以执行了。当然,在各模块正确通过编译后,联调还会产生一些错误,有些错误还比较隐蔽,需要耐心,细致地一一查找改正,这也是锻炼我们实际工作能力的好机会。调试中要充分利用Turbo C 2.0集成开发环境提供的各种调试手段,如单步运行、设置断点、添加观察项等。具体操作请参照教科书上的有关章节。 相信同学们经过艰苦努力,一定会有事前难以预想的收获。