《C程序设计》课程设计指导书0104.docx

上传人:b****2 文档编号:505104 上传时间:2023-04-29 格式:DOCX 页数:18 大小:45.34KB
下载 相关 举报
《C程序设计》课程设计指导书0104.docx_第1页
第1页 / 共18页
《C程序设计》课程设计指导书0104.docx_第2页
第2页 / 共18页
《C程序设计》课程设计指导书0104.docx_第3页
第3页 / 共18页
《C程序设计》课程设计指导书0104.docx_第4页
第4页 / 共18页
《C程序设计》课程设计指导书0104.docx_第5页
第5页 / 共18页
《C程序设计》课程设计指导书0104.docx_第6页
第6页 / 共18页
《C程序设计》课程设计指导书0104.docx_第7页
第7页 / 共18页
《C程序设计》课程设计指导书0104.docx_第8页
第8页 / 共18页
《C程序设计》课程设计指导书0104.docx_第9页
第9页 / 共18页
《C程序设计》课程设计指导书0104.docx_第10页
第10页 / 共18页
《C程序设计》课程设计指导书0104.docx_第11页
第11页 / 共18页
《C程序设计》课程设计指导书0104.docx_第12页
第12页 / 共18页
《C程序设计》课程设计指导书0104.docx_第13页
第13页 / 共18页
《C程序设计》课程设计指导书0104.docx_第14页
第14页 / 共18页
《C程序设计》课程设计指导书0104.docx_第15页
第15页 / 共18页
《C程序设计》课程设计指导书0104.docx_第16页
第16页 / 共18页
《C程序设计》课程设计指导书0104.docx_第17页
第17页 / 共18页
《C程序设计》课程设计指导书0104.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

《C程序设计》课程设计指导书0104.docx

《《C程序设计》课程设计指导书0104.docx》由会员分享,可在线阅读,更多相关《《C程序设计》课程设计指导书0104.docx(18页珍藏版)》请在冰点文库上搜索。

《C程序设计》课程设计指导书0104.docx

《C程序设计》课程设计指导书0104

 

长春理工大学光电信息学院

 

《C程序设计》

课程设计指导书

 

信息工程分院计算机实验室

 

一、课程设计的目的

采用结构化程序设计方法,综合运用C语言的基本知识,尤其是数组、函数、指针及流程控制等,并补充课程中虽未涉及但实用中必要的其他内容,实现一个功能较为齐全的程序实例。

二、设计题目

学生成绩管理系统。

程序的主要功能如下:

1、按学号记录一个班M名学生N门课程的期末考试成绩;

2、逐一显示M个学生的有关数据;

3、实现查找、删除;

4、能统计出补考学生及其相应科目。

三、设计的方法步骤

1、自愿结合,每2~3名同学为一组,选组长一名。

2、由组长主持,全组一起消化理解整个程序的基本功能。

在此基础上,明确每一名同学所承担的具体模块(函数)。

3、尽可能独立地实现系统的功能(组内同学可一起讨论),确有困难,可参照本指导书中所附的示范案例。

4、应认真研读本指导书中示范案例中的思考题,为答辩做准备。

四、课程设计报告的内容

1、课程设计目的;

2、课程设计题目及主要功能;

3、程序中用到的主要数据结构及程序的总体功能框图;

4、所实现的模块(函数)功能及源程序;

5、所实现的模块(函数)中最能代表你设计水平的②算法框图;(可选)

6、程设计的心得体会。

(可选)

五、答辩要求

1、以组为单位答辩,答辩时应提供能运行的完整程序及课程设计报告(每人1份)。

2、组长概述程序的总体功能及总的设计思路后,逐个同学上机演示你本人承担的模块功能并回答老师的提问。

3、提问问题中除指导书上列出的思考题,还包括老师随时针对你的源代码、框图等以及设计中涉及到的基本知识所提出的问题。

附1:

设计参考案例

a)设计的基本思路

我们采用C语言,VC6.0集成开发环境,字符用户界面,结构化程序设计方法。

