C语言课程设计报告(银行存取款管理设计)_第1页
C语言课程设计报告(银行存取款管理设计)_第2页
C语言课程设计报告(银行存取款管理设计)_第3页
C语言课程设计报告(银行存取款管理设计)_第4页
C语言课程设计报告(银行存取款管理设计)_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 C C 语言课程设计语言课程设计 学院 专业 姓 学 指导 银行存取款管理设计 名称: 班级:通信 113 名: 号: 教师: 2012 年 06 月 28 日 2 预习报告预习报告 一:设计题目 银行存取款管理设计 二:功能要求 能够添加和修改以及删除客户文件。 (在客户文件中,每个客户是一条记 录,包括编号、客户姓名、支取密码、客户地址、客户电话、账户总金额)。 能够输入和查询客户存款取款记录。 (在存取款文件中,每次存取款是一 条记录,包括编号、日期、类别、存取数目、经办人。类别分为取款和存 款两种) 。 能够给程序提供运行提示。 三:设计要求 、用 C 语言实现系统; 、函数功能要划分好(结构化程序设计) ; 、界面友好(良好的人机交互) ,加必要的注释; 、要提供程序测试方案,程序一定要经得起测试,宁可功能少一些,也要能 运行起来,不能运行的程序是没有价值的。 四:设计目的 、通过这次课程设计,使我们更加深入地理解和掌握C 语言基本概念,切身 体会用结构化程序设计的工程思想,感受 C 语言的魅力。 、通过这次课程设计,培养我们独立思考、勇于探索、积极创新、严谨求实、 有过必改的工作态度以及较熟的上级操作能力,同时加强我们团结友爱,协作 攻关的团队合作意识。 五:设计框架图 功能选择功能选择 关于关于存存 取取 款款存存 取取 款款客客 户户 资资 办理办理查询查询料料 添添 加加 与操作与操作 查查添添修修删删 存存 款款取取 款款存存 款款取取 款款 询询加加改改除除 办理办理办理办理查询查询查询查询 3 六:函数与变量说明 自定义函数 void main()void main():在里面写了“功能选择”的 SWITCH 函数; void kehu();void kehu();客户资料添加与操作主菜单; void kehu1(struct cou p,char *re,long *h);void kehu1(struct cou p,char *re,long *h);客户资料查询函数; void kehu2(struct cou *p,char *re,long h);void kehu2(struct cou *p,char *re,long h);客户资料添加函数; void kehu3(struct cou *p,char *re,long h);void kehu3(struct cou *p,char *re,long h);客户资料修改函数; void kehu4(struct cou *p,char *re,long h);void kehu4(struct cou *p,char *re,long h);客户资料清楚函数; void kehup(struct cou *p,char *re,long *h);void kehup(struct cou *p,char *re,long *h);客户资料打印函数; void cunq1();void cunq1();存取款办理选择主菜单; void cunq11(struct cou *p,char *re,long h);void cunq11(struct cou *p,char *re,long h);客户存款资料的键入; void cunq12(struct cou *p,char *re,long h);void cunq12(struct cou *p,char *re,long h);客户取款资料的键入; void cunq2();void cunq2();存取款选择查询主菜单; void cunq211(struct cou p,char *re,long *h);void cunq211(struct cou p,char *re,long *h);把顾客存款资料从文件读到缓冲 区; void cunq212(struct cou *p,char *re,long *h);void cunq212(struct cou *p,char *re,long *h);打印存款资料; void cunq221(struct cou p,char *re,long *h);void cunq221(struct cou p,char *re,long *h);把顾客取款资料从文件读到缓冲 区; void cunq222(struct cou *p,char *re,long *h);void cunq222(struct cou *p,char *re,long *h);打印取款资料; void help();void help();使用说明模块。 变量 全局的结构体型数组 w(用来存放 200 多个结构体变量): extern struct couextern struct cou long b;long b; char x20;char x20; long m;long m; char a50;char a50; long d;long d; float j;float j; long bc;long bc; char jin20;char jin20; char jin220;char jin220; char t20;char t20; float j1;float j1; float j2;float j2; 4 float j3;float j3; float j4;float j4; w200; w200; 局部变量 int m;int m;用来在主和其他函数中进行 SWITCHSWITCH 选择判断; 全局变量 longlong t; t;用于记录客户卡号,而卡号是在整个程序中都要用到的,因 为是全局变量,所以一个客户的卡号不能变更。 charchar r20,b20,c20;r20,b20,c20;都为记录客户姓名的一维数组,用在生成客户以及存 取款文件和读取客户文件以及存取款文件; 七:函数调用流程图(客户资料添加与查询 部分部分 ) void main()void main() while(1)while(1) scanf(%d, ; 其他函数其他函数 m=1?m=1? 是 kehu();kehu(); scanf(%d,scanf(%d, switch(m)switch(m); 1 1 m=?m=? 2 2 scanf(%s,b);scanf(%s,b); kehu1(w,b,kehu1(w,b, kehup(w,b,kehup(w,b, break;break; scanf(%s,r);scanf(%s,r); scanf(%ld,scanf(%ld, kehu2(w,r,h);kehu2(w,r,h); break;break; 5 注:上叙具体函数功能见 六(一)函数说明 八:客户资料添加与查询 部分部分 的设计思想 、由于是银行存取款管理设计,考虑到要有较周全的功能要求,所以在设计 之初就对最终成品的功能进行了较为详细的布局, 最终确定了 4 个主功能 (见 源代码) 。 、采用了结构化程序设计思想,在主函数外定义了 voidvoidkehu();kehu();(客户文 件操作) 、void cunq1();void cunq1();(存取款办理) 、void cunq2();void cunq2();(存取款查询) 、voidvoid help();help();(使用帮助)以及他们的嵌套函数,使产品功能更加健全。 、对于如何使每次次级操作后能方便的返回主界面,我们在主函数里用到了 while(1)while(1)这样函数,再在里面用到几个 breakbreak;就实现了返回主界面的功能。 、对于客户及存取款记录的保存我们在这里用到了用 FILEFILE 类型定义文件指 针,从而来以文件形式存放数据,而又用到 fopenfopen 函数打开文件,用 fclosefclose 关闭文件,释放文件缓冲区;又用到 fwritefwrite 函数使数据写入到磁盘保存,用 freadfread 函数把数据拉到缓冲区。 、对于如何使客户文件和客户存取款记录很灵活的结合到一起,我们在主函 数前面构造了一个具有多个成员的结构体,从客户文件记录的客户地址、客户 电话、当前金额等到客户存取款记录的办理时间、办理人、存取金额等全部囊 括在同一个名为 coucou 结构体类型中。 、程序在主函数之前定义了全局的结构体型数组 w w,为相关文件提供了较为灵 活的存取空间,而程序中在 fwritefwrite 函数之前输入了客户姓名和卡号,这实际上 就创建了一个名为所输入客户姓名的文件, 从而在资料读取时直接用姓名读取 非常方便。 。 实验总结报告实验总结报告 九:测试方案 方案、可以直接打开所给的名为“银行存取款及客户资料管理系统.exe.exe”应 用程序进行操作,而操作是纯键盘式的,建议先添加客户文件,或者先查看 “关于”中的帮助。 方案、如果是对源代码进行操作,可以双击名为“银行存取款及客户资料管 理系统.c .c”的.c.c 文件,进入C+C+运行环境,按“重新组建” ,然后点击运行按 钮“! ” ,运行成功,便可进入主界面,相关操作见上。而这同时 C+C+又在后 台生成了.exe.exe 文件,这就是我们所需要的应用程序。 十:调试中问题及解决方案 调试过程并不是一帆风顺的,比如 、如何对客户各种详细资料进行表示,之前我们并没有想到用结构体,然后 再写程序过程中遇到诸多困难,一段时间之后,组员进行仔细研究,并查阅相 关书籍, 最终确定了用结构体这样便捷的数据类型,而这一决定也为后续工作 指明了方向; 6 、对客户资料的打印,因为没有注意到要把文件资料从文件读取到缓冲区, 因而始终不能正确的打印出所要的数据, 而最终在组员的一致努力下,察觉到 问题,然后 freadfread 函数被用到,这问题迎刃而解; 、在程序编写过程中,由于时间关系,难免还有些问题尚未解决,我们不怕 暴露问题,我们只求进步。比如说在写入客户卡号时,用到 fwrite(fwrite( 这样的函数语句, 虽然 h h 已经被我们定义为 longlong 型变量, 然为什么上限为 245 至今尚未得到很好的解决。 但这并不影响我们程序的运行,只要稍微注意一下 卡号,程序还是很理想的。 十一:心得与体会 这次的 C 语言课程设计我们付出不少,一次一次的编写,一次次的修改,花了 不少时间, 甚至有时也用上了休息时间。但我们的收获是那些付出比量不了的。 在一次次的调试与失败中,我们更加坚强,更加专注。在团队合作过程中也发 生过小小的矛盾,但这些终被我们克服,从而转化为难得的友谊,而又使我们 对团队这个概念的认识又上升到一个新的高度。其实一切的一切,都没有知识 来的重要,在这次课程设计过程中我们查阅了大量的资料,而有些是书本上都 较少提到的,而这些给我们的便是知识,无形的宝贵财富。 最后,老师提供给我们这次难得的课程实习机会,我们是受益匪浅的,当看到 一个完整的应用程序出现在我们面前,作为一个初涉软件的学徒来说,又何尝 不是感慨万千呢?我们深怀感恩,一路前行,通信工程,我们来了! 十二:附源程序清单 #include#include #include#include #include#include #include#include voidvoidkehu();kehu(); void kehu1(struct cou p,char *re,long *h);void kehu1(struct cou p,char *re,long *h);/* /*(把顾客资料)从文件读到缓冲区(把顾客资料)从文件读到缓冲区*/ */ void kehu2(struct cou *p,char *re,long h);void kehu2(struct cou *p,char *re,long h);/* /*客户资料输入客户资料输入*/ */ void kehu3(struct cou *p,char *re,long h);void kehu3(struct cou *p,char *re,long h);/* /*新客户资料输入新客户资料输入*/ */ void kehu4(struct cou *p,char *re,long h);void kehu4(struct cou *p,char *re,long h);/* /* 资料清除资料清除*/ */ void kehup(struct cou *p,char *re,long *h);void kehup(struct cou *p,char *re,long *h);/* /*打印顾客资料打印顾客资料*/ */ void cunq1();void cunq1(); void cunq11(struct cou *p,char *re,long h);void cunq11(struct cou *p,char *re,long h);/* /*客户存款资料的键入客户存款资料的键入*/ */ void cunq12(struct cou *p,char *re,long h);void cunq12(struct cou *p,char *re,long h);/* /*客户取款资料的键入客户取款资料的键入*/ */ void cunq2();void cunq2(); void cunq211(struct cou p,char *re,long *h);void cunq211(struct cou p,char *re,long *h);/* /*(把顾客存款资料)从文件读到缓冲区(把顾客存款资料)从文件读到缓冲区*/ */ void cunq212(struct cou *p,char *re,long *h);void cunq212(struct cou *p,char *re,long *h); void cunq221(struct cou p,char *re,long *h);void cunq221(struct cou p,char *re,long *h);/* /*(把顾客取款资料)从文件读到缓冲区(把顾客取款资料)从文件读到缓冲区*/ */ void cunq222(struct cou *p,char *re,long *h);void cunq222(struct cou *p,char *re,long *h); 7 long t;long t; extern struct couextern struct cou ; ; struct cou w200;struct cou w200; void main()void main() int m;int m; while(1)while(1) system(cls);system(cls); printf(printf(欢迎进入银行存取款管理系统欢迎进入银行存取款管理系统n);n); printf(n*n);printf(n*n); printf(*printf(*【功能选择】【功能选择】*n);*n); printf(*printf(*1 1:客户添加与操作:客户添加与操作*n);*n); printf(*printf(*2 2:存取款办理:存取款办理*n);*n); printf(*printf(*3 3:存取款查询:存取款查询*n);*n); printf(*n);printf(*n); printf(-printf(-请按相应的数字选择您的需要请按相应的数字选择您的需要-n);-n); scanf(%d,scanf(%d, switch(m)switch(m) case 1:kehu();break;case 1:kehu();break; case 2:cunq1();break;case 2:cunq1();break; case 3:cunq2();break;case 3:cunq2();break; getchar();getchar(); printf(nnnnnprintf(nnnnn-按回车键返回主界面按回车键返回主界面-);-); getchar();getchar(); long b;long b; char x20;char x20; long m;/*long m;/*密码密码*/ */ char a50;/*char a50;/*地址地址*/ */ long d;long d;/* /*电话电话*/ */ float j;/*float j;/*初始金额初始金额*/ */ long bc;/*long bc;/*存款流水号存款流水号*/ */ char jin20;/*char jin20;/*取款经办人取款经办人*/ */ char jin220;/*char jin220;/*存款经办人存款经办人*/ */ char t20;/*char t20;/*时间时间*/ */ float j1;/*float j1;/*存款金额存款金额*/ */ float j2;/*float j2;/*存后总金额存后总金额*/ */ float j3;/*float j3;/*取款金额取款金额*/ */ float j4;/*float j4;/*取后总金额取后总金额*/ */ 8 voidvoidkehu()kehu() int m;int m; char r20,b20,c20;char r20,b20,c20; long h,k;long h,k; system(cls);system(cls); printf(n*);printf(n*); printf(nprintf(n客户文件:客户文件:1 1:客户资料查询:客户资料查询);); printf(nprintf(n2 2:客户资料添加:客户资料添加);); printf(nprintf(n3 3:客户资料修改:客户资料修改);); printf(nprintf(n4 4:客户资料删除:客户资料删除);); printf(nprintf(n5 5:后退:后退nn);nn); printf(*n);printf(*n); printf(-printf(-按相应的数字以选择您的需要按相应的数字以选择您的需要-n);-n); scanf(%d,scanf(%d, switch(m)switch(m) case 1: case 1: printf(printf(n);n); printf(printf(1 1:客户资料查询:客户资料查询n);n); printf(printf(n);n); printf( printf( 请输入您要查询的客户的姓名请输入您要查询的客户的姓名:n);:n); scanf(%s,b);scanf(%s,b); kehu1(w,b,kehu1(w,b,/* /*从文件读到缓冲区从文件读到缓冲区*/ */ kehup(w,b,kehup(w,b,/* /*打印打印*/ */ break;break; printf(printf(n);n); case 2:case 2: printf(printf(2 2:客户资料添加:客户资料添加n);n); printf(printf(n);n); printf(*printf(*请输入新客户的姓名和卡号请输入新客户的姓名和卡号(1-245)(1-245):*n);*n); scanf(%s,r);scanf(%s,r); scanf(%ld,scanf(%ld, kehu2(w,r,h);kehu2(w,r,h);/* /*把数据从缓冲区输入到文件把数据从缓冲区输入到文件*/ */ break;break; case 3:case 3: printf(printf(n);n); printf(printf(3 3:客户资料修改:客户资料修改n);n); printf(printf(请输入姓名请输入姓名:n);:n); printf(printf(请输入卡号请输入卡号:n);:n); printf(printf(n);n); printf(n-printf(n-请输入您要修改的请输入您要修改的 客户的姓名和卡号:客户的姓名和卡号:n);n); 9 printf(printf(请输入姓名请输入姓名:n);:n); scanf(%s,c);scanf(%s,c); printf(printf(请输入卡号请输入卡号:n);:n); scanf(%ld,scanf(%ld, kehu3(w,c,k);kehu3(w,c,k);/* /*把把 新数据从缓冲区输入到文件新数据从缓冲区输入到文件*/ */ break;break; printf(printf(n);n); case 4:case 4: printf(printf(4 4:客户资料删除:客户资料删除n);n); printf(printf(n);n); printf(n*printf(n*请输入您要删除的请输入您要删除的 客户姓名和卡号客户姓名和卡号*:n);n); void kehu1(struct cou p,char *re,long *h)void kehu1(struct cou p,char *re,long *h) void kehup(struct cou *p,char *re,long *h)void kehup(struct cou *p,char *re,long *h) printf(printf(客户客户 【 %s%s 】详细资料】详细资料n,re);n,re); printf();printf(); printf(printf(客户卡号客户卡号);); printf(%ldn,*h);printf(%ldn,*h); printf();printf(); printf(printf(客户密码客户密码);); printf(%ldn,p*h.m);printf(%ldn,p*h.m); printf();printf(); printf(printf(客户电话客户电话);); printf(%ldn,p*h.d);printf(%ldn,p*h.d); printf();printf(); FILE *fp;FILE *fp; system(cls);system(cls); fp=fopen(re,rb);fp=fopen(re,rb); fread(h,4,1,fp);fread(h,4,1,fp); fread(fread( fclose(fp);fclose(fp); printf(printf(请输入姓名请输入姓名:n);:n); scanf(%s,c);scanf(%s,c); printf(printf(请输入卡号请输入卡号:n);:n); scanf(%ld,scanf(%ld, kehu4(w,c,k);kehu4(w,c,k);/* /*把把 0 0 数据从缓冲区输入到文件数据从缓冲区输入到文件*/ */ break;break; case 5:break;case 5:break; default:default: fprintf(stderr,fprintf(stderr,输入有误输入有误!);!); 10 void kehu2(struct cou *p,char *re,long h)void kehu2(struct cou *p,char *re,long h) void kehu3(struct cou *p,char *re,long h)void kehu3(struct cou *p,char *re,long h) FILE *fp;FILE *fp; system(cls);system(cls); fp=fopen(re,wb);fp=fopen(re,wb); fwrite(fwrite( printf(n*printf(n*请键入顾客请键入顾客 【%s%s】( (卡号卡号 【 %ld%ld 】 ) )的新的客户资料的新的客户资料:*n,re,h);:*n,re,h); ph.b=h;ph.b=h; printf(nprintf(n 修改后客户密码修改后客户密码:n);:n); scanf(%ld,scanf(%ld, printf(nprintf(n 修改后客户地址修改后客户地址:n);:n); scanf(%s,ph.a);scanf(%s,ph.a); printf(nprintf(n 修改后客户电话修改后客户电话:n);:n); scanf(%ld,scanf(%ld, fwrite(fwrite( FILE *fp;FILE *fp; system(cls);system(cls); fp=fopen(re,wb);fp=fopen(re,wb); fwrite(fwrite( ph.b=h;ph.b=h; printf(nprintf(n 客户密码客户密码:n);:n); scanf(%ld,scanf(%ld, printf(nprintf(n 客户地址客户地址:n);:n); scanf(%s,ph.a);scanf(%s,ph.a); printf(nprintf(n客户电话客户电话: :(只接受(只接受 1010 位以下的号码)位以下的号码)n);n); scanf(%ld,scanf(%ld, printf(nprintf(n客户当前金额客户当前金额: :(建议不要使账户满(建议不要使账户满 100100 万)万)n);n); scanf(%f,scanf(%f, fwrite(fwrite( printf(printf(客户地址客户地址);); printf(%sn,p*h.a);printf(%sn,p*h.a); printf();printf(); printf(printf(账户当前金额账户当前金额);); printf(%.2fn,p*h.j);printf(%.2fn,p*h.j); printf();printf(); printf(*printf(*请键入顾客请键入顾客 【%s%s】( (卡号卡号 【 %ld%ld 】 ) )的客户资料的客户资料:*n,re,h);:*n,re,h); fclose(fp);fclose(fp); 11 fclose(fp);fclose(fp); void kehu4(struct cou *p,char *re,long h)void kehu4(struct cou *p,char *re,long h) FILE *fp;FILE *fp; system(cls);system(cls); fp=fopen(re,wb);fp=fopen(re,wb); fwrite(fwrite( printf(nnnnprintf(nnnn*请输入请输入 0 0 键以清除键以清除*:n);*:n); scanf(%s,ph.a);scanf(%s,ph.a); ph.m=0;ph.m=0; ph.d=0;ph.d=0; ph.j=0;ph.j=0; ph.bc=0;ph.bc=0; fwrite(fwrite( fclose(fp);fclose(fp); /*-*/*-*/ void cunq1()void cunq1() int m;int m; char g20;char g20; long m1;long m1; system(cls);system(cls); printf(*n);printf(*n); printf(nprintf(n1. 1.存款办理存款办理2. 2.取款办理取款办理3 3:后退:后退n);n); printf(n*);printf(n*); printf(n-printf(n-按相应的数字以选择您的需要按相应的数字以选择您的需要-n);-n); scanf(%d,scanf(%d, switch(m)switch(m) case 1:case 1: printf(printf(n);n); printf(printf(1. 1.存款办理存款办理n);n); printf(printf(n);n); printf(-printf(- 请输入办理存款业务的客户的姓名和卡号请输入办理存款业务的客户的姓名和卡号(1-245)nn);(1-245)nn); printf(printf(输入客户姓名输入客户姓名:n);:n); scanf(%s,g);scanf(%s,g); printf(printf(输入客户卡号输入客户卡号:n);:n); scanf(%ld,scanf(%ld, cunq11(w,g,m1);cunq11(w,g,m1);/* /*存款数据输入存款数据输入*/ */ 12 break;break; printf(printf(n);n); case 2:case 2: printf(printf(2 2:取款办理:取款办理n);n); printf(printf(n);n); void cunq11(struct cou *p,char *re,long h)void cunq11(struct cou *p,char *re,long h) FILE *fp;FILE *fp; void cunq12(struct cou *p,char *re,long h)void cunq12(struct cou *p,char *re,long h) FILE *fp;FILE *fp; system(cls);system(cls); fp=fopen(re,wb);fp=fopen(re,wb); fwrite(fwrite( printf(*nn);printf(*nn); printf(printf(存款办理存款办理nn);nn); printf(*n);printf(*n); printf(-printf(-请键入顾客请键入顾客 【%s%s 】( (卡号卡号 %ld )%ld ) 的存款明细的存款明细:-n,re,h);:-n,re,h); printf(printf(请输入存款流水号请输入存款流水号:n);:n); scanf(%ld,scanf(%ld, printf(printf(请输入存款数目请输入存款数目( (建议不要一次存超过百万建议不要一次存超过百万):n);):n); scanf(%f,scanf(%f, ph.j2=ph.j+ph.j1;ph.j2=ph.j+ph.j1; ph.j=ph.j2;ph.j=ph.j2; printf(printf(经办人经办人:n);:n); scanf(%s,ph.jin);scanf(%s,ph.jin); printf(printf(办理时间办理时间( (形如形如 2012.06.2.):n);2012.06.2.):n); scanf(%s,ph.t);scanf(%s,ph.t); fwrite(fwrite( fclose(fp);fclose(fp); printf(*printf(*请输入办理取款业务的客户的姓名和卡号请输入办理取款业务的客户的姓名和卡号(1-245)* nn);(1-245)* nn); printf(printf(输入客户姓名输入客户姓名:n);:n); scanf(%s,g);scanf(%s,g); printf(printf(输入客户卡号输入客户卡号:n);scanf(%ld,:n);scanf(%ld, cunq12(w,g,m1);cunq12(w,g,m1); break;break; case 3:break;case 3:break; default:default: fprintf(stderr,fprintf(stderr,输入有误输入有误!);!); 13 /*-*/*-*/ void cunq2()void cunq2() int m;int m; char v20;char v20; system(cls);system(cls); printf(*nn);printf(*nn); printf(printf(1. 1.存款查询存款查询2. 2.取款查询取款查询3 3:后退:后退nn);nn); printf(*n);printf(*n); printf(-printf(-按相应的数字以选择您的需要按相应的数字以选择您的需要-n);-n); scanf(%d,scanf(%d, switch(m)switch(m) case 1:case 1: printf(printf(n);n); printf(printf(1 1:存款查询:存款查询n);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论