第五章 程序编码
主要内容:
程序设计语言
结构化程序设计
程序设计风格
程序复杂性度量
一、程序设计语言的分类:
1、 可分为汇编语言和高级语言两大类。(a/机器语言、汇编——第一、第二代计算机用;b/高级语言——同一个问题,高级语言编码可比汇编少3~7倍,按软件工程的分类,语言的发展大致分4代、3阶段
2、 从语言的内在特征看,高级语言课分为系统实现语言、静态高级语言、块结构高级语言和动态高级语言四大类。
二、语言的选择
1、应用领域的不同决定选择的语言
领域 可选语言
商用 COBOL、4GLS(第四代语言)
科学计算 FORTRAN、PASCAL、PL/1
实时 汇编、ADA
系统 汇编、ADA、C
智能 LISP、PROLOG
2、系统用户的要求决定
用户使用它们熟悉的语言。
3、可以使用的编译程序
运行目标系统的环境中可以提供的编译程序往往限制了对语言的选择。
4、程序员的经验和知识(编程者对语言的熟悉程度)
5、软件可移植性要求
6、当工程规模很大时,而又没有完全合适的语言,可编一个专用的语言。
7、算法与计算复杂性、软件的可靠性
8、数据结构的复杂性,软件的可维护性
9、效率的考虑
10、了解语言的发展前景
总之,选择语言的原则为:
1、 最少的工作量原则
2、 最少技巧性原则
3、 最少错误原则
4、 最少维护原则
5、 减少记忆原则
一、 总原则
1、 先求正确后求快
2、 先求清晰后求快
3、 求快不忘保持程序正确
4、 保持程序整洁以求快
5、 不要因效率而牺牲清晰
二、 好程序标准
1、 易于测试和调试
2、 易于维护
3、 易于修改
4、 设计简单
5、 高效率
据统计,一个典型的程序的50%的执行时间被3%的语句所占用,故这部分代码的效率很重要。
结构化程序设计
结构化程序设计主要包括两方面:
1、 在编写程序时,强调使用几种基本控制结构。
2、 在程序设计过程中,尽量采用自顶向下和逐步细化的原则,由粗到细,一步步展开。
结构化程序设计的主要原则
使用语言中的顺序、选择、重复等有限的基本控制结构表示程序逻辑。
选用的控制结构只准许有一个入口和一个出口。
复杂结构应该用基本控制结构进行嵌套来实现。
程序设计风格
程序实际上也是一种供人阅读的文章,有一个文章的风格问题。应该使程序具有良好的风格。
源程序文档化
数据说明
语句结构
输入/输出方法
源程序文档化
标识符的命名
安排注释
程序的视觉组织
数据说明
为了使程序中数据说明更易于理解和维护,必须注意一下几点。
1、 数据说明的次序应当规范化
2、 说明语句中变量安排有序化
3、 使用注释说明复杂数据结构
数据说明的次序应当规范化
数据说明次序规范化,使数据属性容易查找,也有利于测试,排错和维护。
例如:在Fortran程序中数据说明次序
1、 常量说明
2、 简单变量类型说明
3、 数组说明
4、 公用数据块说明
5、 所有的文件说明
在类型说明中还可进一步要求。
例如:
1、 整型量说明
2、 实型量说明
3、 字符量说明
4、 逻辑量说明
说明语句中变量安排有序化
当多个变量名在一个说明语句中说明时,应当对这些变量按字母的顺序排列。
数据说明:
1、 数据说明应标准化、规范化
2、 当多个变量名在一个语句中说明时,按字母顺序排列
3、 应该对过程和函数的形参排列有序。
A、 输入参数在前,输出参数在后
B、 整型参数在前,实型参数次之,其它参数在后。
使用注释说明复杂数据结构
如果设计了一个复杂的数据结构,应当使用注释来说明在程序实现时这个数据结构的固有特点。
语句结构
语句构造力求简单,直接,不能为了片面追求效率而使语句复杂化。
1、 在一行内只写一条语句
2、 程序编写首先应当考虑清晰性
3、 程序要能直截了当的说明程序员的用意。
4、 除非对效率有特殊的要求,程序编写要做到清晰第一,效率第二
5、 首先要保证程序正确,然后菜肴求提高速度。
6、 避免使用临时变量而使可读性下降。
7、 让编译程序做简单的优化。
8、 尽可能使用库函数。
9、 避免不必要的转移。同时如果能保持程序可读性,则不必用GO TO语句。
10、 尽量只采用三种基本的控制结构来编写程序。
11、 避免使用空的ELSE语句和IF…Then IF …的语句。这种结构容易使读者产生误解。
12、 避免采用过于复杂的条件测试。
13、 尽量减少使用“否定”条件的条件语句。
14、 尽可能用通俗易懂的伪码来描述程序的流程,然后再翻译成必须使用的语言。
15、 数据结构要有利于程序的简化。
16、 要模块化。
17、 利用信息隐蔽,确保每一个模块的独立性。
18、 从数据触发去构造程序。
19、 不要修补不好的程序,要重新编写。
20、 对太大的程序,要分块编写、测试,然后再集成。
输入和输出
输入和输出信息是与用户的使用直接相关的。输入和输出地方式和格式应当尽可能方便用户的使用。
满足运行工程学的输入输出风格。
1. 输入:
输入格式力求简单、一致,并尽可能采用自由格式输入;
使用数据结束或文件结束标志来终止输入,不要让用户来计算输入的项数或记录数。
2、输出
标志所有的输出数据,加必要的说明;
当用户使用程序时,可对用户做到“在线”帮助;
对可能产生重大后果的请求,先给出提示;发生错误时,能迅速恢复正常。
效率
先使程序正确,再使程序有效率;先使程序清晰,再使程序有效率。
写程序前先简化表达式;
尽量避免使用多维数组;
尽量避免使用指针和复杂表;
不要混合使用不同的数据类型;
尽量使用整数运算和布尔表达式;
使用执行时间短的算术运算。
程序设计质量评价
一、 正确性
1、 程序中没有语法错误;
2、 程序运行时没有发现明确的运行错误;
3、 程序中没有不适当的语句;
4、 用有效地测试数据,得到程序的正确结果;
5、 用无效地测试数据,得到程序的正确结果;
6、 用任何可能的数据,使程序在运行时得到正确的结果。
二、 结构清晰性
1、 是否用三中结构化格式表示程序的控制逻辑
2、 是否有一个入口,一个出口
3、 是否严格控制GOTO语句
三、 易修改性
四、 易读性
五、 简单性
程序复杂性量度
程序复杂性主要指模块内程序的复杂性。
代码行度量法:方法的基本考虑是统计一个程序模块的源代码行数目,并以源代码行数作为程序复杂性的度量。
设每行代码的出错率为每100行源程序中可能有的错误数目。
Thayer曾指出,程序出错率的估算范围是从0.0%~7%之间,即每100行源程序中可能存在0.04~7个错误。
McCabe度量法:又称环路复杂性度量,是一种基于程序控制流的复杂性度量方法。
计算环路复杂性的方法:根据图论,在一个强连通的有向图G中,环的个数由以下公式给出:
V(G)=m-n+p
其中,V(G)是有向图G中环路个数,m是图G中弧数,n是图G中结点数,p是图G中强连通分量个数。
为使图成为强连通图,从图的入口点到出口点加一条用虚线表示的有向边,使图成为强连通图。这样就可以使用上式计算环路复杂性。
在例示中,结点数n=11,弧数m=13,p=1,则有V(G)=m-n+p=13-11+1=3
等于程序图中弧所封闭的区域数。
几点说明:
1、环路复杂度取决于程序控制结构的复杂度。
2、环路复杂度是可加的。
3、McCabe建议,对于复杂度超过10的程序,应分成几个小程序,以减少程序中的错误。
Halstead的软件科学
Halstead软件科学研究确定计算机软件卡发中的一些定量规律,它采用以下一组基本的度量值。
程序长度(预测的Halstead长度)
令n1表示程序中不同运算符(包括保留字)的个数,令n2表示程序中不同运算对象的个数,令H表示“程序长度”,则有,H=n1*log2n1+n2*log2n2这里,H是程序长度的预测值,它不等于程序中语句个数。
在定义中,运算符包括:
算术运算符 赋值符(=或:=)
逻辑运算符 分界符(,或;或:)
关系运算符 括号运算符
子程序调用符 数组操作符
循环操作符等
特别的,成对的运算符“Begin…end”等都当做单一运算符。
运算对象包括变量名和常数。
实际的Halstead长度
设N1为程序中实际出现的运算符总个数,N2为程序中实现出现的运算对象总个数,N为实际的Halstead长度,则有N=N1+N2
程序的词汇表
Halstead定义程序的词汇表为不同的运算符种类数n1和不同的运算对象种类数n2的总和。
若令n为程序的词汇表,则有n=n1+n2
程序量
程序量V可用下式得到V=N*log2n
程序量比率(语言的抽象级别)
L=V*/V或L=(2/n1)*(n2/N2)它表明了一个程序的最近错形式的程序量与实际程序量之比,反映了程序的效率,其倒数D=1/L表明了实现算法的困难程序。
程序员工作量
E=V/L
程序的潜在错误
Halstead度量可以用来预测程序中的错误。预测公式为
B=(N1+N2)*log2(n1+n2)/3000
B为该程序的错误数。