C语言上机实验Word文档格式.docx
《C语言上机实验Word文档格式.docx》由会员分享,可在线阅读,更多相关《C语言上机实验Word文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
voidsearchRecord(ADDR*head);
这个函数将根据输入的姓名查找通讯信息。
voidsaveFile(ADDR*head);
这个函数将链表中储存的通讯信息写入文件。
ADDR*readFile();
这个函数从文件中读取信息,将存入链表中。
voiddisplay(ADDR*head);
这个函数将显示链表中储存的通讯录信息。
在通讯录中,每个人的通讯信息用户一条记录表示,其中仅包括姓名,电话号码两个数据项。
考虑到每本通讯录所含有的记录条数有可能相差很远,所以准备选用链表作为在内存中表示通讯录信息的储存结构,它的结点结构类型应该定义为:
typedefstructaddress/*通讯录信息结构*/
{
charname[24];
chartele[24];
structaddress*next;
}ADDR
为了能够将通讯录的信息独立于程序永久性地保护起来,需要利用C语言提供的文件类型将通讯录信息存储磁盘文件。
2详细程序描述及相应流程图
3详细程序代码
❶模块顺序:
⑴定义模块⑵函数声明模块⑶主函数模块⑷主菜单模块⑸菜单选择模块⑹释放链表结点模块⑺添加信息模块⑻创建通讯录模块⑼删除一条记录信息模块⑽按照姓名查找信息模块⑾将通讯录信息写入文件模块⑿从文件中读取通讯录信息模块⒀显示通讯录信息模块
❷详细代码:
⑴定义模块
#include<
stdio.h>
stdlib.h>
string.h>
conio.h>
}ADDR;
⑵函数声明模块
⑶主函数模块
main()
ADDR*head=NULL;
/*表头指针*/
intchoice;
/*clrscr();
system("
clr"
);
*/
do
{
choice=choiceItem();
/*菜单选择*/
switch(choice)
case1:
head=createRecord(head);
/*创建通讯录*/
break;
case2:
head=addRecord(head);
/*添加记录*/
case3:
head=deleteRecord(head);
/*删除记录*/
case4:
searchRecord(head);
/*查找记录*/
case5:
display(head);
/*显示通讯录*/
case6:
saveFile(head);
/*保存到文件*/
case7:
head=readFile();
/*从文件读通讯录数据*/
}
while(choice!
=0);
printf("
\n\nBye!
"
freeRecord(head);
}
⑷主菜单模块
voiddisplayMenu(void)/*显示菜单*/
*/
\n=============MENU=============\n"
\n1......CreatNewRecord\n"
\n2......AddRecord\n"
\n3......DeleteRecord\n"
\n4......SearchRecord\n"
\n5......DisplayRecord\n"
\n6......SavetoFile\n"
\n7......ReadfromFile\n"
\n0......ExitSystem\n"
\nChoice:
⑸菜单选择模块
intchoiceItem(void)/*菜单选择*/
charline[80];
displayMenu();
gets(line);
/*scanf("
%d"
&
choice);
choice=atol(line);
while(choice<
0||choice>
7);
returnchoice;
⑹释放链表结点模块
voidfreeRecord(ADDR*p)/*释放链表结点*/
ADDR*q;
while(p!
=NULL)
q=p;
p=p->
next;
free(q);
/*依次释放各结点*/
⑺添加信息模块
ADDR*addRecord(ADDR*p)/*输入一组记录,添加到链表*/
ADDRhead,*q;
head.next=p;
p=&
head;
while(p->
next!
=NULL)/*将当前指针移动到链表尾端*/
while
(1)
chartext[80];
q=(ADDR*)malloc(sizeof(ADDR));
if(q==NULL)
returnhead.next;
q->
next=NULL;
\n\nPleaseenterthenameandtelehonenumber:
gets(text);
/*读取一行文本*/
if(text[0]=='
\0'
)break;
/*空行为结束标志*/
sscanf(text,"
%s%s"
q->
name,q->
tele);
/*分解名称和电话号码*/
p->
next=q;
/*在链表尾端添加结点*/
p=q;
/*更新当前指针*/
⑻创建通讯录模块
ADDR*createRecord(ADDR*p)/*创建新通讯录*/
freeRecord(p);
/*释原链表所占的空间*/
returnaddRecord(NULL);
/*输入一组记录,创建链表*/
⑼删除一条记录信息模块
ADDR*deleteRecord(ADDR*p)/*根据输入的姓名删除记录*/
charname[32];
ADDR*q,head;
/*前驱结点*/
\nPleaseinputtheNamefordeletion:
gets(name);
/*输入姓名*/
for(head.next=p,q=&
p!
=NULL;
p=p->
next)
if(strcmp(p->
name,name)!
=0)/*不等于当前结点中的姓名*/
/*以当前结点作为前驱结点*/
else
next=p->
/*从链表中移出当前结点*/
free(p);
/*释放当前结点*/
\nThe%shasbeendeleted.\n"
name);
\nNOrecordof%s\n"
⑽按照姓名查找信息模块
voidsearchRecord(ADDR*p)/*通过输入的姓名查询记录*/
{
\nPleaseinputthenameforSeach:
for(;
name,name)==0)/*找到指定记录*/
\nName\tTelephone\n%s\t%s\n"
p->
name,p->
return;
⑾将通讯录信息写入文件模块
voidsaveFile(ADDR*p)/*将记录信息写入文件*/
FILE*fp;
charfname[32];
\nPleaseinputtheFileName:
gets(fname);
/*输入文件名*/
if((fp=fopen(fname,"
wb"
))==NULL)/*打开文件*/
Cannotopenthisfile!
\n"
\nSaveFile..."
next)/*遍历链表*/
fwrite(p,sizeof(ADDR),1,fp);
/*写一个记录到文件*/
fclose(fp);
OK\n"
⑿从文件中读取通讯录信息模块
ADDR*readFile(void)/*从文件中读取记录信息*/
ADDR*p,*q,head={"
"
NULL};
rb"
Connotopenthisfile!
returnNULL;
\nReadFile..."
q=&
/*尾端结点指针*/
while(!
feof(fp))/*读结束?
p=(ADDR*)malloc(sizeof(ADDR));
if(p==NULL)
if(1!
=fread(p,sizeof(ADDR),1,fp))
/*读失败时*/
next=p;
/*在链表尾端添加*/
/*更新尾端指针*/
/*关闭文件*/
⒀显示通讯录信息模块
voiddisplay(ADDR*p)/*显示所有记录信息*/
\nName\tTelephone\n"
%s\t%s\n"
四系统调试及运行介绍
⑴调试部分
当我把这个程序做完的时候,我的心情十分的高兴。
这个程序虽然十分的简单,但我在做的过程中可谓是困难重重。
在做这个程序的时候,总是好不容易把这个模块做好了,然而加入另一个模块的时候又是一堆错误。
当好不容易没有错误的时候有运行不了。
一阵喜一阵悲让我深刻理解到C语言的巧、灵、变。
下面是我调试过程遇到的问题及解决办法。
这个程序从写到敲入计算机内花了我好几个星期的时间。
写程序还不是最难的,而当把所有的都写完了调试的时候发现全是错误,那才是最打击人的。
明明感觉写得很好的程序,也参考了资料,但就是一直有错误。
没办法,解决方法只有是继续查找资料,请教学长、学姐。
期间又反复看书理解,去图书馆,上网参考资料,问同学自己这个部分怎么错误。
有时一个很简单的错误自己检查半天也找不到,自己进入了思维定式出不来了,而同学一点就发现了。
这让我充分感受到C语言的灵活和团队合作的重要性。
最后终于经过自己努力和别人的帮助把它写完了,虽然编写这个程序花去了我很多的时间,但我也从中学到了很多的东西,这让我对C语言有了更多的认识。
这次的编程让我对没学过的文件、结构体、指针等有了了解,同时也让我巩固了函数、数组、循环、if语句、switch语句还有链表等知识。
这次程序的编译中遇到许多诸如半角和全角分辨不清,导致程序编译错误,颇有体会。
还有就是经常忘记在英文状态下输入符号,由于这个我反复看程序,但就是找不到哪里错,就只有重新输程序。
虽然浪费了很多时间,但我也因此对这个问题有了更多的记忆。
在这次编程中我出现了以下这些关于书本上的知识的错误。
1、在if的条件句我出现了赋值语句,对于这个问题我可谓是受尽折磨,因为我没有注意书上写的if的条件中可以包含赋值表达式,但不能包含赋值语句。
2、在使用switch语句时,忘记了每一个case的常量表达式的值必须互不相同。
3、在使用函数的嵌套调用时,没有注意到C语言不能嵌套定义函数,它只可以嵌套用函数。
4、在使用文件时没有注意用“w”方式打开的文件只能用于该文件写数据(即输出文件),而不能用来向计算机输入。
从这个细节中我知道了文件打开时要注意打开的方式。
5、输入数据的错误。
我们最容易犯错误,程序设计必须考虑到使用者可能犯的各种错误,考虑用户在选择菜单时各种输入可能,也考虑用户在输入各种数据信息和命令时键入错误信息的可能性,采用了gets()函数,避免了使用scanf()函数对输入数据格式的局限。
6、我在储存的时候出现了错误,就采用了所有动态申请的内存空间,在使用之后,释放。
7、在使用结构体时要注意不要忽略最后的分号。
在定义结构体类型变量时要注意与变量定义的区别。
在定义结构体变量时不仅要求指定变量为结构体类型,而且指定为某一特定的结构体类型,而在定义变量为整型是,只需单化指定为int型即可。
从这我总结到C语言确实是灵巧多变,给了编译者很大的自由空间。
本来无法实现功能但也不提示错误。
所以说程序能运行并不代表程序已经大告成。
真正实现了功能才算是完成一个程序。
最后小问题又检查了一遍。
反复检查试完功能后全部正常。
我的作业就全部调试完成了。
整个过程可以说是对我的耐力和智力的考验。
不过欣慰的是自己总算完成了。
这是对自己的一种考验,自己也得到了一些收获。
我相信编完这个程序之后,我会对C语言的理解更加深刻。
⑵运行结果
最开始进入系统,需要写入数字选择菜单。
包括各种功能。
图中有显示。
按相应的选项执行相应的功能。
录入通讯录信息录入完毕后可对信息进行相应的管理如修改、查询、删除。
退出系统有退出显示,当操作错误或者文件错误时提示相应的错误。
下面就是我的通讯录系统运行的各种情况及截图,可能图截得不是太清楚。
图一:
主菜单界面
图二:
创建通讯录显示界面
图三:
增加记录
图四:
删除记录
图五:
查找模块
图六:
显示通讯录
图七:
将通讯录写入文件
图八:
从文件中读取信息
图九:
退出界面
五总结
做了好几个星期,终于把这个程序写完了。
内心有很多感触,真正自己尝试才知道编程是多么不容易。
从最开始的选材,实践到最后完成。
去了多少次图书馆又上了多少次机我已记不清了,但自己努力的过程却深深印在我心中。
查阅资料,规划想法,付诸实践,写了几页的代码,又一个一个字符敲进入,这些过程是对自己的考验也是宝贵的收获。
这个过程锻炼了我的毅力,磨砺了我的耐心,更重要的是自己又多学了一些编程知识。
当看到编译成功的那一刻,我知道,我的努力没白费。
由于我的知识有限,所以编译的程序简单,功能还不全面,但我相信随着我对C语言学习的深入,我相信我会完善这个系统的,也希望老师多加指正。
同时经过这次的编程对链表有了很多的理解。
我这次编程采用了链表维护一组电话号码记录。
实现方法有以下以下一些。
(1)通过一个结点指针变量来管理整个链表的,作为程序中链表的唯一标识。
(2)在各个记录的维护过程中,利用一个指针变量指向当前处理的结点,并通过该指针处理当前结点中的数据。
通过指针的移动,逐个处理各个结点的数据。
(3)在创建、删除等链表维护功能的实现中,经常需要找到当前结点之前的结点,也就是前驱结点。
随着处理的进展,也需要更新前驱结点指针。
(4)使用前驱结点的问题是对于第一个结点不存在的前驱结点,需要特殊的处理逻辑。
可能带来控制逻辑的混乱。
程序中多次采用一个局部变量head作为第一结点的前驱结点,保证head.next中始终维护真正的链表头指针,从而避免控制逻辑的混乱。
以上就是我计算机引论的全部作业,谢谢老师批阅。
同时时经过这次的编程,让我对C语言产生了更浓厚的兴趣,我相信在今后的学习中,我会编译出更好的程序。