软件工程第四章复习资料Word文档下载推荐.docx
《软件工程第四章复习资料Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《软件工程第四章复习资料Word文档下载推荐.docx(34页珍藏版)》请在冰豆网上搜索。
![软件工程第四章复习资料Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2022-11/15/53d6e5ef-50af-473d-89df-55591264f072/53d6e5ef-50af-473d-89df-55591264f0721.gif)
程序语句组成容易识别的块,每块只有一个入口和一个出口。
复杂结构应该用基本控制结构进行组合嵌套来实现。
语言中没有的控制结构,可用一段等价的程序段模拟,但要求该程序段在整个系统中应前后一致。
严格控制GOTO语句,仅在用一个非结构化的程序设计语言去实现一个结构化的构造,或者在某种可以改善而不是损害程序可读性的情况下才可以使用GOTO语句。
大量采用GOTO语句实现控制路径,会使程序路径变得复杂而且混乱,因此要控制GOTO语句的使用。
但有时完全不用GOTO语句进行程序编码,比用GOTO语句编出的程序可读性差。
例如,在查找结束时,文件访问结束时,出现错误情况要从循环中转出时,使用布尔变量和条件结构来实现就不如用GOTO语句来得简洁易懂。
对于常用的高级程序设计语言,一般都具备前述的几种基本控制结构。
即使不具备等同的结构,也可以采用仿真来实现。
下面以FORTRAN77为例进行说明,参看图4.1。
基本控制结构
用FORTRAN77模拟基本控制结构
判断语句
if(p)S1;
elseS2;
IF(p)THEN
S1
ELSE
S2
ENDIF
先判断型循环语句
while(p)
S;
100CONTINUE
S
GOTO100
后判断型循环语句
doS;
while(p);
IF(p)GOTO100
图4.1用FORTRAN77语句实现基本控制结构
(2)程序设计自顶向下,逐步求精
在详细设计和编码阶段,应当采取自顶向下,逐步求精的方法,把一个模块的功能逐步分解,细化为一系列具体的步骤,进而翻译成一系列用某种程序设计语言写成的程序。
例如,要求用筛选法求100以内的素数。
所谓筛选法,就是从2到100中去掉2,3,…,9,10的倍数,剩下的就是100以内的素数。
为了解决这个问题,可先按程序功能写出一个框架。
main(){
建立2到100的数组A[],其中A[i]=i;
-------------------------1
建立2到10的素数表B[],其中存放2到10以内的素数;
------------2
若A[i]=i是B[]中任一数的倍数,则剔除A[i];
--------------------3
输出A[]中所有没有被剔除的数;
-------------------------------4
}
上述框架中每一个加工语句都可进一步细化成一个循环语句。
/*建立2到100的数组A[],其中A[i]=i*/------------------------1
for(i=2;
i<
=100;
i++)A[i]=i;
/*建立2到10的素数表B[],其中存放2到10以内的素数*/-----------2
B[1]=2;
B[2]=3;
B[3]=5;
B[4]=7;
/*若A[i]=i是B[]中任一数的倍数,则剔除A[i]*/--------------------3
for(j=1;
j<
=4;
j++)
检查A[]所有的数能否被B[j]整除并将能被整除的数从A[]中剔除;
--------3.1
/*输出A[]中所有没有被剔除的数*/-------------------------------4
for(i=2;
i<
i++)
若A[i]没有被剔除,则输出之;
-----------------------------------4.1
继续对3.1和4.1细化下去,直到最后每一个语句都能直接用程序设计语言来表示为止。
B[1]=2;
/*若A[i]=i是B[]中任一数的倍数,则剔除A[i]*/
for(j=1;
/*检查A[]所有的数能否被B[j]整除并将能被整除的数从A[]中剔除*/
if(A[i]/B[j]*B[j]==A[i])A[i]=0;
/*输出A[]中所有没有被剔除的数*/
i++)
/*若A[i]没有被剔除,则输出之*/
if(A[i]!
=0)
printf(“A[%d]=%d\n”,i,A[i]);
自顶向下,逐步求精方法的优点:
①自顶向下,逐步求精方法符合人们解决复杂问题的普遍规律。
可提高软件开发的成功率和生产率;
②用先全局后局部,先整体后细节,先抽象后具体的逐步求精的过程开发出来的程序具有清晰的层次结构,因此程序容易阅读和理解;
图4.2程序的树形结构
③程序自顶向下,逐步细化,分解成一个树形结构(如图4.2所示)。
在同一层的结点上做的细化工作相互独立。
在任何一步发生错误,一般只影响它下层的结点,同一层其它结点不受影响。
在以后的测试中,也可以先独立地一个结点一个结点地做,最后再集成。
④程序清晰和模块化,使得在修改和重新设计一个软件时,可复用的代码量最大;
⑤每一步工作仅在上层结点的基础上做不多的设计扩展,便于检查;
⑥有利于设计的分工和组织工作。
(3)数据结构的合理化
H.Mills指出,结构化程序设计主要是想从程序的控制结构入手,消除不适应的、容易引起混乱的GOTO语句。
这只是问题的一个方面,而问题的另一方面,过去没有注意到的是数据结构的合理化问题,即数据结构访问的规范化,标准化问题。
假如数据结构中常使用数组、指针等数据类型,则对它们必须采取随机访问,这样势必产生访问上的混乱。
例如,要访问数组元素A[i][j],必须先对下标i,j访问,造成访问忽前忽后,这与GOTO语句造成的混乱类似,同样是有害的。
H.Mills指出,解决这一问题的办法是用栈和队列去代替数组和指针。
栈与队列分别是按后进先出(LIFO)和先进先出(FIFO)的原则进行存取的。
在程序中用栈和队列代替数组和指针,用合理的规范的顺序存取代替随机存取,将克服随机存取带来的麻烦。
而且有人做了证明,所有使用数组和指针的程序,都可以使用栈和队列的程序等价替换。
2.程序设计风格
在软件生存期中,人们经常要阅读程序。
特别是在软件测试阶段和维护阶段,编写程序的人与参与测试、维护的人都要阅读程序。
因此,阅读程序是软件开发和维护过程中的一个重要组成部分,而且读程序的时间比写程序的时间还要多。
70年代初,有人提出在编写程序时,应使程序具有良好的风格。
程序设计风格包括4个方面:
源程序文档化,数据说明,语句结构和输入/输出方法,力图从编码原则的角度提高程序的可读性,改善程序质量。
(1)源程序文档化
①符号名的命名
符号名即标识符,包括模块名、变量名、常量名、子程序名、数据区名、缓冲区名等。
这些名字应能反映它所代表的实际东西,应有一定实际意义。
名字不是越长越好,过长的名字会使程序的逻辑流程变得模糊,给修改带来困难。
所以应当选择精炼的意义明确的名字,改善对程序功能的理解。
必要时可使用缩写名字,但缩写规则要一致,并且要给每一个名字加注释。
在一个程序中,一个变量只应用于一种用途。
就是说,在同一个程序中一个变量不能身兼几种工作。
②程序的注释
夹在程序中的注释是程序员与日后的程序读者之间通信的重要手段。
正确的注释能够帮助读者理解程序,可为后续阶段进行测试和维护,提供明确的指导。
因此,注释决不是可有可无的,大多数程序设计语言允许使用自然语言来写注释,这就给阅读程序带来很大的方便。
一些正规的程序文本中,注释行的数量占到整个源程序的1/3到1/2,甚至更多。
序言性注释:
通常置于每个程序模块的开头部分,它应当给出程序的整体说明,对于理解程序本身具有引导作用。
有些软件开发部门对序言性注释做了明确而严格的规定,要求程序编制者逐项列出的有关项目包括:
程序标题、有关本模块功能和目的的说明、主要算法、接口说明、有关数据描述、模块位置、开发简历等。
功能性注释:
嵌在源程序体中,用以描述其后的语句或程序段是在做什么工作,不要解释下面怎么做,因为解释怎么做常常是与程序本身重复的,并且对于阅读者理解程序没有什么帮助。
书写功能性注释,要注意:
·
用于描述一段程序,而不是每一个语句;
用缩进和空行,使程序与注释容易区别;
注释要正确。
③视觉组织
利用空格、空行和移行,提高程序的可视化程度。
恰当地利用空格,可以突出运算的优先性,避免发生运算的错误。
自然的程序段之间可用空行隔开;
对于选择语句和循环语句,把其中的程序段语句向右做阶梯式移行。
这样可使程序的逻辑结构更加清晰,层次更加分明。
(2)数据说明
在编写程序时,需注意数据说明的风格。
为了使程序中数据说明更易于理解和维护,必须注意以下几点。
数据说明的次序应当规范化,使数据属性容易查找。
当多个变量名用一个语句说明时,应当对这些变量按字母的顺序排列。
如果设计了一个复杂的数据结构,应当使用注释来说明在程序实现时这个数据结构的固有特点。
(3)语句结构
在设计阶段确定了软件的逻辑流结构,但构造单个语句则是编码阶段的任务。
语句构造力求简单,直接,不能为了片面追求效率而使语句复杂化。
在一行内只写一条语句,并且采取适当的移行格式,使程序的逻辑和功能变得更加明确。
程序编写首先应当考虑清晰性,不要刻意追求技巧性,使程序编写得过于紧凑。
程序编写得要简单,写清楚,直截了当地说明程序员的用意。
除非对效率有特殊的要求,程序编写要做到清晰第一,效率第二。
不要为了追求效率而丧失了清晰性。
事实上,程序效率的提高主要应通过选择高效的算法来实现。
首先要保证程序正确,然后才要求提高速度。
反过来说,在使程序高速运行时,首先要保证它是正确的。
让编译程序做简单的优化。
尽可能使用库函数。
避免使用临时变量而使可读性下降。
尽量用公共过程或子程序去代替重复