1、 结构化程序设计方法 一个结构化程序 就是用高级语言表示的结构化算法。用三种基本结构组成的程序必然是结构化的程序,这种程序便于编写、便于阅读、便于修改和维护。结构化程序设计强调程序设计风格和程序结构的规范化,提倡清晰的结构。结构化程序设计方法的基本思路是:把一个复杂问题的求解过程 分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内。采取以下方法来保证得到结构化的程序:自顶向下;逐步细化;模块化设计;结构化编码。两种不同的方法:自顶向下,逐步细化;自下而上,逐步积累。用这种方法逐步分解,直到作者认为可以直接将各小段表达为文字语句为止。这种方法就叫 做“自顶向下,逐步细化”。自顶向下
2、,逐步细化方法的优点:考虑周全,结构清晰,层次分明,作者容易写,读者容易看。如果发现某一部分中有一段内容不妥,需要修改,只需找出该部分修改有关段落即可,与其它部分无关。我们提倡用这种方法设计程序。这就是用工程的方法设计程序。模块设计的方法:模块化设计的思想实际上是一种“分而治之”的思想,把一个大任务分为若干个子任务,每一个子任务就相对简单了。在拿到一个程序模块以后,根据程序模块的功能将它划分为若干个子模块,如果这些子模块的规模还嫌大,还再可以划分为更小的模块。这个过程采用自顶向下方法来实现。子模块一般不超过50行。划分子模块时应注意模块的独立性,即:使一个模块完成一项功能,耦合性愈少愈好。自上
3、而下的编程方法基本步骤自上而下的编程方法基本步骤(1)首先)首先对你所面临的问题进行精确描述对你所面临的问题进行精确描述,即你遇到的到底是,即你遇到的到底是什么问题;什么问题;(2)定义输入输出量,即分析我们的)定义输入输出量,即分析我们的目的是什么和现有的条件;目的是什么和现有的条件;(3)设计算法,逐层分解,逐步求精设计算法,逐层分解,逐步求精,这是做事情的一个过程,这是做事情的一个过程,大部分人做事出错就出在这个地方,懒得到逐层分解,逐步求大部分人做事出错就出在这个地方,懒得到逐层分解,逐步求精,总是妄想一步登天;精,总是妄想一步登天;(4)把算法转化为程序语言把算法转化为程序语言,这一
4、步是踏踏实实做的过程,没有,这一步是踏踏实实做的过程,没有这一步你什么也做不成。这一步你什么也做不成。(5)检测程序检测程序,我们做的东西是否正确,不正确检测错误。这一,我们做的东西是否正确,不正确检测错误。这一步是需要耐心的,不要怕错误,每一次检测都会让你提高。做步是需要耐心的,不要怕错误,每一次检测都会让你提高。做事时,不要因一些错误而畏缩不前。事时,不要因一些错误而畏缩不前。软件生命周期由软件生命周期由软件定义、软件开发和运行维护软件定义、软件开发和运行维护(也称为软件维护也称为软件维护)3个时期组成。个时期组成。软件定义时期软件定义时期通常进一步划分成通常进一步划分成3个阶段,即问题个
5、阶段,即问题定义、可行性研究和需求分析。定义、可行性研究和需求分析。开发时期开发时期通常由下述通常由下述4个阶段组成:总体设计,详个阶段组成:总体设计,详细设计,编码和单元测试,综合测试。其中前两个细设计,编码和单元测试,综合测试。其中前两个阶段又称为系统设计,后两个阶段又称为系统实现。阶段又称为系统设计,后两个阶段又称为系统实现。维护时期维护时期的主要任务是使软件持久地满足用户的需的主要任务是使软件持久地满足用户的需要。通常对维护时期不再进一步划分阶段,但是每要。通常对维护时期不再进一步划分阶段,但是每一次维护活动本质上都是一次压缩和简化了的定义一次维护活动本质上都是一次压缩和简化了的定义和
6、开发过程。和开发过程。1.3 软件生命周期软件生命周期软件生命周期每个阶段的基本任务。软件生命周期每个阶段的基本任务。1.问题定义问题定义2.可行性研究可行性研究3.需求分析需求分析4.总体设计总体设计5.详细设计详细设计6.编码和单元测试编码和单元测试7.综合测试综合测试8.软件维护软件维护时时 期期阶阶 段段关键问题关键问题问题问题定义定义问题定义问题定义问题是什么?问题是什么?可行性研究可行性研究有可行的解吗?有可行的解吗?需求分析需求分析 系统必须做什么?系统必须做什么?开发开发系统系统设计设计 总体设计总体设计 概括地说,应该如何解决这个问概括地说,应该如何解决这个问题?题?详细设计
7、详细设计 怎样具体地实现这个系统?怎样具体地实现这个系统?系统系统实现实现 编码和编码和单元测试单元测试 正确的程序模块正确的程序模块 综合测试综合测试 符合要求的软件符合要求的软件维护维护 维护维护 持久地满足用户需要的软件持久地满足用户需要的软件 第第2章章 可行性研究可行性研究2.1 可行性研究的任务可行性研究的任务2.2 可行性研究过程可行性研究过程2.3 成本成本/效益分析效益分析可行性研究的目的,就是用最小的代价在尽可能短可行性研究的目的,就是用最小的代价在尽可能短的时间内确定问题是否能够解决。的时间内确定问题是否能够解决。标准:系统完成后所能带来的效益是否大到值得投标准:系统完成
8、后所能带来的效益是否大到值得投资开发这个系统的程度。(资本回报)资开发这个系统的程度。(资本回报)2.1 可行性研究的任务可行性研究的任务单击此处编辑母版标题样式单击此处编辑母版标题样式 单击此处编辑母版副标题样式单击此处编辑母版副标题样式单击此处编辑母版标题样式单击此处编辑母版标题样式 单击此处编辑母版副标题样式单击此处编辑母版副标题样式 用户类型 外行型 熟练型 专家型 操作习惯 使用单位的计算机使用情况 使用单位的规章制度第第3章章 需求分析需求分析3.1 需求分析的任务需求分析的任务3.2 与用户沟通获取需求的方法与用户沟通获取需求的方法3.3 软件需求规格说明软件需求规格说明3.4
9、实体实体-联系图联系图3.5 验证软件需求验证软件需求通信录通信录问题定义:以文件的方式保存用户录入的通讯录数据 供用户查询和使用通讯录信息通信录通信录功能需求:记录项的基本属性:姓名、性别、住址、联系电话、电子邮件 等通信录通信录功能需求:录入:操作添加一条新的记录项 删除:删除一条已经存在的记录项 修改:改变记录项的一个或多个属性,并用新的记录项覆盖已经存在的记录项 查找:根据用户输入的属性值查找符合条件的记录项通信录通信录功能需求:通讯录数据以文件形式存储在磁盘上,根据实际需要定义文件的存储格式;在程序运行中需要对文件进行读取操作。程序中还要对输入数据的容错性进行检查,可以保证通讯录数据
10、的合法性。第第4章章 总体设计总体设计4.1 设计过程设计过程4.2 设计原理设计原理4.3 描绘软件结构的图形工具描绘软件结构的图形工具总体设计的基本目的就是回答总体设计的基本目的就是回答“概括地说,系统应概括地说,系统应该如何实现该如何实现?”这个问题,因此,总体设计又称为概这个问题,因此,总体设计又称为概要设计或初步设计。要设计或初步设计。总体设计阶段的另一项重要任务是设计软件的结构,总体设计阶段的另一项重要任务是设计软件的结构,也就是要确定系统中每个程序是由哪些模块组成的,也就是要确定系统中每个程序是由哪些模块组成的,以及这些模块相互间的关系。以及这些模块相互间的关系。典型的总体设计过
11、程包括下述典型的总体设计过程包括下述9个步骤:个步骤:1.设想供选择的方案设想供选择的方案2.选取合理的方案选取合理的方案3.推荐最佳方案推荐最佳方案4.功能分解功能分解5.设计软件结构设计软件结构6.设计数据库设计数据库7.制定测试计划制定测试计划8.书写文档书写文档(系统说明、用户手册、测试计划、详细的实现系统说明、用户手册、测试计划、详细的实现计划、数据库设计结果)计划、数据库设计结果)9.审查和复审审查和复审4.1 设计过程设计过程过程、函数、子程序和宏等,都可作为模块。过程、函数、子程序和宏等,都可作为模块。模块化就是把程序划分成独立命名且可独立访问的模块化就是把程序划分成独立命名且
12、可独立访问的模块,每个模块完成一个子功能,把这些模块集成模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户起来构成一个整体,可以完成指定的功能满足用户的需求。的需求。采用模块化原理可以使软件结构清晰,能够提高软采用模块化原理可以使软件结构清晰,能够提高软件的可靠性和可修改性,也有助于软件开发工程的件的可靠性和可修改性,也有助于软件开发工程的组织管理。组织管理。4.2 设计原理设计原理 4.2.1 模块化模块化信息隐藏原理指出:应该这样设计和确定模块,使信息隐藏原理指出:应该这样设计和确定模块,使得一个模块内包含的信息得一个模块内包含的信息(过程和数据过程和
13、数据)对于不需要对于不需要这些信息的模块来说,是不能访问的。这些信息的模块来说,是不能访问的。局部化有助于实现信息隐藏,隐藏的不是有关模块局部化有助于实现信息隐藏,隐藏的不是有关模块的一切信息,而是模块的实现细节。的一切信息,而是模块的实现细节。4.2.2 信息隐藏和局部化信息隐藏和局部化开发具有独立功能而且和其他模块之间没有过多的开发具有独立功能而且和其他模块之间没有过多的相互作用的模块,就可以做到模块独立。换句话说,相互作用的模块,就可以做到模块独立。换句话说,希望这样设计软件结构,使得每个模块完成一个相希望这样设计软件结构,使得每个模块完成一个相对独立的特定子功能,并且和其他模块之间的关
14、系对独立的特定子功能,并且和其他模块之间的关系很简单。很简单。模块的独立性很重要,有两条理由:第一,有效的模块的独立性很重要,有两条理由:第一,有效的模块化模块化(即具有独立的模块即具有独立的模块)的软件比较容易开发出的软件比较容易开发出来。第二,独立的模块比较容易测试和维护。总之,来。第二,独立的模块比较容易测试和维护。总之,模块独立是好设计的关键,而设计又是决定软件质模块独立是好设计的关键,而设计又是决定软件质量的关键环节。量的关键环节。4.2.3 模块独立模块独立通信录的模块结构图4.3 描绘软件结构的图形工具描绘软件结构的图形工具通信录通信录功能需求:录入:操作添加一条新的记录项 删除
15、:删除一条已经存在的记录项 修改:改变记录项的一个或多个属性,并用新的记录项覆盖已经存在的记录项 查找:根据用户输入的属性值查找符合条件的记录项通信录通信录功能需求:通讯录数据以文件形式存储在磁盘上,根据实际需要定义文件的存储格式;在程序运行中需要对文件进行读取操作。程序中还要对输入数据的容错性进行检查,可以保证通讯录数据的合法性。通信录的模块结构图输入输出终端输入输出模块管理模块文件操作模块存储文件用户输入系统输出文件写入文件读出4.3 描绘软件结构的图形工具描绘软件结构的图形工具4.3.1 层次图层次图 层次图用来描绘软件的层次结构。层次图用来描绘软件的层次结构。层次图中的一个矩形框代表一
16、个模块,方框间的连线表示调层次图中的一个矩形框代表一个模块,方框间的连线表示调用关系。用关系。第第5章章 详细设计详细设计5.1 结构程序设计结构程序设计5.2 人机界面设计人机界面设计5.3 过程设计的工具过程设计的工具结构程序设计的概念最早由结构程序设计的概念最早由E.W.Dijkstra提出。提出。1966年年Bohm和和Jacopini证明了,只用证明了,只用3种基本的控种基本的控制结构就能实现任何单入口单出口的程序。这制结构就能实现任何单入口单出口的程序。这3种种基本的控制结构是基本的控制结构是“顺序顺序”、“选择选择”和和“循循环环”。5.1 结构程序设计结构程序设计3种基本的控制
17、结构种基本的控制结构出于要有一种不允许违背结构程序设计精神的图形出于要有一种不允许违背结构程序设计精神的图形工具的考虑,工具的考虑,Nassi和和Shneiderman提出了盒图,又提出了盒图,又称为称为N-S图。它有下述特点:图。它有下述特点:(1)不可能任意转移控制。不可能任意转移控制。(2)很容易确定局部和全程数据的作用域。很容易确定局部和全程数据的作用域。(3)很容易表现嵌套关系,也可以表示模块的层次很容易表现嵌套关系,也可以表示模块的层次结构。结构。6.3.2 盒图盒图(N-S图图)图图6.4 盒图的基本符号盒图的基本符号PAD是问题分析图是问题分析图(problem analysi
18、s diagram)的英的英文缩写,自文缩写,自1973年由日本日立公司发明以后,已得年由日本日立公司发明以后,已得到一定程度的推广。它用二维树形结构的图来表示到一定程度的推广。它用二维树形结构的图来表示程序的控制流,将这种图翻译成程序代码比较容易。程序的控制流,将这种图翻译成程序代码比较容易。6.3.3 PAD图图图图6.5 PAD图的基本符号图的基本符号下面以行李托运费的算法为例说明判定表的组织方下面以行李托运费的算法为例说明判定表的组织方法。假设某航空公司规定,乘客可以免费托运重量法。假设某航空公司规定,乘客可以免费托运重量不超过不超过30kg的行李。当行李重量超过的行李。当行李重量超过
19、30kg时,对头时,对头等舱的国内乘客超重部分每公斤收费等舱的国内乘客超重部分每公斤收费4元,对其他元,对其他舱的国内乘客超重部分每公斤收费舱的国内乘客超重部分每公斤收费6元,对外国乘元,对外国乘客超重部分每公斤收费比国内乘客多一倍,对残疾客超重部分每公斤收费比国内乘客多一倍,对残疾乘客超重部分每公斤收费比正常乘客少一半。用判乘客超重部分每公斤收费比正常乘客少一半。用判定表可以清楚地表示与上述每种条件组合相对应的定表可以清楚地表示与上述每种条件组合相对应的计算行李费的算法,如表计算行李费的算法,如表6.1(见书(见书118页)所示。页)所示。用判定树表示计算行李费的算法用判定树表示计算行李费的
20、算法5.2.1 设计问题设计问题系统响应时间、用户帮助设施、出错信息处理和命系统响应时间、用户帮助设施、出错信息处理和命令交互。令交互。1.系统响应时间系统响应时间一般说来,系统响应时间指从用户完成某个控制动一般说来,系统响应时间指从用户完成某个控制动作作(例如,按回车键或点击鼠标例如,按回车键或点击鼠标),到软件给出预期,到软件给出预期的响应的响应(输出信息或做动作输出信息或做动作)之间的这段时间。之间的这段时间。2.用户帮助设施用户帮助设施设计帮助设施时要解决的问题设计帮助设施时要解决的问题(见下页)见下页)5.2 人机界面设计人机界面设计3.出错信息处理出错信息处理出错信息和警告信息,是
21、出现问题时交互式系统给出错信息和警告信息,是出现问题时交互式系统给出的出的“坏消息坏消息”。一般说来,交互式系统给出的出错信息或警告信息,一般说来,交互式系统给出的出错信息或警告信息,应该具有下述属性。应该具有下述属性。(1)信息应该用用户可以理解的术语描述问题。信息应该用用户可以理解的术语描述问题。(2)信息应该提供有助于从错误中恢复的建设性意信息应该提供有助于从错误中恢复的建设性意见。见。(3)信息应该指出错误可能导致哪些负面后果。信息应该指出错误可能导致哪些负面后果。(4)信息应该伴随着听觉上或视觉上的提示。信息应该伴随着听觉上或视觉上的提示。(5)信息不能带有指责色彩。信息不能带有指责
22、色彩。4.命令交互命令交互命令行曾经是用户和系统软件交互的最常用的方式,命令行曾经是用户和系统软件交互的最常用的方式,现在面向窗口的、点击和拾取方式的界面已经减少现在面向窗口的、点击和拾取方式的界面已经减少了用户对命令行的依赖。了用户对命令行的依赖。通讯录界面设计:通讯录界面设计:通信录通信录功能需求:记录项的基本属性:姓名、性别、住址、联系电话、电子邮件 等通讯录数据结构设计:struct myrecordunsigned int num;unsigned int group;char nameMAXLEN+1;char gender;date birthday;char addressMA
23、XLEN+1;char phoneMAXLEN+1;char emailMAXLEN+1;通讯录数据结构设计:struct mydateunsigned int year;unsigned int month;unsigned int day;typedef struct mydate date;通讯录数据结构设计:三个查询关键字:记录编号、组别和联系人姓名 union mysearch_entryunsigned int num;unsigned int group;char nameMAXLEN+1;typedef union mysearch_entry search_entry;通讯录
24、-函数设计函数原型函数功能函数处理描述void menulist(void)以文本方式显示程序主以文本方式显示程序主菜单,同时响应用户输菜单,同时响应用户输入入调用调用bioske(0),获取按,获取按键的值键的值void upbar(int y)向上滚动光标条向上滚动光标条通过改变字体颜色实现通过改变字体颜色实现光标条移动光标条移动void downbar(int y)向下滚动光标条向下滚动光标条通过改变字体颜色实现通过改变字体颜色实现光标条移动光标条移动void mydelay(void)等待用户响应等待用户响应调用调用getch()实现实现void format(void)结果输出时打印
25、输出的结果输出时打印输出的格式信息格式信息调用调用printf()实现实现void searchmenu(void)输出查询功能的子菜单输出查询功能的子菜单调用调用printf()实现实现void input_search(char ch)处理查询时用户的输入处理查询时用户的输入,将关键字读入,将关键字读入根据输入参数根据输入参数ch,执行,执行相应的操作相应的操作menu.c输入输出文件通讯录-函数设计函数原型函数功能函数处理描述int input_num(void)读入一个整型数值(记读入一个整型数值(记录编号),进行合法性录编号),进行合法性检查检查采用了递归的方法循环采用了递归的方法循
26、环读取数据读取数据int input_new(myrecord*p)进行数据修改时,读入进行数据修改时,读入一个新的记录项,并用一个新的记录项,并用它覆盖输入参数所指向它覆盖输入参数所指向的数据记录项。的数据记录项。参数:新记录项的指针参数:新记录项的指针返返 回回 值:返回是否进值:返回是否进行了修改的信息,已修行了修改的信息,已修改返回改返回 1,否则返回,否则返回0。myrecord*input_app(void)录入信息时处理键盘输录入信息时处理键盘输入,对输入进行合法性入,对输入进行合法性检查检查逐项录入通讯记录逐项录入通讯记录int date_legal(int year,int
27、month,int day)检查日期是否为合法检查日期是否为合法参数:年、月、日的信参数:年、月、日的信息息返返 回回 值:合法日期返值:合法日期返回回1,否则返回,否则返回0menu.c输入输出文件通讯录-函数设计file.c文件处理文件int file_app(myrecord*p)添加一条新的记录添加一条新的记录项项参参 数:要录入的记录项数:要录入的记录项的指针的指针返返 回回 值:操作结果(插入值:操作结果(插入成功返回成功返回1,失败返回,失败返回0)myrecord*read_record(int n)从文件中读出下标从文件中读出下标为为n的块(记录项)的块(记录项)参参 数:下
28、标值数:下标值返返 回回 值:读取结果的指针值:读取结果的指针int write_record(myrecord*p,int n)向文件中写入某一向文件中写入某一块(如果该块已经块(如果该块已经存在,将进行覆盖存在,将进行覆盖)参参 数:指向记录项的指数:指向记录项的指针和要写入的块位置针和要写入的块位置返返 回回 值:操作结果(插入值:操作结果(插入成功返回成功返回1,失败返回,失败返回0)int file_search(search_entry*s,int f)对存储文件进行遍对存储文件进行遍历,查找符合输入历,查找符合输入的记录项并输出的记录项并输出参参 数:指向查询项的指数:指向查询项
29、的指针和查询类型针和查询类型返返 回回 值:符合条件的记录值:符合条件的记录项总数(如果是项总数(如果是0则查找失则查找失败)败)int file_delete(int n)删除文件中某个记删除文件中某个记录块录块参参 数:下标值数:下标值返返 回回 值:操作结果(插入值:操作结果(插入成功返回成功返回1,失败返回,失败返回0)通讯录-函数设计control.c控制文件void append(void)执行数据录入操作执行数据录入操作调用调用input_app()完成数据录入,调完成数据录入,调用用file_app()完成数据保存。完成数据保存。void delet(void)执行数据记录项删
30、除操执行数据记录项删除操作作调用调用file_search查找要删除的记录,查找要删除的记录,然后调用然后调用file_delete()进行删除()进行删除void search(void)执行数据查找操作执行数据查找操作调用调用searchmenu()进入查找的菜单,进入查找的菜单,调用调用input_search(ch)获得要查找的获得要查找的内容,内容,file_search()进行查找()进行查找void change(void)执行数据记录项修改操执行数据记录项修改操作作调用调用input_num()输入待修改的记()输入待修改的记录,调用录,调用file_search()进行查找,
31、()进行查找,调用调用input_new()输入新的内容,()输入新的内容,调用调用write_record()进行更新()进行更新void list_all(void)列出当前所有联系人信列出当前所有联系人信息息打开文件,遍历所有记录并输出打开文件,遍历所有记录并输出void init(void)系统初试化操作,保证系统初试化操作,保证文件的正确性和合法性文件的正确性和合法性调用调用fopen()打开文件,初始化打开文件,初始化void quit(void)系统退出函数,写回文系统退出函数,写回文件以保证数据的一致性件以保证数据的一致性关闭文件,退出系统关闭文件,退出系统通讯录的某个模块的流
32、程图通讯录的某个模块的流程图第第6章章 实现实现6.1 编码编码6.2 软件测试基础软件测试基础6.3 白盒测试技术白盒测试技术6.4 黑盒测试技术黑盒测试技术6.5 调试调试6.6 软件可靠性软件可靠性通常把编码和测试统称为实现。通常把编码和测试统称为实现。所谓编码就是把软件设计结果翻译成用某种程序设所谓编码就是把软件设计结果翻译成用某种程序设计语言书写的程序。计语言书写的程序。测试的目的就是在软件投入生产性运行之前,尽可测试的目的就是在软件投入生产性运行之前,尽可能多地发现软件中的错误,它是对软件规格说明、能多地发现软件中的错误,它是对软件规格说明、设计和编码的最后复审。设计和编码的最后复
33、审。通常在编写出每个模块之后就对它做必要的测试通常在编写出每个模块之后就对它做必要的测试(称为单元测试称为单元测试),编码和单元测试属于软件生命周,编码和单元测试属于软件生命周期的同一个阶段。在这个阶段结束之后,对软件系期的同一个阶段。在这个阶段结束之后,对软件系统还应该进行各种综合测试。统还应该进行各种综合测试。通过测试发现错误之后还必须诊断并改正错误,这通过测试发现错误之后还必须诊断并改正错误,这就是调试的目的。就是调试的目的。适宜的程序设计语言能使根据设计去完成编码时困适宜的程序设计语言能使根据设计去完成编码时困难最少,可以减少需要的程序测试量,并且可以得难最少,可以减少需要的程序测试量
34、,并且可以得出更容易阅读和更容易维护的程序。出更容易阅读和更容易维护的程序。由于软件系统的绝大部分成本用在生命周期的测试由于软件系统的绝大部分成本用在生命周期的测试和维护阶段,所以容易测试和容易维护是极端重要和维护阶段,所以容易测试和容易维护是极端重要的。的。6.1 编码编码 6.1.1 选择程序设计语言选择程序设计语言总的说来,高级语言明显优于汇编语言,因此,除总的说来,高级语言明显优于汇编语言,因此,除了在很特殊的应用领域,或者大型系统中执行时间了在很特殊的应用领域,或者大型系统中执行时间非常关键的一小部分代码需要用汇编语言书写之外,非常关键的一小部分代码需要用汇编语言书写之外,其他程序应
35、该一律用高级语言书写。其他程序应该一律用高级语言书写。高级语言应该有理想的模块化机制,以及可读性好高级语言应该有理想的模块化机制,以及可读性好的控制结构和数据结构;语言特点应该使编译程序的控制结构和数据结构;语言特点应该使编译程序能够尽可能多地发现程序中的错误;能够尽可能多地发现程序中的错误;程序设计语言的实用标准:程序设计语言的实用标准:(1)可以得到的软件工具。可以得到的软件工具。(2)工程规模。工程规模。(3)程序员的知识。程序员的知识。(4)软件可移植性要求。软件可移植性要求。(5)软件的应用领域。软件的应用领域。源程序代码的逻辑简明清晰、易读易懂是好程序的源程序代码的逻辑简明清晰、易
36、读易懂是好程序的一个重要标准。一个重要标准。1.程序内部的文档程序内部的文档6.1.2 编码风格编码风格源程序代码的逻辑简明清晰、易读易懂是好程序的源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标准。一个重要标准。1.程序内部的文档程序内部的文档 包括包括恰当的标志符、适当的注解和程序的视觉组织恰当的标志符、适当的注解和程序的视觉组织。选取。选取含义鲜明的名字,有助于阅读者理解程序,如果用缩写,含义鲜明的名字,有助于阅读者理解程序,如果用缩写,那么缩写规则应该一致,并且应该给每个名字加注解。那么缩写规则应该一致,并且应该给每个名字加注解。正确的注解正确的注解非常有助于对程序的理解。通常在
37、每个模块开非常有助于对程序的理解。通常在每个模块开始处有一段序言性的注解,简要描述模块的功能、主要算始处有一段序言性的注解,简要描述模块的功能、主要算法、接口特点、重要数据以及开发简史。在模块内部,对法、接口特点、重要数据以及开发简史。在模块内部,对于重要语句或分支应该注解。对全局变量做注释。于重要语句或分支应该注解。对全局变量做注释。程序清单的布局程序清单的布局对于程序的可读性也有很大影响,应该利对于程序的可读性也有很大影响,应该利用阶梯形式使程序的结构清晰明显。函数间增加空行以示用阶梯形式使程序的结构清晰明显。函数间增加空行以示分隔分隔6.1.2 编码风格编码风格源程序代码的逻辑简明清晰、
38、易读易懂是好程序的源程序代码的逻辑简明清晰、易读易懂是好程序的一个重要标准。一个重要标准。全局变量全局变量应该应该“有限制地使用全局变量有限制地使用全局变量”。使。使用全局变量过多,会降低程序的清晰性;降低函用全局变量过多,会降低程序的清晰性;降低函数的通用性;滥用全局变量会造成程序的混乱数的通用性;滥用全局变量会造成程序的混乱函函 数数“工欲善其事,必先利其器工欲善其事,必先利其器”。我们在编。我们在编写大型程序时,要善于利用已有的函数,以减少写大型程序时,要善于利用已有的函数,以减少重复编写程序段的工作量重复编写程序段的工作量 6.1.2 编码风格编码风格/*/*函数原型:函数原型:myr
39、ecord*input_app(void);*/*参数:无参数:无 */*返返 回回 值:新增的记录项的地址值:新增的记录项的地址 */*函数功能:录入信息时处理键盘输入,对输入进行合法性检查。函数功能:录入信息时处理键盘输入,对输入进行合法性检查。*/*/myrecord*input_app(void)int t;char s100,c;system(cls);while(1)/*输入分组输入分组*/printf(group(1-10):);scanf(%d,&t);if(t10)printf(invalid input!n);continue;input.group=t;break;whi
40、le(1)/*输入姓名输入姓名*/printf(name:);scanf(%s,&s);if(strlen(s)MAXLEN)printf(too long!n);continue;strcpy(input.name,s);break;while(1)/*输入性别输入性别*/printf(gender(F/M):);scanf(%s,&s);if(strlen(s)1)printf(invalid input!n);continue;c=s0;if(c!=F&c!=f&c!=M&c!=m)printf(invalid input!n);continue;input.gender=toupper
41、(c);break;while(1)/*输入出生日期输入出生日期*/printf(brithday-year(1900-2007):);scanf(%d,&t);if(t2007)printf(invalid input!n);continue;input.birthday.year=t;break;while(1)printf(brithday-month(1-12):);scanf(%d,&t);if(t12)printf(invalid input!n);continue;input.birthday.month=t;break;while(1)printf(brithday-day(1
42、-31):);scanf(%d,&t);if(!date_legal(input.birthday.year,input.birthday.month,t)printf(invalid input!n);continue;input.birthday.day=t;break;while(1)/*输入地址输入地址*/printf(address:);scanf(%s,&s);if(strlen(s)MAXLEN)printf(too long!n);continue;strcpy(input.address,s);break;while(1)/*输入电话号码输入电话号码*/printf(phon
43、e:);scanf(%s,&s);if(strlen(s)MAXLEN)printf(too long!n);continue;strcpy(input.phone,s);break;while(1)/*输入输入email*/printf(email:);scanf(%s,&s);if(strlen(s)MAXLEN)printf(too long!n);continue;strcpy(input.email,s);break;return&input;6.1.2 编码风格编码风格软件测试的目的与软件工程所有其他阶段的目的都软件测试的目的与软件工程所有其他阶段的目的都相反。在测试阶段测试人员努
44、力设计出一系列测试相反。在测试阶段测试人员努力设计出一系列测试方案,目的是为了竭力证明程序中有错误不能按照方案,目的是为了竭力证明程序中有错误不能按照预定要求正确工作。预定要求正确工作。6.2 软件测试基础软件测试基础测试任何产品都有两种方法:测试任何产品都有两种方法:如果已经知道了产如果已经知道了产品应该具有的功能,可以通过测试来检验是否每个品应该具有的功能,可以通过测试来检验是否每个功能都能正常使用;如果知道产品的内部工作过程,功能都能正常使用;如果知道产品的内部工作过程,可以通过测试来检验产品内部动作是否按照规格说可以通过测试来检验产品内部动作是否按照规格说明书的规定正常进行。前一种方法
45、称为明书的规定正常进行。前一种方法称为黑盒测试黑盒测试,后一种方法称为后一种方法称为白盒测试白盒测试。6.2.1 测试方法测试方法对于软件测试而言,黑盒测试法把程序看作一个黑对于软件测试而言,黑盒测试法把程序看作一个黑盒子,完全不考虑程序的内部结构和处理过程。黑盒子,完全不考虑程序的内部结构和处理过程。黑盒测试又称为功能测试。盒测试又称为功能测试。白盒测试法与黑盒测试法相反,它的前提是可以把白盒测试法与黑盒测试法相反,它的前提是可以把程序看成装在一个透明的白盒子里,测试者完全知程序看成装在一个透明的白盒子里,测试者完全知道程序的结构和处理算法。白盒测试又称为结构测道程序的结构和处理算法。白盒测
46、试又称为结构测试。试。如果一个软件是为许多客户开发的,让每个客户都如果一个软件是为许多客户开发的,让每个客户都进行正式的验收测试是不现实的。在这种情况下,进行正式的验收测试是不现实的。在这种情况下,绝大多数软件开发商都使用被称为绝大多数软件开发商都使用被称为Alpha测试和测试和Beta测试的过程,来发现那些看起来只有最终用户测试的过程,来发现那些看起来只有最终用户才能发现的错误。才能发现的错误。6.2.2 Alpha和和Beta测试测试Alpha测试由用户在开发者的场所进行,并且在开测试由用户在开发者的场所进行,并且在开发者对用户的发者对用户的“指导指导”下进行测试。开发者负责记下进行测试。
47、开发者负责记录发现的错误和使用中遇到的问题。总之,录发现的错误和使用中遇到的问题。总之,Alpha测试是在受控的环境中进行的。测试是在受控的环境中进行的。Beta测试由软件的最终用户们在一个或多个客户场测试由软件的最终用户们在一个或多个客户场所进行。与所进行。与Alpha测试不同,开发者通常不在测试不同,开发者通常不在Beta测试的现场,因此,测试的现场,因此,Beta测试是软件在开发者不能测试是软件在开发者不能控制的环境中的控制的环境中的“真实真实”应用。应用。所谓测试方案包括具体的测试目的、应该输入的测所谓测试方案包括具体的测试目的、应该输入的测试数据和预期的结果。通常又把测试数据和预期的
48、试数据和预期的结果。通常又把测试数据和预期的输出结果称为测试用例。其中最困难的问题是设计输出结果称为测试用例。其中最困难的问题是设计测试用的输入数据。测试用的输入数据。因为不可能进行穷尽的测试,选用少量因为不可能进行穷尽的测试,选用少量“最有效的最有效的”测试数据,做到尽可能完备的测试很重要。测试数据,做到尽可能完备的测试很重要。设计测试方案的基本目标是,确定一组最可能发现设计测试方案的基本目标是,确定一组最可能发现某个错误或某类错误的测试数据。某个错误或某类错误的测试数据。6.3 白盒测试技术白盒测试技术有选择地执行程序中某些最有代表性的通路是对穷有选择地执行程序中某些最有代表性的通路是对穷
49、尽测试的惟一可行的替代办法。尽测试的惟一可行的替代办法。6.3.1 逻辑覆盖逻辑覆盖1.语句覆盖语句覆盖为了暴露程序中的错误,至少每个语句应该执行一为了暴露程序中的错误,至少每个语句应该执行一次。次。A=2,B=0,X=42.判定覆盖判定覆盖判定覆盖又叫分支覆盖,它的含义是,不仅每个语判定覆盖又叫分支覆盖,它的含义是,不仅每个语句必须至少执行一次,而且每个判定的每种可能的句必须至少执行一次,而且每个判定的每种可能的结果都应该至少执行一次,也就是每个判定的每个结果都应该至少执行一次,也就是每个判定的每个分支都至少执行一次。分支都至少执行一次。A=3,B=0,X=3;A=2,B=1,X=13.条件
50、覆盖条件覆盖条件覆盖的含义是,不仅每个语句至少执行一次,条件覆盖的含义是,不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取到各种可能的而且使判定表达式中的每个条件都取到各种可能的结果。结果。A=2,B=0,X=4;A=1,B=1,X=1A=2,B=0,X=4语句覆盖语句覆盖A=3,B=0,X=3;A=2,B=1,X=1判定覆盖判定覆盖1.语句覆盖语句覆盖为了暴露程序中的错误,至少每个语句应该执行一为了暴露程序中的错误,至少每个语句应该执行一次。次。A=2,B=0,X=42.判定覆盖判定覆盖判定覆盖又叫分支覆盖,它的含义是,不仅每个语判定覆盖又叫分支覆盖,它的含义是,不仅每个语句必须至
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。