1、结构化程序设计综合训练结构化程序设计综合训练主讲:聂明星QQ:2678728943 邮箱:一、本课程的教学目的l结构化程序设计和面向对象程序设计是程序设计的两种典型的思想和方法。目前高校开设的程序设计课程也基本据此划分为两大系列。l本课程以C语言为工具,通过布置一些课题,进行结构化程序设计的综合训练,该课程是计算机专业的一门实验课,通过该课程的学习,l达到以下目的:课程目的课程目的l1 1在软件工程生命周期开发方法的指导下,在软件工程生命周期开发方法的指导下,深入理解和真正掌握自顶向下、逐步求精深入理解和真正掌握自顶向下、逐步求精的的结构化程序设计方法;结构化程序设计方法;l2.2.掌握良好的
2、程序设计编码风格;掌握良好的程序设计编码风格;l3 3学习常用的算法设计的技术;学习常用的算法设计的技术;l4 4进一步提高学生的程序调试能力;进一步提高学生的程序调试能力;l5 5提高学生的程序编程兴趣。提高学生的程序编程兴趣。二、课时的安排序号内 容讲授(学时)实验1结构化程序方法的开发流程1.52管理系统的开发0.53.53游戏程序的开发0.53.54筛选的算法设计技术0.53.55归纳的算法设计技术0.53.56分治的算法设计技术0.53.57贪心算法设计技术0.53.58综合程序开发0.549总结2合计725三、其它说明教材:教材:本课程是实验课程,主要以实验为本课程是实验课程,主要
3、以实验为主。主。综合每个实验考核成绩(综合每个实验考核成绩(80%80%),平时的),平时的考勤情况(考勤情况(20%20%)等,作为期末的成绩,)等,作为期末的成绩,成绩用五级制。成绩用五级制。从三个方面考核每个实验的成绩:功能完从三个方面考核每个实验的成绩:功能完成情况、实验报告以及程序风格、界面设成情况、实验报告以及程序风格、界面设计以及操作方便性。计以及操作方便性。四、结构化开发方法l 在60年代计算机发展初期,产生了一堆问题:程序质量低下,错误频出,进度延误,费用剧增。这些问题导致了“软件危机”。l 在1968年,一群程序员、计算机科学家与工业界人士聚集一起共商对策。通过借鉴传统工业
4、的成功做法,他们主张通过工程化的方法开发软件来解决软件危机,并冠以“软件工程”这一术语。l 软件工程主要讲述软件开发的道理,基本上是软件实践者的成功经验和失败教训的总结。四、结构化开发方法l结构化开发方法是一种设计程序的技术,采用自顶向下逐步求精的设计方法和单入口单出口的顺序、选择和循环三种基本控制结构。l它提出的原则可归纳为32字:“自顶向下,逐步细化;清晰第一,效率第二;书写规范,缩进格式;基本结构,组合而成。”四、结构化开发方法l例如设计房屋就采用了这种方法,先进行整体规划,然后确定建筑物的方案,再进行各部分的设计,最后进行门窗、楼道等的细节设计。l例:要求用筛选法求100 以内的素数(
5、筛选法为:从2到100中去掉2,3,9,10的倍数,剩下的就是100以内的素数)。步骤一:(1)建立2到100的数组A,其中Ai=i;(2)建立2到10的素数表B,其中存放2到10以内的素数;(3)Ai=i 是B 中的任一数的倍数,则剔除Ai;(4)输出A 中所没有被剔除的数;步骤二:前述框架中每一个加工语句都可进一步细化成一个循环语句。(1)/*建立2到100的数组A,其中Ai=i*/for(i=2;i =100;i+)Ai=i;(2)/*建立2到10的素数表B,其中存放2到10以内的素数*/B1=2;B2=3;B3=5;B4=7;步骤二:前述框架中每一个加工语句都可进一步细化成一个循环语句
6、。(3)/*若Ai=i 是B 中的任一数的倍数,则剔除Ai*/for(i=2;i =100;i+)3.1 检查Ai 能否被B 中任意数整除,并将能被整除且商不等于1的数从A 中剔除;(4)/*输出A 中所有没有被剔除的数*/for(i=2;i=b&c d&c+f=g+h;l 不要把程序中的复合表达式与“真正的数学表达式”混淆。l 例如:if(a b c)l 当心副作用。当心副作用。像+这一类运算符具有副作用,它们除了返回一个值外,还将隐含地改变变量的值。这类表达式有时用起来很方便,但有时也会成为问题,因为变量的取值操作和更新操作可能不是同时发生。采用缩进程序结构,是使程序呈现出结构清晰的最省力
7、的方法。比较:for(i=0;i1a+;else if a=1a=a-;else b+;for(i=0;i1 a+;else if a=1 a=a+b;else b+;使用表达式的自然形式使用表达式的自然形式。否定运算的条件表达式比较难理解,比较:if(!(block_id=unblocks)if(block_id=actblks)|(block_idunblocks)分解复杂的表达式分解复杂的表达式。C有很丰富的表达式语法结构和很丰富的运算符,因此应该避免将一大堆东西塞进一个结构中。比较:*xp+=(x=2*k (n-m)?ck+1:dk-);if(2*k=A&(c)=Z)l但如果它在下面的
8、上下文中使用:while(isupper(c=getchar()l那么,每当遇到一个大于等于A的字符,程序就会丢掉它,而下一个字符将被读入并去与Z做比较。因此,上面的实现是错误。宏宏l 除了这个问题外,由于宏是通过文本替换方式实现的,如果忘记给宏的体和参数加上括号,将产生错误。如:#define square(x)(x)*(x)1/square(x)将替换成1/(x)*(x)l 正确的宏应该是:#define square(x)(x)*(x)l 所以建议:除了定义符号常量外,最好避免使用宏。注释l注释是帮助读者阅读程序的一种手段,它们澄清情况,不是添乱。l注释要注意:l不要琐谈明显的东西不要琐
9、谈明显的东西。l注释不要与代码矛盾注释不要与代码矛盾。如果注释的长度超过代码本身,可能就说明这个代码应该修改了。C语言中常见的错误l忽略了“=”与“=”的区别。lif(a=3)then l但C语言中,“=”是赋值运算符,“=”是关系运算符。如:lif(a=3)a=b;C语言中常见的错误l忘记加分号。l分号是C语句中不可缺少的一部分,语句末尾必须有分号。la=1lb=2lif(a%3=0);lI+;C语言中常见的错误l输入变量时忘记加地址运算符“&”。lint a,b;lscanf(%d%d,a,b);l这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&a”指a
10、在内存中的地址。C语言中常见的错误l switch语句中漏写break语句。l 例如:根据考试成绩的等级打印出百分制数段。l switch(grade)l case A:printf(85100n;l case B:printf(7084n;l case C:printf(6069n;l case D:printf(<60n;l default:printf(errorn;)C语言中常见的错误常量表达式中可以包含常量和符号常量,不能包常量表达式中可以包含常量和符号常量,不能包含变量。含变量。#define n 10main()int an,bn+10,C2+3;int m;scanf(“
11、%d”,&m);int am;/errorC语言中常见的错误l在定义数组时,将定义的“元素个数”误认为是可使的最大下标值。lmain()lstatic int a10=1,2,3,4,5,6,7,8,9,10;lprintf(%d,a10);l 常见的内存错误未初始化的指针 void f2(int datum)int*p2;*p2=datum;.常见的内存错误错误的内存释放 void f3()char*p;p=malloc(10);.free(p);.free(p);常见的内存错误struct x*f8()struct x*xp;xp=(struct x*)malloc(sizeof(stru
12、ct x);.free(xp);.return xp.常见的内存错误char*get_str(void)char*str=abcd;return str;intmain(intargc,char*argv)char*p=get_str();printf(%sn,p);return 0;局部变量的空间在函数返回时被释放测试题l1、头文件中的 ifndef/define/endif 干什么用?l2、#include 和#include “filename.h”有什么区别?l3、请写出 float x 与“零值”比较的 if 语句。l4、请写出 char *p 与“零值”比较的 if 语句:测试题char str=“Hello”;char *p=str;int n=10;请计算sizeof(str)=sizeof(p)=sizeof(n)=