
7章实现 西安电子科技大学 软件工程教学课件.ppt
125页第七章 实现,西安电子科技大学网络学院课程,第七章 编码,程序设计的语言 翻译过程 在编程步骤中,要把详细设计的表达式翻译成编程语言的构造,编译器接受作为输入的源代码,源代码生成作为输出并从属于机器的目标代码,然后编译器把输出目标代码进一步翻译成机器代码(它是真正指令),它的驱动放在CPU中的微代码 程序设计的语言分类: 基础语言(BASIC,FORTRAN,COBOL,ALGOL) 结构语言(PL/1,PASCAL,C.ADA) 专用语言(FORTH,PROLOG,LISP) 系统实现语言(C) 语言分类 静态高级语言(COBOL,FORTRAN) 动态高级语言 块结构高级语言(ALGOL,PASCAL) 可视化编程语言(VB,VC,PB,BC,C++BUILDER),第七章 编码,7.1.1程序设计语言特点与特性 编程语言的特点 心理学观点 在编程中,人的因素极其重要,所以,语言的心理学特性对代码的翻译和实现的设计都有重要影响 1、一致性 一致性是表示某种语言使用一致的符号,采用看似任意的限制和支持语法或语义例外规则的程度例如,FORTRAN用圆括号用作数组下标的界限符,算术运算有限次序的修改符等,容易引起难以觉察的错误。
2、多义性 编程语言的多义性是程序员的理解一般一条语句一个解释有时却有多种解释 第七章 编码,3.紧凑性 紧凑性是一种面向代码信息量的表示.度量紧凑性的语言属性有: (1) 该语言支持结构化构造和逻辑“块”的程度 (2) 所用的关键字和缩写词的种类 (3) 数据类型和缺省特性的品种 (4) 算术运算和逻辑运算的数量 4.局域性 是编程语言的综合特性,当语句可以组合为程序块,结构化构造可以直接实现,设计代码和合成代码具有高的模块性和聚合时,局域性就高. 5.线性: 是一种心理特性.它与保持功能域的概念紧密联系即当遇到一个逻辑运算线性序列时,人容易理解,外延分支和外延大的循环都违反处理的线性,而结构化构造的直接实现有助于编程语言的线性第七章 编码,工程观点 是把重点放在具体的软件开发项目的需要上,虽然,可以对源代码提出许多要求,但常常为源代码建立一组工程特性 ( 1 ) 易于把设计翻译为代码. ( 2) 编译器效率 (3) 源代码可移植性:源代码不修改或很小修改,直接搬到 另一编译器,环境变了,源码不变,, (4) 开发工具的可用性 : 许多编程语言有调试工具,内部 编辑,源码控制,浏览器,宏处理器,反向工程工具和其 他工具. (5) 可维护性: 源码必须可读,并能根据设计的变化进行修改等.,第七章 编码,选择一种语言 语言选择的一般哲理是:从问题开始,判断它的需要是什么,以及它们相关的重要性,因为一种语言不可能同时满足各种需求,那么就应该对各种需求进行权衡,比较各种可用语言的适用程度,最后选择一种被认为是最适用的. 用于评价语言的准则: (1) 一般的应用领域 (2) 算法和计算的复杂性 (3) 软件运行环境 (4) 性能考虑 (5) 数据结构的复杂性 (6) 软件开发人员的知识 (7) 一个好的编译器或交叉编译器的可使用性.,第七章 编码,7.1.2 程序设计途径与编写程序的风格 l 程序设计方法论 方法论: 自上而下:程序可读性好,可靠性高。
自下而上:局部优化:系统整体性差,但能及时发现算法是否可行,返工性好 编程人员的主要差别在于比前面介绍了二种人是如何编程的,但各有优缺点,可以采用: 在软件预言和攻关,技术积累时采用自下而上,在紧迫工程时,采用自上而下.,第七章 编码,l 程序设计工具 1.编译程序 它是最基本的程序设计工具,它可以诊断出程序中的错误,减少开发成本,生成高效率的机器代码 2.代码管理系统 l 编码风格 编码风格实际上是一种编码原则,编码对象是有两个: 机器:编码要为机器所理解与执行 人: 能读懂,方便使用与维护 编码风格最重要的有两条:简单和清晰 程序中与编码风格有关的因素有代码的文档化,数据说明方法,语句构造处理和I/O技术,下面我们分别讨论这些因素第七章 编码,l 代码文档化 代码文档化是从选择标识符(变量、标号)的名字开始,接着是写程序和安排注释,最后是程序的整个组织形式的视觉所有的编程语言都允许用自然语言在程序中进行注释,问题在于: (1) 多少注释才算够? (2) 注释应该放在什么位置? (3) 注释是否会使逻辑流不清楚? (4) 注释是否会使读者误解? (5) 注释是否会使程序不可维护? 这些问题很难回答,但有一点很清楚:软件必须包含代码的内部说明,开发者可以用注释的方法对代码内部进行说明。
第七章 编码,l 注释(注释范例): ① 序言性注释:应该安排在每个模块的起始部分,其内容有: (1) 说明每个模块的用途,并指明它的功能 (2) 接口描述,应包括:调用序列,每个参数的描述,以及 所有从属模块清单 (3) 有关数据的讨论,包括:重要的变量和它们的用途、限 制或约束条件,以及其他必要的信息 (4) 开发历史,包括:模块设计人姓名,评审人姓名及日期 、修改说明及日期 ② 功能性注释: 应嵌入在源代码体内,用来描述处理功能书写这种注释的基本原则是:注释要解释程序代码,还应提供附加说明此外,注释还应做到以下几点: (1) 注释是说明代码块,而不是注释每一行代码 (2) 使用空行或缩格,以便很容易的区分注释和代码 (3) 注释一定要正确,以免引起错误,造成误解序言性注释:,,,功能性注释:,第七章 编码,当使用PDL表示进行详细设计时,设计文档可以作为注释直接嵌入在源代码体内,它是十分有效,当修改设计或代码时,确保设计和代码都能维护 (1)数据说明的次序应规范化,可使数据属性更容易寻找,有利于测试、纠错和维护 (2)当多个变量名在一条语句说明时,变量名的次序应按字母序排列 (3)如设计中,确定了一个复杂的数据结构,就应该用注释说明在编程语言实现时的特点。
第七章 编码,l 语句构造 软件逻辑构造也是在设计时确定的,而每个语句构造则是编码步骤中的一部分语句构造应当遵守的原则是:每条语句应当简单而直接,同时也不应为了追求运行效率而使代码变得复杂化,而让人难以理解 为了提高代码的可读性,最好一行只写一条语句(因为许多编程语言允许一行写多条语句)还应采用缩排的方式,这样可以使程序段的逻辑结构和功能特征更加清晰第七章 编码,单条源代码(语句)的简化方法如下: (1) 避免使用复杂的条件测试 (2) 排除测试条件的“非” (3) 避免多重循环嵌套或条件嵌套 (4) 用括号的方法使逻辑表达式或算术表达式更 加清晰 (5) 用空格或可读的符号使语句内容更加清晰 (6) 只使用国家标准 (7) 要时时想着,如果代码不是我编写的,我也能读懂它 总之,一句话:要力求直接了当,简单明了第七章 编码,l I/O I/O的风格不是在编码时确定的,而是在软件需求分析和实际中就确定了的但是,在编码时,I/O的实现方式决定了用户对系统特征的可接受程度 不管软件的性质是批处理,还是交互的,在设计和编码时,都应考虑下述有关I/O风格原则: (1) 检查所有输入数据的有效性 (2) 检查输入项上的重要组合的合法性。
(3) 保持简单的输入格式 (4)使用数据结束说明符,而不应要求用户规定输入项目的数量 (5)用标记标明交互的输入请求,应规定可以使用的选择值或 边界值 (6)当编程语言对格式有严格的要求时,应保持输入格式的一致性 (7) 给所有输出加标记,并设计所有输出报告第七章 编码,l 效率 有三条准则应该指出的: (1)效率是一种性能要求因此,应当在软件 需求时规定软件效率应按实际需要来要 求,而不是越高越好 (2) 一个良好的设计可以提高效率 (3) 代码效率与代码的简单性紧密联系第七章 编码,代码效率 源代码的效率与详细设计阶段所确定的算法效率直接相关但编码风格也会影响运行速度和对内存的需要一般可以使用以下准则: (1) 在进行编码以前,应简化算术表达式和逻辑表达式 (2) 要细心的评价嵌套循环,以确定能否把一些语句或表达式移到循环外边 (3) 应尽量避免使用多维数组 (4) 应尽量避免使用指针和复杂的列表 (5) 采用快的算术运算 (6) 即使语言允许,也不要采用混合数据类型 (7) 只要可能,就应当采用整型算术表达式和布尔表达式第七章 编码,内存效率 在大型计算机和工作站领域中,内存限制大多已是过去的事了。
低成本内存提供了大的物理地址空间,而虚存管理为应用软件提供了巨大的逻辑地址空间,对于这样的环境,内存效率不等于使用最小内存倒不如说,内存效率必须注意考虑操作系统的分页特征,而代码局域性或通过结构化构造功能域的管理才是减少分页和提高效率的最好办法 尽管低成本、高密度内存芯片发展很快,但在嵌入式微处理器领域中,内存限制仍是一个非常实际非常重要的问题如果系统需求(如高容量低成本产品)要求最小内存,那么为了内存的压缩性质,必须非常细心的对高级语言的编译程序进行估算,或作为最后的手段,也可以采用汇编语言第七章 编码,I/O效率 当讨论I/O效率时,有两类I/O要考虑 (1) 由人支配的I/O (2) 取决于其他设备的(如磁盘或另一台计算机)的I/O 提高I/O效率的简单原则: (1) I/O要求的数量应当减至最小 (2)所有I/O应当缓存,以减少过多的通信次数 (3)对于辅存(如磁盘),应当选择和使用最简单的可接受 的存取方法 (4)辅存设备的I/O,应当是块状的终端和打印机的I/O, 应当考虑设备的特性,以提高质量和速度 (5)要记住,如果超高效的I/O不能被人们所理解,那么这样的I/O是没有价值的。
第七章 编码,7.1.3 保护性编程 对于认为编写程序可以做到完全没有错误的人来说,在软件中建立检查的意义不大相反,对于相信软件中总会有遗留错误的人来说,进行软件内部的错误检查则是一项重要策略,这种策略就是保护性编程(defensive programming) 保护性编程技术可分为主动和被动两种: 主动保护技术周期性的或在空闲时间对整个程序或数据库进行搜索,用以发现异常情况被动保护技术是在到达检查代码时,对程序的某些部分进行检查第七章 编码,某些反对保护性编程人员提出了许多逃避保护性编程的理由: (1)“我们的程序中即使有错误,也是很少的,所以不 需要保护性编程 (2)“要求采用他人的程序来检查和发现我的程序错 误, 这是不公正的 (3)“错误检查降低了计算机系统的速度,而且还要求 额外的内存 (4)“错误检查要占用很多编程时间 (5)“可以在我的程序中加入错误检查,不过一旦程序通过测试,就应把它撤去第七章 编码,对这些反对意见的回答,都直接或间接的与程序中预料的错误数及其潜在后果有关 如果相信错误无所不在,即有相当数量的错误在晚期发现是不可避免的,就必须采用保护性编程 如果这种保护在测试阶段对我们有帮助,则肯定要在程序操作使用时继续将其包括在内。
如果承认错误会出现这一事实,则比起因出现错误所带来的责难来说,增加一些工作量是有意义的第七章 编码,另一方面,基于运行时间、存储空间和编程费用等方面的反对意见,仅当保护性编程要求设计增加的资源量相当大时才有意义 事实上,只有在极少数情况下,保护性编程所要求增加的资源量才会相当大,以致不得不放弃考虑这种技术第七章 编码,Yourdon 曾提出过一个建设性意见,即在设计过程的早期就把保护性编程包括进去在设计过程中,大多数设计在填充可用存储空间时,其规模都增加的很快,如果企图在设计过程的结尾再引入保护性编程,则肯定已没有剩余空间而且在近乎完成的设计中,移动任何部分挤出空间的任何做法,都会招致强烈的反对但如果在一开始就把保护性编程包括进来。