依据N.Wirth的著名公式:

程序=数据结构+算法

其中数据结构要解决两个问题:

表示一个学生的属性及M个学生的集合;算法则应实现程序的功能。

二、数据结构

用一个结构体类型表示一个学生的属性:

typedefstructstudent{

longnum;/*学号*/

charname[20];/*姓名*/

intscote[N];/*N门功课考试成绩*/

structstudent*next;/*为构成链表而设*/

}Student;

我们采用单链表表示M个学生的集合,这主要是为了熟悉链表的操作。

所以在Student类型中事先已设置了next域。

我们也可以采用结构体数组表示M个学生的集合(当然应去掉Student中的next域)。

三、系统的功能框图

四、系统各功能模块(函数)的实现

1、主模块(main()函数)再任意选择两个模块书写

主模块的主要功能是反复显示菜单,根据用户的选项,调用相应的功能模块,直到用户选择退出。

参考程序如下:

#include"my.h"

charcourse[N][20];

voidmain()

{

Student*head;

Student*p;

charch;

longnum;/*numberofstudents*/

inti;

clrscr();

printf("\nEnter%dcoursenames:

\n",N);

for(i=0;i

{

fflush(stdin);

gets(course[i]);

}

p=(Student*)malloc(sizeof(Student));

if(p==NULL)

{

printf("\nMemoryallocationerror.");

exit

(1);

}

else

{

p->number=0;

p->next=NULL;

strcpy(p->name,"headnode");

for(i=0;i

p->score[i]=0;

head=p;

}

do{

ch=menu();

switch(ch)

{

case'1':

input(head);

break;

case'2':

display(head);

printf("\nEnteranykeytocontinue,please:

");

getche();

break;

case'3':

delete(head);

printf("\nEnteranykeytocontinue,please:

");

getche();

break;

case'4':

printf("\nEnterthenumberofstudent:

");

scanf("%ld",&num);

p=search(head,num);

if(p==NULL)

printf("\n%ldnumberstudentisnotfound.",num);

else

dispnode(p->next);

printf("\nEnteranykeytocontinue,please:

");

getche();

break;

case'5':

reexamine(head);

printf("\nEnteranykeytocontinue,please:

");

getche();

break;

case'6':

printf("\nExittheprogramnow,bye_bye!

");

exit(0);

break;

default:

printf("\nYoushouldpress<1>---<6>");

if(ch=='\n'||ch=='\t'||ch=='')

printf("\nchiswhitecharacter.\n");

else

printf("\nch=%c\n",&ch);

break;

}

}while

(1);

}

_

思考题:

(1)main()函数中的循环怎样才能结束?

(2)除了用do-while,还可用什么循环语句?

(3)head所指的空节点的num域可用于表示什么信息?

2、显示菜单模块

显示一个字符界面的菜单,返回代表用户选项的一个数字字符。

参考程序如下:

#include"my.h"

charmenu()

{

charch;

inti;

clrscr();

printf("\n\n\t1---Input\n");

printf("\n\t2---Display\n");

printf("\n\t3---delete\n");

printf("\n\t4---Search\n");

printf("\n\t5---Reexamine\n");

printf("\n\n\t6---Exit\n");

printf("\n\n\t\tEnteryourchoice:

");

fflush(stdin);

ch=getche();

getche();/*waitfor*/

returnch;

}

思考题:

(1)你能自己设计一个更美观好用的字符用户界面吗?

(2)用单个字符代表用户的选项,如,I代表input,,则菜单程序应如何修改?

(3)函数中的fflush()getche()起什么作用?

3、录入模块

录入学生的数据,以学号从小到大的顺序插入到链表中。

如果链表中已存在该学生,则给出提示信息,不重复录入。

一次可录入0…n名学生数据,当输入学号为负时,结束录入。

参考程序如下:

#include"my.h"

externcharcourse[N][20];

voidinput(Student*h)

{

longnum;

Student*p,*q,*r;

inti,n=0;/*nisnumberofinsertedinonecalling*/

charch;

clrscr();

printf("\nEnterdataforastudent:

\n");

printf("\nNumber:

");

scanf("%ld",&num);

while(num>0)

{

p=search(h,num);

if(p!

=NULL)

{

printf("\n%ldnumberstudenthasbeenexisted.",num);

printf("\nReenternumberforastudent,please:

");

fflush(stdin);

scanf("%ld",&num);

}

else

{

p=(Student*)malloc(sizeof(Student));

if(p==NULL)

{

printf("\nMemoryallocationerror.");

exit

(1);

}

else

{

n++;/*incrementsnumberofstudents*/

p->number=num;

printf("\nName:

");

fflush(stdin);

gets(p->name);

printf("\nEnter%dexaminescores:

",N);

for(i=0;i

{

printf("\n%s:

\t",course[i]);

scanf("%d",&p->score[i]);

}

}

r=h;

q=r->next;

while(q!

=NULL&&num>q->number)

{

r=q;

q=q->next;

}

r->next=p;

p->next=q;

clrscr();

printf("\nEnterdataforastudent:

\n");

printf("\nNumber:

");

scanf("%ld",&num);

}

}

h->number+=n;

printf("\nThereare(is)%dstudent(s)were(was)inserted.",n);

printf("\nThereare(is)total%ldstudent(s).",h->number);

}

思考题:

(1)在录入模块中,为什么要调用查找模块?

(2)为什么在接收输入的学号时,另设一个变量num,而不直接使用p→num?

(定p指向新近成功申请的节点)

(3)插入新节点时,如何在原附加在表头,而与其它情况同样处理可以吗?

(4)在此模块内,表头指针所指的空的头节点起到了什么作用?

(5)在接收学生姓名时,用了库函数gets(name);比运用scanf("%s”,name)好处在哪儿?

(6)不调用search(),代码应如何修改?

(7)果用程序保证每门课的成绩在[0,100]范围内,怎样实现?

4、查找模块

在给定的链表中查找给定学号的学生。

找到则返回给定节点前驱节点的指针,找不到返回null.

这里所以要返回前驱节点的指针,而不是待查节点的指针,原因在于删除模块想调用查找模块,插入节点时要用到待删节点的前驱节点的指针。

这是本查找模块与一般查找不同的一个创意。

参考程序如下:

#include"my.h"

Student*search(Student*h,longnum)

{Student*p,*q;

q=h;

p=h->next;

if(p==NULL)

returnNULL;

else

{

while(p!

=NULL&&p->number!

=num)

{

q=p;

p=p->next;

}

if(p!

=NULL&&p->number==num)

returnq;

else

returnNULL;

}

}

_

思考题:

(1)此search()模块为何返回所查节点前驱的指针?

(2)如果不考虑插入的需要,本模块应如何修改?

5输出补考名单

遍历整个链表,输出需补考的学生名单及补考课目。

这一功能很有实际意义。

它是在遍历链表的基础上进行筛选。

附带求出全班的不及格率。

参考程序如下:

#include"my.h"

voidreexamine(Student*h)

{Student*p;

intpass;/*logicvar.*/

inti;

intnopass=0;/*numberofno-passstudent*/

clrscr();

if(h->number==0)

printf("\nThereisnostudentinthelist.");

else

{

p=h->next;

while(p!

=NULL)

{

pass=1;

for(i=0;i

{

if(p->score[i]<60)

{

pass=0;

nopass++;

break;

}

}

if(pass==0)

{

dispnode(p);

printf("\nEnteranykeytocontinue,please:

");

getche();

}

p=p->next;

}

printf("\n\nThere%stotal%ldstudent(s)",h->number>1?

"are":

"is",h->number);

printf("\nincluded%dstudent%cno-pass.",nopass,nopass>1?

's':

'');

printf("\nNo-passpercentageis%.2f%%.\n",(float)(nopass)/h->number*100);

}

}

思考题:

(1)能设计一个更好的输出格式;

(2)int型变量pass的作用是什么?

while循环中为什么有pass=1;这条语句

7、显示模块遍历链表,逐个显示学生的数据。

此模块功能与输出补考名单类似,只是不必筛选,因此更简单一些。

参考程序如下:

#include"my.h"

voiddisplay(Student*h)

{

Student*p;

clrscr();

if(h->number==0)

printf("\nThereisnostudentinthelist.\n");

else

{p=h->next;

while(p!

=NULL)

{

dispnode(p);

printf("\nEnteranytocontinue,please:

");

getche();

p=p->next;

};

}

{

intmany;/*indicatenumberofstudent>1?

*/

many=h->number>1;

printf("There%s%ldstudent(s)",many?

"are":

"is",h->number);

}

}

思考题:

(1)显示与输出补考名单模块有何相似之处?

(2)自己设计一个更好的输出格式。

6、删除模块:

由用户指定待删除学生的学号,调用search()模块,若找到则删除,否则返回,一次只删除一个学生。

参考程序如下:

#include"my.h"

voiddelete(Student*h)

{Student*p,*q;

intnum;

charanswer;

clrscr();

printf("\nEnternumberofthestudentbeingdeleted:

");

scanf("%ld",&num);

q=search(h,num);

if(q!

=NULL)

{

p=q->next;

dispnode(p);

printf("\nDeletethestudent,areyousure?

(Y/N):

");

fflush(stdin);

answer=getche();

answer=tolower(answer);

if(answer=='y')

{

q->next=p->next;

free(p);

h->number--;

}

else

{

printf("\nYouchangeyouridea,bye_bye.");

}

}

else

{

printf("\nThestudenttobedeletedisnotfound.");

}

}

思考题:

(1)如果想一次可删除多个学生,此模块的程序代码应怎样修改?

(2)free(p);起什么作用?

(3)实际删除节点前,显示一下待删节点包含的信息,然后再次要求用户确认要删除此节点,你认为是否有必要?

程序如何实现的?

附2:

程序的调试:

一位著名的编程大师曾说过:

“程序就是10%的灵感和90%的调试。

所有的编程高手都是调试的能手。

调试可分单模块调试和多模块联调。

关于调试的基本原则和方法以后在《软件工程》等相关课程中会深入探讨,我们在在此仅就以上案例说说具体作法。

为了调试每个模块,首先要对该模块单独编译,以便让编译器为我们尽可能地发现语法方面的错误,然后加以改正,直至编译成功。

然后,我们需要编写一个main()函数,调用该模块,以发现逻辑上的错误,并进一步分析对代码进行优化。

当可以正常执行后再仔细划分程序所能处理数据的各种情况,特别是边界上的数据,能否被正确处理;异常或错误的数据能否被程序所发现并剔除,例如,对menu()函数,就须反复调用,以验证在多次调用时是否每次都能按预期的方式工作。

案例中的fflush()就是在调试中发现问题后,通过查找资料而填加上的。

另外,各模块虽然相互独立,但逻辑上的有一定的先后次序。

建议调试次序先调menu(),search(),input(),然后调其它模块。

联调要建立项目文件(或称工程文件)。

具体操作方法是:

在TurboC2.0的集成开发环境下,用编辑器建一个一个项目文件,(.prj是必须的,文件名可选)内容如下:

main.c

menu.c

input.c

display.c

dispnode.c

search.c

delete.c

reexam.c

命名为student.prj然后在project下拉菜单,的PrjectName项下,注册上述项目文件名。

再接ctrl-F9菜单就自动对项目文件中所列的C源文件进行编译连接并加以执行了。

当然,在各模块正确通过编译后,联调还会产生一些错误,有些错误还比较隐蔽,需要耐心,细致地一一查找改正,这也是锻炼我们实际工作能力的好机会。

调试中要充分利用TurboC2.0集成开发环境提供的各种调试手段,如单步运行、设置断点、添加观察项等。

具体操作请参照教科书上的有关章节。

相信同学们经过艰苦努力,一定会有事前难以预想的收获。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2