1、附加章 软件编码,主要任务:将详细设计确定的具体算法用程序设计语言描述出来,生成目标系统对应的源程序。 F.1 程序设计语言 F.2 编码风格及软件效率,F.1 程序设计语言,F.1.1 程序设计语言的分类1. 面向机器语言包括机器语言(Machine Language)和汇编语言(Assemble Language)两种。由于机器语言难以记忆和使用,通常不用机器语言编写程序。汇编语言是一种符号语言,它采用了一定的助记符来替代机器语言中的指令和数据。由于汇编语言生产效率低且可维护性差,所以目前软件开发中很少使用汇编语言。,2. 高级语言高级语言中的语句标识符与人类的自然语言(英文)较为接近,并
2、且采用了人们十分熟悉的十进制数据表示形式,利于学习和掌握。高级语言的抽象级别较高,不依赖于实现它的计算机硬件,且编码效率较高,往往一条高级语言的语句对应着若干条机器语言或汇编语言的指令。高级语言程序需要经过编译或解释之后,才能生成可在计算机上执行的机器语言程序。高级语言按其应用特点的不同,可分为通用语言和专用语言两大类。,1) 通用语言通用语言是指可用于解决各类问题、可广泛应用于各个领域的程序设计语言。从较早出现的基础语言Basic、FORTRAN等,到后来出现的结构化语言P、C等,再到现在被广泛使用的面向对象语言Visual C、Java等都属于通用语言的范畴。,2) 专用语言专用语言是为了
3、解决某类特殊领域的问题而专门设计的具有独特语法形式的程序设计语言。如专用于解决数组和向量计算问题的APL语言;专用于开发编译程序和操作系统程序的BLISS语言;专用于处理人工智能领域问题的LISP语言和PROLOG语言等。这些语言的共同特点是可高效地解决本领域的各种问题,但难以应用于其他领域。,F.1.2 程序设计语言的选择要为待开发项目选择合适的程序设计语言,应充分考虑到项目的各种需求,结合各种语言的特点,尽量选取实现效率高且易于理解和维护的语言。,1. 理论标准1) 理想的模块化机制、易于阅读和使用的控制结构及数据结构模块化、良好的控制结构和数据结构可以降低编码工作的难度,增强程序的可理解
4、性,提高程序的可测试性和可维护性,从而减少软件生存周期中的总成本,并缩短软件开发所需的时间。2) 完善、独立的编译机制完善的编译系统可尽可能多地发现程序中的错误,便于程序的调试和提高软件的可靠性,并且可以使生成的目标代码紧凑、高效;独立的编译机制便于程序的开发、调试和维护,可以降低软件开发和维护的成本。,2. 实用标准1) 系统用户的要求由于用户是软件的使用者,因此软件开发者应充分考虑用户对开发工具的要求。特别是当用户要负责软件的维护工作时,用户理所应当地会要求采用他们熟悉的语言进行编程。,2) 工程的规模语言系统的选择与工程的规模有直接的关系。例如,Foxpro与Oracal及Sybase都
5、是数据库处理系统,但Foxpro仅适用于解决小型数据库问题,而Oracal和Sybase则可用于解决大型数据库问题。特别是在如果工程的规模非常庞大,并且现有的语言都不能完全适用时,为了提高开发的效率和质量,就可以考虑为这个工程设计一种专用的程序设计语言。,3) 软件的运行环境软件在提交给用户后,将在用户的机器上运行,在选择语言时应充分考虑到用户运行软件的环境对语言的约束。此外,运行目标系统的环境中可以提供的编译程序往往也限制了可以选用的语言的范围。4) 可以得到的软件开发工具由于开发经费的制约,往往使开发人员无法任意选择、购买合适的正版开发系统软件。此外,若能选用具有支持该语言程序开发的软件工
6、具的程序设计语言,则将有利于目标系统的实现和验证。,5) 软件开发人员的知识软件开发人员采用自己熟悉的语言进行开发,可以充分运用积累的经验使开发的目标程序具有更高的质量和运行效率,并可以大大缩短编码阶段的时间。为了能够根据具体问题选择更合适的语言,软件开发人员应拓宽自己的知识面,多掌握几种程序设计语言。6) 软件的可移植性要求要使开发出的软件能适应于不同的软、硬件环境,应选择具有较好通用性的、标准化程度高的语言。,7) 软件的应用领域任何语言编译系统设计的出发点都有所不同,其对某一领域问题的处理能力也就存在较大差异,因此不存在真正适用于任何应用领域的语言,通用语言也不例外。如FORTRAN语言
7、最适用于工程科学计算,COBOL语言最适用于处理商业领域中的问题。所以,选择语言时一定要充分考虑到软件的应用领域。,在实际选择语言时,往往任何一种语言都无法同时满足项目的所有需求和各种选择的标准,这时就需要编程者对各种需求和标准进行权衡,分清主次,在所有可用的语言中选取最适合的一种进行编程。,F.2 编码风格及软件效率,F.2.1 编码风格编码风格是指在不影响程序正确性和效率的前提下,有效编排和合理组织程序的基本原则。一个具有良好编码风格的程序主要表现为可读性好、易测试、易维护。,1. 内部文档所谓内部文档,是指程序中的说明性注释信息,即应在必要的地方加上相应的注释。在修改程序时,不要忘记对相
8、应的注释也要进行修改。程序中的注释一般可按其用途分为两类:序言性注释和描述性注释。,1) 序言性注释序言性注释一般位于模块的首部,用于说明模块的相关信息。主要包括:对模块的功能、用途进行简要说明;对模块的界面进行描述,如调用语句的格式、各个参数的作用及需调用的下级模块的清单等;对模块的开发历史进行介绍,如模块编写者的资料、模块审核者的资料及建立、修改的时间等;对模块的输入数据或输出数据进行说明,如数据的格式、类型及含义等。,/* 函数名称:* DIBWidth()* 参数:* LPBYTE lpbi - 指向DIB对象的指针* 返回值:* DWORD - DIB位像宽度* 说明:* 获取DIB
9、位图的宽度 */DWORD CDIB:DIBWidth(LPBYTE lpDIB) ,2) 描述性注释描述性注释位于源程序模块内部,用于对某些难以理解的语句段的功能或某些重要的标识符的用途等进行说明。对语句的注释应紧跟在被说明语句之后书写。需要注意的是,并不是对所有程序中的语句都要进行注释,太多不必要的注释反而会影响人们对程序的阅读。,DWORD CDIB:DIBWidth(LPBYTE lpDIB) / 指向BITMAPINFO结构的指针(Win3.0)LPBITMAPINFOHEADER lpbmi;/ 指向BITMAPCOREINFO结构的指针LPBITMAPCOREHEADER lpb
10、mc;/ 获取指针lpbmi = (LPBITMAPINFOHEADER)lpDIB;lpbmc = (LPBITMAPCOREHEADER)lpDIB;/ 返回DIB中图像的宽度if (IS_WIN30_DIB(lpDIB)/ 对于Windows 3.0 DIB,返回lpbmi-biWidthreturn lpbmi-biWidth;else/ 对于其它格式的DIB,返回lpbmc-bcWidthreturn (DWORD)lpbmc-bcWidth; ,2. 标识符的命名及说明编写程序必然要使用标识符,特别是对于大型程序,使用的标识符可能成千上万。由于对程序中的标识符作用的正确理解是读懂程
11、序的前提。1) 标识符的命名为了便于阅读程序时对标识符作用进行正确的理解,标识符的命名应注意以下几个问题:,(1) 选用具有实际含义的标识符。如用于存放年龄的变量名最好取age,用于存放学生信息的数组名最好取student。若标识符由多个单词构成,则每个单词的第一个字母最好采用大写或单词间用下划线分隔,以利于对标识符含义的理解。(2) 标识符的名字不宜过长,通常不要超过八个字符。特别是对于那些对标识符长度有限制的语言编译系统来说,取过长的标识符名没有任何的意义。如在FORTRAN 77中,通常编译系统可以区分的标识符长度不超过六个字符。(3) 不同的标识符不要取过于相似的名字。如student
12、和students,很容易在使用或阅读时产生混淆。,2) 标识符的说明由于程序中通常需要使用大量不同类型的标识符,为了使说明部分阅读起来更加清晰,在对其进行类型说明时应注意以下几点:(1) 应按照某种顺序分别对各种类型的变量进行集中说明,如:先说明简单类型,再说明指针类型,再说明记录类型;对简单类型的变量进行说明时,可先说明整型,再说明实型,再说明字符型等等。(2) 在使用一个说明语句对同一类型的多个变量进行说明时,应按照变量名中的字母顺序(az)对其进行排列。,3. 语句的构造及书写语句是构成程序的基本单位,语句的构造方式和书写格式对程序的可读性具有非常重要的决定作用。1) 语句构造(1)
13、语句应简单直接,避免使用华而不实的程序设计技巧。如为了求出x、y两个数中的较大数,以下两个C语句均可实现: 方法一: max=(x+y+abs(xy)/2; 方法二: max=(xy)?x:y; 显然,方法二的可读性要比方法一好得多。,(2) 对复杂的表达式应加上必要的括号使表达更加清晰。如C语言中判断闰年的表达式若写为(year % 400 = = 0) | | (year % 4 = = 0 & year %100 != 0) 则比不加括号时看起来清晰得多。(3) 由于人的一般思维方式对逻辑非运算不太适应,因此在条件表达式中应尽量不使用否定的逻辑表示。如Pascal中的条件表达式 not(
14、x=5) and (x10)则更加直观和清晰。,(4) 为了不破坏结构化程序设计中结构的清晰性,在程序中应尽量不使用强制转移语句GOTO。 (5) 为了便于程序的理解,不要书写太复杂的条件,嵌套的重数也不宜过多。(6) 为了缩短程序的代码,在程序中应尽可能地使用编译系统提供的标准函数。对于程序中需要重复出现的代码段,应将其用独立模块(函数或过程)实现。,2) 书写格式为了便于人们对程序(特别是大型程序)的阅读,清晰整齐的书写格式是必不可少的。以下列出了书写程序时需注意的几个主要问题。(1) 虽然许多语言都允许在一行上书写多个语句,但为了程序看起来更加清楚,最好在一行上只书写一条语句。(2) 在
15、书写语句时,应通过采用递缩式格式使程序的层次更加清晰。(3) 在模块之间通过加入空行进行分隔。(4) 为了便于区分程序中的注释,最好在注释段的周围加上边框。,4. 输入/输出由于输入和输出是用户与程序之间传递信息的渠道,因此输入、输出的方式往往是用户衡量程序好坏的重要指标。为了使程序的输入、输出能便于用户的使用,在编写程序时应对输入和输出的设计格外注意。1) 输入在运行程序时,原始数据的输入工作通常要由用户自己完成。为了使用户能方便地进行数据的输入,应注意以下几点:,(1) 输入方式应力求简单,尽量避免给用户带来不必要的麻烦。如:尽可能采用简单的输入格式、尽可能减少用户的输入量。当程序中对输入
16、数据的格式需要有严格规定时,同一程序中的输入格式应尽可能保持一致。(2) 交互式输入数据时应有必要的提示信息,提示信息可包括:输入请求、数据的格式及可选范围等。如:“ 请输入待查职工的编号(5位数字 0000199999)”。,(3) 程序应对输入数据的合法性进行检查。若用户输入了非法的数据,则应向用户输出相应的提示信息,并允许用户重新输入正确的信息。例如,月份的正确值只能在112之间,若检测输入的月份超出了这个范围,就说明用户输入的数据非法,此时应输出出错提示并允许用户再次输入。(4) 若用户输入某些数据后可能会产生严重后果,应给用户输出必要的提示并在必要的时候要求用户确认。如:“ 清库会使
17、库中原有数据全部丢失,真的需要清库吗?(Y/N)”,(5) 当需要输入一批数据时,不要以记数方式控制数据的输入个数,而应以特殊标记作为数据输入结束的标志。例如,要输入一个班学生的成绩,若要求用户输入学生的总数并通过总数来控制输入数据的个数,无疑就会增加用户的麻烦;而若以特殊标记来控制数据的录入,如当用户输入1时结束输入,对于用户而言就方便多了。(6) 应根据系统的特点和用户的习惯设计出令用户满意的输入方式。,2) 输出用户需要通过程序的输出来获取加工的结果。为了使用户能够清楚地看到需要的结果,设计数据输出方式时应注意以下几点:(1) 输出数据的格式应清晰、美观。如对大量数据采用表格的形式输出,
18、可以使用户一目了然。(2) 输出数据时要加上必要的提示信息。例如,表格的输出一定要带有表头,用以说明表格中各项数据的含义。,F.2.2 软件效率软件的“高效率”,即用尽可能短的时间及尽可能少的存储空间实现程序要求的所有功能,是程序设计追求的主要目标之一。一定要遵循“先使程序正确,再使程序有效率;先使程序清晰,再使程序有效率”的准则。软件效率的高低应以能满足用户的需要为主要依据。在满足以上原则的基础上,可依照下述方法来提高程序的效率。,1. 用于提高运行速度的指导原则为了提高程序的运行速度,应尽量避免和简化复杂的运算,为此应遵循以下原则:(1) 编写程序之前,先对需要使用的算术表达式和逻辑表达式
19、进行化简。(2) 尽可能多地采用执行时间短的算术运算。(3) 尽量避免使用多维数组、指针和其他复杂的数据类型。(4) 尽量采用整型算术表达式和布尔表达式。,(5) 尽可能减少循环体,特别是内循环中语句的个数。(6) 尽量使同一表达式中的数据类型保持统一。需要特别强调的是,应尽量避免不同类型数据的比较运算,因为这样有可能导致程序运行出错。(7) 应当对所有的输入和输出安排适当的缓冲区,以减少频繁通信所带来的额外开销。,2. 用于优化存储空间使用的指导原则(1) 对于变动频繁的数据最好采用动态存储。(2) 可根据需要采用存储单元共享等节约空间的技术。(3) 选用具有紧缩存储器特性的编译程序,在必要时甚至可采用汇编语言。(4) 采用结构化程序设计,将程序划分为大小合适的模块。一个模块或若干个关系密切的模块的大小最好与操作系统页面的容量相匹配,以减少页面调度的次数,提高存储效率。,