主元素C程序分析时间复杂度,包括线性情况真的很好,真的很好
谭浩强教授我国著名计算机教育专家。1934年生1958年清华大学毕业。学生时代曾担任清华大学学生会主席、北京市人民代表他是我国计算机普及和高校计算机基础教育开拓者之一,现任全国高等院校计算机基础教育研究会会长、教育部全國计算机应用技术***考试委员会主任委员 谭浩强教授创造了3个世界纪录:(1)20年来他(及和他人合作)共编著出版了130本计算机著作,此外主编了250多本计算机书籍是出版科技著作数量最多的人。(2)他编著和主编的书发行量超过4500万册是读者最多的科技作家。我国平均烸30人、知识分子每, All Rights
第 一 章 概述 1-1 简述计算机程序设计语言的发展历程 解: 迄今为止计算机程序设计语言的发展经历了机器语言、汇编语言、高级语言等阶段,C++语言是一种面向对象的编程语言也属于高级语言。 1-2 面向对象的编程语言有哪些特点 解: 面向对象的编程语言与以往各种编程语言有根本的不同,它设计的出发点就是为了能更直接的描述客观世界中存在的事物以及它们之间的关系面向对象的编程语訁将客观事物看作具有属性和行为的对象,通过抽象找出同一类对象的共同属性(静态特征)和行为(动态特征)形成类。通过类的继承与多态可以很方便地实现代码重用大大缩短了软件开发周期,并使得软件风格统一因此,面向对象的编程语言使程序能够比较直接哋反问题域的本来面目软件开发人员能够利用人类认识事物所采用的一般思维方法来进行软件开发。C++语言是目前应用最广的面向对象的編程语言 1-3 什么是结构化程序设计方法?这种方法有哪些优点和缺点 解: 结构化程序设计的思路是:自顶向下、逐步求精;其程序结构昰按功能划分为若干个基本模块;各模块之间的关系尽可能简单,在功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结構组成;其模块化实现的具体方法是使用子程序结构化程序设计由于采用了模块***与功能抽象,自顶向下、分而治之的方法从而有效地将一个较复杂的程序系统设计任务***成许多易于控制和处理的子任务,便于开发和维护 虽然结构化程序设计方法具有很多的优点,但它仍是一种面向过程的程序设计方法它把数据和处理数据的过程分离为相互独立的实体。当数据结构改变时所有相关的处理过程嘟要进行相应的修改,每一种相对于老问题的新方法都要带来额外的开销程序的可重用性差。 由于图形用户界面的应用程序运行由顺序运行演变为事件驱动,使得软件使用起来越来越方便但开发起来却越来越困难,对这种软件的功能很难用过程来描述和实现使用面姠过程的方法来开发和维护都将非常困难。 1-4 什么是对象什么是面向对象方法?这种方法有哪些特点 解: 从一般意义上讲,对象是现实卋界中一个实际存在的事物它可以是有形的,也可以是无形的对象是构成世界的一个独立单位,它具有自己的静态特征和动态特征媔向对象方法中的对象,是系统中用来描述客观事物的一个实体它是用来构成系统的一个基本单位,由一组属性和一组行为构成 面向對象的方法将数据及对数据的操作方法放在一起,作为一个相互依存、不可分离的整体--对象对同类型对象抽象出其共性,形成类类中嘚大多数数据,只能用本类的方法进行处理类通过一个简单的外部接口,与外界发生关系对象与对象之间通过消息进行通讯。这样程序模块间的关系更为简单,程序模块的独立性、数据的安全性就有了良好的保障通过实现继承与多态性,还可以大大提高程序的可重鼡性使得软件的开发和维护都更为方便。 面向对象方法所强调的基本原则就是直接面对客观存在的事物来进行软件开发,将人们在日瑺生活中习惯的思维方式和表达方式应用在软件开发中使软件开发从过分专业化的方法、规则和技巧中回到客观世界,回到人们通常的思维 1-5 什么叫做封装? 解: 封装是面向对象方法的一个重要原则就是把对象的属性和服务结合成一个独立的系统单位,并尽可能隐蔽对潒的内部细节 1-6 面向对象的软件工程包括哪些主要内容? 解: 面向对象的软件工程是面向对象方法在软件工程领域的全面应用它包括面姠对象的分析(OOA)、面向对象的设计(OOD)、面向对象的编程(OOP)、面向对象的测试(OOT)和面向对象的软件维护(OOSM)等主要内容。 1-7 简述计算機内部的信息可分为几类 解: 计算机内部的信息可以分成控制信息和数据信息二大类;控制信息可分为指令和控制字两类;数据信息可汾为数值信息和非数值信息两类。 1-8 什么叫二进制使用二进制有何优点和缺点? 解: 二进制是基数为2每位的权是以2 为底的幂的进制,遵循逢二进一原则基本符号为0和1。采用二进制码表示信息有如下几个优点:/hadley。在用法方面ggplot2也开创了一种奇特而绝妙的语法,那就是加號:一幅图形从背后的设计来说是若干图形语法的叠加,从外在的代码来看也是若干R对象的相加。这一点精妙尽管只是ggplot2系统的很小一蔀分但我个人认为没有任何程序语言可比拟,它对作为泛型函数的加号的扩展只能用两个字形容:绝了, 至2013年2月26日,ggplot2的邮件列表(/group/ggplot2 )订閱成员已达3394人邮件总数为15185封,已经成为一个丰富、活跃的用户社区未来ggplot2的发展也将越来越依赖于用户的贡献,这也是很多开源软件最終的走向, 关于版本更新, 用来更方便地调整修改ggplot2图形中的图元,ggplotGrob()会返回一个gtable类这个对象可以利用gtable包中提供的函数和接口进行操作。, 所有“模板”类型的图形函数比如plotmatrix(),ggorder()等等已被标记为“不推荐使用”(deprecated),将在未来版本中取消, 在本书出版之际,ggplot2更新到了版本/cosname/ggplot2-translation 读者鈳以在这里得到最新的勘误和书中的代码,也可以随时提出任何问题, 谢益辉,
构件的重用性不如在B/S要求下的构件的重用性好. B/S 对的多重結构,要求构件相对独立的功能. 能够相对较好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子 5.系统维护不同 C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 可能是再做一个全新的系统 B/S 构件组成,方面构件个别的更换,实现系统的无缝升級. 系统维护开销减到最小.用户从网上自己下载***就可以实现升级. 6.处理问题不同 C/S 程序可以处理用户面固定, 并且在相同区域, 安全要求高需求, 与操作系统相关. 应该都是相同的系统 B/S 建立在广域网上, 面向不同的用户群, 分散地域, 这是C/S无法作到的. 与操作系统平台关系最小. 7.用户接口不同 C/S 多是建立的Window平台上,表现方法有限,对程序员普遍要求较高 B/S 建立在浏览器上, 有更加丰富和生动的表现方式与用户交流. 並且大部分难度减低,减低开发成本. 8.信息流不同 C/S 程序一般是典型的中央集权的机械式处理, 交互性相对低 B/S 信息流向可变化, B-B B-C B-G等信息、流向的变化, 更像交易中心。 118、LINUX下线程GDI类的解释。 LINUX实现的就是基于核心轻量级进程的"一对一"线程模型一个线程实体对应一个核心轻量级进程,而线程之间的管理在核外函数库中实现 GDI类为图像设备编程接口类库。 119、STRUTS的应用(如STRUTS架构) Struts 是采用Java Servlet/JavaServer servlet中提供关联支持帮助开发员創建交互式表单应用。三.提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息 120、Jdo是什么? JDO 是Java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化APIJDO提供了透明的对象存储,因此对开发人员来说存储数据对象完全不需要額外的代码(如JDBC API的使用)。这些繁琐的例行工作已经转移到JDO产品提供商身上使开发人员解脱出来,从而集中时间和精力在业务逻辑上叧外,JDO很灵活因为它可以在任何数据底层上运行。JDBC只是面向关系数据库(RDBMS)JDO更通用提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMS)等等使得应用可移植性更强。 121、内部类可以引用他包含类的成员吗有没有什么限制? 一个内部类对象可鉯访问创建它的外部类对象的内容 122、WEB SERVICE名词解释JSWDL开发包的介绍。JAXP、JAXM的解释SOAP、UDDI,WSDL解释。 Web ServiceWeb Service是基于网络的、分布式的模块化组件它执行特定嘚任务,遵守具体的技术规范这些规范使得Web WSDL是一种 XML 格式,用于将网络服务描述为一组端点这些端点对包含面向文档信息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述然后将其绑定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点(服务) SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议 UDDI 的目的是为电子商务建立标准;UDDI是┅套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册以使别的企业能够发现嘚访问协议的实现标准。 java中的保留字现在没有在java中使用。 125、启动一个线程是用run()还是start()? 启动一个线程是调用start()方法使线程所代表的虚拟处悝机处于可运行状态,这意味着它可以由JVM调度并执行这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程
攀枝花学院本科学生课程设计任务书 题 目 二叉排序树与平衡二叉树的实现 1、课程设计的目的 使学生进一步理解和掌握课堂上所学各种基夲抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法 使学生掌握软件设计的基本内容和设计方法,并培养学生进行规范化软件设计的能力 3) 使学生掌握使用各种计算机资料和有关参考资料,提高学生进行程序设计的基本能力 2、课程设計的内容和要求(包括原始数据、技术要求、工作要求等) (1) (1)以回车('\n')为输入结束标志,输入数列L,生成一棵二叉排序树T; (2)对二叉排序树T作中序遍历输出结果; (3)计算二叉排序树T查找成功的平均查找长度,输出结果; (4)输入元素x,查找二叉排序树T,若存在含x的结点,则删该结点,并作中序遍历(執行操作2);否则输出信息“无x”; (5)用数列L,生成平衡的二叉排序树BT:当插入新元素之后发现当前的二叉排序树BT不是平衡的二叉排序树,则竝即将它转换成新的平衡的二叉排序树BT; (6)计算平衡的二叉排序树BT的平均查找长度输出结果。 3、主要参考文献 [1]刘大有等《数据结构》(C语言版),高等教育出版社 [2]严蔚敏等《数据结构》(C语言版),清华大学出版社 [3]William FordWilliam Topp,《Data Structure with C++》清华大学出版社 [4]苏仕华等數据结构课程设计,机械工业出版社 4、课程设计工作进度计划 第1天 完成方案设计与程序框图 第2、3天 编写程序代码 第4天 程序调试分析和结果 苐5天 课程设计报告和总结 指导教师(签字) 日期 年 月 日 教研室意见: 年 月 日 学生(签字): 接受任务时间: 年 月 日 注:任务书由指导教师填写 课程设计(论文)指导教师成绩评定表 题目名称 二叉排序树与平衡二叉树的实现 评分项目 分值 得分 评价内涵 工作 表现 20% 01 学习态度 6 遵守各项纪律,工作刻苦努力具有良好的科学工作态度。 02 科学实践、调研 7 通过实验、试验、查阅文献、深入生产实践等渠道获取与课程设计囿关的材料 03 课题工作量 7 按期圆满完成规定的任务,工作量饱满 能力 水平 35% 04 综合运用知识的能力 10 能运用所学知识和技能去发现与解决实际問题,能正确处理实验数据能对课题进行理论分析,得出有价值的结论 05 应用文献的能力 5 能独立查阅相关文献和从事其他调研;能提出並较好地论述课题的实施方案;有收集、加工各种信息及获取新知识的能力。 06 设计(实验)能力方案的设计能力 5 能正确设计实验方案,獨立进行装置***、调试、操作等实验工作数据正确、可靠;研究思路清晰、完整。 07 计算及计算机应用能力 5 具有较强的数据运算与处理能力;能运用计算机进行资料搜集、加工、处理和辅助设计等 08 对计算或实验结果的分析能力(综合分析能力、技术经济分析能力) 10 具有較强的数据收集、分析、处理、综合的能力。 成果 质量 45% 09 插图(或图纸)质量、篇幅、设计(论文)规范化程度 5 符合本专业相关规范或规定偠求;规范化符合本文件第五条要求 10 设计说明书(论文)质量 30 综述简练完整,有见解;立论正确论述充分,结论严谨合理;实验正确分析处理科学。 11 创新 10 对前人工作有改进或突破或有独特见解。 成绩 指导教师评语 指导教师签名: 年 月 日 摘要及关键字 本程序中的數据采用“树形结构”作为其数据结构具体采用的是“二叉排序树”。 二叉排序树(又称二叉查找树):(1)若左子树不空则左子树上所囿节点的值均小于它的根结点的值;(2)若右子树不空,则右子树上所有节点均大于它的根结点的值;(3)它的左右子树分别为二叉排序树 二叉岼衡树:若不是空树,则(1)左右子树都是平衡二叉树;(2)左右子树的深度之差的绝对值不超过1 本次实验是利用二叉排序树和平衡二叉树达到鉯下目的:(1)以回车('\n')为输入结束标志,输入数列L,生成一棵二叉排序树T;(2)对二叉排序树T作中序遍历输出结果;(3)计算二叉排序树T查找成功的平均查找长度,输出结果; (4)输入元素x,查找二叉排序树T,若存在含x的结点,则删该结点,并作中序遍历(执行操作2);否则输出信息“无x”;(5)用数列L,生成岼衡的二叉排序树BT:当插入新元素之后发现当前的二叉排序树BT不是平衡的二叉排序树,则立即将它转换成新的平衡的二叉排序树BT; (6)计算平衡的二叉排序树BT的平均查找长度输出结果。 关键字:数列L,结点,二叉排序树,平衡二叉树 目录 摘要…………………………………………………………………………… 3 1 绪论………………………………………………………………………… 5 1.1 课程设计的目的…………………………………………………………… 5 1.2 相关知识的阐述…………………………………………………………… 5 1.2.1一位数组的存储结构…………………………………………………… 5 1.2.2建立二叉排序树……………………………………………………… 5 1.2.3中序遍历二叉树………………………………………………………… 5 1.2.4平均查找长度…………………………………………………………… 6 1.2.5平均二叉树(***L树)…………………………………………………… 6 1.2.6平衡因子………………………………………………………………… 7 1.2.7平衡二叉树的调整方法…………………………………………………… 7 2 方案设计……………………………………………………………… 8 2.1 模块功能………………………………………………………………………8 3 算法设计…………………………………………………………………… 8 3.1 算法流程图…………………………………………………………………… 8 4 详细设计……………………………………………………………… 10 4.1 主程序………………………………………………………………… 10 4.2 定義二叉树结构……………………………………………………………… 11 4.3 建立二叉树…………………………………………………………………… 11 4.3.1二叉排序树的查找…………………………………………………………11 4.3.2二叉排序树的插入…………………………………………………………11 4.4 中序遍历…………………………………………………………………12 4.5 平均查找长度…………………………………………………………………12 4.6 删除节点…………………………………………………………………12 4.7 判断平衡二叉树……………………………………………………………… 13 5 调试分析………………………………………………………………………… 14 5.1 时间复杂度的分析………………………………………………………………14 5.2 运行结果………………………………………………………………… 14 5.3 结果分析………………………………………………………………… 15 6 课程设计总结…………………………………………………………………… 16 参考文献………………………………………………………………………… 17 1 绪论 1.1 课程设计的目的 (1)使学生进一步理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法鉯及它们在程序中的使用方法。 (2)使学生掌握软件设计的基本内容和设计方法并培养学生进行规范化软件设计的能力。 (3)使学生掌握使用各種计算机资料和有关参考资料提高学生进行程序设计的基本能力。 1.2 相关知识的阐述 1.2.1 一维数组的存储结构 建立二插排序树首先用一个一維数组记录下读入的数据,然后再用边查找边插入的方式将数据一一对应放在完全二叉树相应的位置为空的树结点用“0” 补齐。 1.2.2 建立二叉排序树 二叉排序树是一种动态树表其特点是:树的结构通常不是一次生成的,而是在查找过程中当树中不存在关键字等于给定值的節点时再进行插入。新插入的结点一定是一个新添加的叶子节点并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子結点。 插入算法: 首先执行查找算法找出被插结点的父亲结点; 判断被插结点是其父亲结点的左、右儿子。将被插结点作为叶子结点插叺; 若二叉树为空则首先单独生成根结点。 注意:新插入的结点总是叶子结点 1.2.3 中序遍历二叉树 中序遍历二叉树算法的框架是: 若二叉樹为空,则空操作; 否则(1)中序遍历左子树(L); (2)访问根结点(V); (3)中序遍历右子树(R) 中序遍历二叉树也采用递归函数的方式,先访问咗子树2i,然后访问根结点i,最后访问右子树2i+1.先向左走到底再层层返回直至所有的结点都被访问完毕。 1.2.4 平均查找长度 计算二叉排序树的平均查找长度时采用类似中序遍历的递归方式,用s记录总查找长度j记录每个结点的查找长度,s置初值为0采用累加的方式最终得到总查找长喥s。平均查找长度就等于s/i(i为树中结点的总个数) 假设在含有n(n>=1)个关键字的序列中,i个关键字小于第一个关键字n-i-1个关键字大于第一个关键字,则由此构造而得的二叉排序树在n个记录的查找概率相等的情况下其平均查找长度为: 其中P(i)为含有i个结点的二叉排序树的平均查找长度,则P(i)+1为查找左子树中每个关键字时所用比较次数的平均值P(n-i-1)+1为查找右子树中每个关键字时所用比较次数的平均值。又假设表中n个关键芓的排列是“随机”的即任一个关键字在序列中将是第1个,或第2个…,或第n个的概率相同则可对上式从i等于0至n-1取平均值。最终会推導出: 另外含有n个结点的二叉排序树其判定树不是惟一的。对于含有同样一组结点的表由于结点插入的先后次序不同,所构成的二叉排序树的形态和深度也可能不同 而在二叉排序树上进行查找时的平均查找长度和二叉树的形态有关: ①在最坏情况下,二叉排序树昰通过把一个有序表的n个结点依次插入而生成的此时所得的二叉排序树蜕化为棵深度为n的单支树,它的平均查找长度和单链表上的顺序查找相同亦是(n+1)/2。 ②在最好情况下二叉排序树在生成的过程中,树的形态比较匀称最终得到的是一棵形态与二分查找的判定树相姒的二叉排序树,此时它的平均查找长度大约是lgn ③插入、删除和查找算法的时间复杂度均为O(lgn)。 1.2.5 平衡二叉树( ***L树 ) ①平衡二叉树(Balanced Binary Tree)是指树中任一结点的左右子树的高度大致相同 ②任一结点的左右子树的高度均相同(如满二叉树),则二叉树是完全平衡的通常,只要二叉树的高度为O(1gn)就可看作是平衡的。 ③平衡的二叉排序树指满足BST性质的平衡二叉树 ④***L树中任一结点的左、右子树的高度之差的绝对值不超過1。在最坏情况下n个结点的***L树的高度约为1.44lgn。而完全平衡的二叉树高度约为lgn***L树是最接近最优的。 1.2.6 平衡因子 二叉树上任一结点的左子树深喥减去右子树的深度称为该结点的平衡因子易知平衡二叉树中所有结点的因子只可能为0,-1和1 平衡二叉排序树的在平衡因子绝对值等于2時开始调整到绝对值为1或0,在平衡因子绝对值为2时二叉排序树会出现四种不同的情况的树形,因此这时需要分别单独讨论来降低平衡因孓 1.2.7 平衡二叉树的调整方法 平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时首先检查是否因插入新结点而破坏了②叉排序树的平衡性,若是则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下调整最小不平衡子树中各结点之间的链接關系,进行相应的旋转使之成为新的平衡子树。具体步骤如下: (1)每当插入一个新结点从该结点开始向上计算各结点的平衡因子,即计算该结点的祖先结点的平衡因子若该结点的祖先结点的平衡因子的绝对值均不超过1,则平衡二叉树没有失去平衡继续插入结点; (2)若插叺结点的某祖先结点的平衡因子的绝对值大于1,则找出其中最小不平衡子树的根结点; (3)判断新插入的结点与最小不平衡子树的根结点的关系确定是哪种类型的调整; (4)如果是LL型或RR型,只需应用扁担原理旋转一次在旋转过程中,如果出现冲突应用旋转优先原则调整冲突;洳果是LR型或LR型,则需应用扁担原理旋转两次第一次最小不平衡子树的根结点先不动,调整插入结点所在子树第二次再调整最小不平衡孓树,在旋转过程中如果出现冲突,应用旋转优先原则调整冲突; (5)计算调整后的平衡二叉树中各结点的平衡因子检验是否因为旋转而破坏其他结点的平衡因子,以及调整后的平衡二叉树中是否存在平衡因子大于1的结点 2 方案设计 2.1 模块功能 1.建立二叉树:要求以回车('\n')为输入結束标志,输入数列L,生成一棵二叉排序树T 2.中序遍历并输出结果:要求将第一步建立的二叉树进行中序遍历,并将结果输出 3.平均查找长喥并输出:要求计算二叉排序树T查找成功的平均查找长度,输出结果。 4.删除节点:要求输入元素x,查找二叉排序树T,若存在含x的结点,则删该结点,並作中序遍历(执行操作2);否则输出信息“无x” 5.生成平衡二叉树:要求用数列L,生成平衡的二叉排序树BT:当插入新元素之后发现当前的二叉排序树BT不是平衡的二叉排序树,则立即将它转换成新的平衡的二叉排序树BT; /*在根指针t所指二叉排序树中递归地查找其关键字等于key的数据え素若查找成功,则指针p指向该数据元素节点并返回(1),否则指针p指向查找路径上访问的最后一个节点并返回(0)指针f指向t的双親,其初始调用值为NULL*/ if(!t) {*p=f;return (0);} /*查找不成功*/ else if(key==t->data) {*p=t;return 在程序调试过程当中编译时并没有报错,但是运行时总是出错在查阅资料和同学的帮助下,发现程序未对数组初始化添加数组初始化代码: s=(node)malloc(sizeof(BSTnode)) 输入一组数列,以结0结束: 图5.2.2运行界面一 中序遍历: 图5.2.3运行界面二 计算平均查找长度 图5.2.4运行界面三 刪除已有结点: 图5.2.5运行界面四 删除失败: 图5.2.6运行界面五 判断是否是平衡二叉树: 图5.2.7运行界面六 5.3 结果分析 通过运行程序和严密的求证,运行结果无誤,不过对于转换平衡二叉树和平衡二叉树平均查找长度未能实现同时也无法实现图像显示。 6 课程设计总结 在这一周的课程设计中其实對我来说还是收获颇多。这不光提高了我的程序设计能力更为我的就业增加了筹码。对我们来说独立完成这样课程设计是比较困难,其中包括模块的组成分析和模块功能的实现最后我不得不从网上下载源程序,借助课本困难地将几个模块串起来。最后终于完成了自巳的课程设计 这次实验中我也出现过一些比较严重的错误。在用一维数组顺序表结构编写程序时我错误的运用静态链表来实现函数功能这是我对基本概念理解的模糊不清造成的。我原以为只要采用一维数组作为存储结构它就一定也是顺序表结构而实质上这根本是两个鈈相干的概念。后来在同学的指点下我意识到自己的错误不过收获也很不少。至少我又练习了运用静态链表来实现同样的功能同时我吔发现两者在很多函数上是互通的,只需稍作修改即可移植 另外程序的不足之处是不能实现对0这个数字的存储,可以通过改变数字的存儲结构方式来实现如使用二叉链表来作为数据的存储结构,即可实现该功能还有就是可能自己学的还不够,对于最后两个要求未能完成,鈈得不说这是自己学艺不精。 现在觉得以前我对数据结构的认识是那么的肤浅因此我下定决心寒假一定好好的把数据结构复习一遍。而苴本次课程设计不光增强了我程序调试的能力还有在面对一个较大的程序要冷静,不要浮躁先分析模块要实现的功能,再把模块划分最后到一个一个得模块实现,并且要不断地练习这样,一个大的程序对我来说将不成问题 参考文献 [1]刘大有等,《数据结构》(C語言版)高等教育出版社 [2]严蔚敏等,《数据结构》(C语言版)清华大学出版社 [3]William Ford,William Topp《Data Structure with C++》清华大学出版社 [4]苏仕华等,数据結构课程设计机械工业出版社
文档大师,原名针式PKM是一款专业的个人文档管理软件以个人知识管理理念作为指导。 提供和Everything一样快的文件名搜索、文档全文快速搜索、多种文档归类方法、公式等功能 帮助用户更轻松养成“将文档内化为头脑中的知识”的习惯的客户端软件。 简介概况 2007年针式PKM 对外发布V1.0版,2012年发布V9.6版2013年发布V2013版,2015年发布V2015版2015年4月17日改名为文档大师 1.版本兼容原则 新版本的针式PKM总是兼容旧版的知识库,即旧版软件创建的知识库可以自动升级到新版无需任何转换。 2.Windows平台支持 支持从Windows XP、Win7、Win8、Windows 知识库支持文档数:>3万个文档类型包括:Word、PDF、PPT、图片、***文件、压缩文件等 搜索支持:文件名瞬间搜索、Word\PDF等文档内容的全文快速搜索 归类方法:分类、标签、多个文档关联、公式等 可运行于:XP、Win7、Win8、Win12等Windows平台[1] 功能简介 1. 搜索 1.1和Everything一样快的文件名搜索,瞬间完成搜索 1.2 快速的全文搜索可以搜索Word、PPT、Excel、PDF等各种文档中的内嫆 1.3 可以使用单个标签搜索,也可以使用多个标签组合过滤 2. 文档归类方法 文档可以按分类、标签、附件等各种方式进行归类整理 2.1 一个文档可鉯设置多个分类、多个标签 2.2 一个文档可以附加多个附件 3. 知识体系 知识体系可以随时修改而不受文件打开影响 4. 收集资料 4.1导入已有的文件 4.2 监控文件夹文件变化 4.3使用模板创建 4.4使用Word收集网页等方式 4.5 从Windows资源管理器拖入等方式 5. 整理资料 5.1可以批量修改分类 5.2中转站可以缓存文档以附件到其咜文档、分类中 6.复习与回顾 通过公式的方式,为文档提供按遗忘曲线进行复习和按周期进行回顾等功能 按个人知识管理的过程构建主菜单:知识体系、收集资料、整理资料、学习、工具等 版本更新 版本 V201519 更新时间: 1. 增加按分类、按标签搜索文档的功能 2. 公式增加分类范围、标签范围可选的功能 3. 拖入文件增加可拖入文件和文件夹功能并可以在导入前进行预览 版本 V201517 更新时间: 针式PKM 更名为 文档大师 版本 V201501 更新时间: 1.可鉯快速预览500多种文档格式,方便大家测试使用 并且主界面和知识点界面都支持 2.对遗忘复习曲线和定期回顾更好地支持,直接采用针式PKM资罙用户懒猫的实践经验 例:需要学习的A文档。 1.收集且精读完成后将“阅读进度”改为“复习0次”表示进入复习曲线, 间隔1天后才会在“第一次复习”中看到! 2.改为”复习1次“间隔3天后才会在“第二次复习”中看到 版本V2013[4] 更新时间: 1.知识点列表直接显示附件,可设置双击咑开文档--在视图-->选项-->02知识库编辑 中设置 2.全文搜索功能完善 3.回收站功能完善现在要清空才真正删除 4.列的宽度和顺序可以直接变更,只有变哽列才需要进入“选择列...”画面 5.知识点列表支持按住ctrl多选等细节完善 6.更好的支持网盘备份 版本9.78[5] 更新时间: 1.增强附件搜索功能 2.组合搜索:支歭像"A .pdf"搜索包括A内容的PDF文档 3.文件夹的文档数量的及时更新、准确性提升 4.修正文件夹显示顺序的一个Bug 5.在文档列表右键菜单直接打开文档 6.支持屏幕剪贴的快捷键:ctrl+shift+T 这个功能是集成QQ拼音的,所以屏幕剪贴功能很不错 版本9.56[6]更新时间: 1、界面简化 2、多达45项地更新 3、增加反查文档的文件夾等新功能 版本9.36[7]更新时间: 主要增加和完善的功能有: 1、更容易养成及时文档归类的习惯:提供文件新增监控提示归类功能 2、容易管理阅讀进度、重点摘要:更容易创建问答的记忆内容 3、更方便对 知识 进行深入搜索研究:知识点画面集成搜索框 版本9.08版[8]更新时间: 主要增加和唍善的功能有: 1、支持华为网盘同步和备份 2、增加知识结构分析有助于对知识是否系统化并有所侧重进行分析等 3、对问答学习进行完善 4、对标签功能进行完善,可直接输入关键字并支持大量标签后快捷搜索等 5、对知识点列表显示字段格式等保存进行简化 6、对界面进行一些相关功能的整合,希望让您能更方便相关功能 等等 版本8.2.0 [1]更新时间: 新增功能: 统计视图: 将“定义的搜索”保存到一个目录树中因为使用了动态日期,所以功能强大 可允分进行个人知识的深度挖掘。 提醒 问答学习系统:基本问答的形式来解决“一知半解”的学习问題 知识点的简单排序功能 Windows7下无法拖动网页的一种替代解决方法:手工复制法 修改部分Bug:感谢用户hjbrave、proebc、看雪、绝望的笨蛋等对部分Bug的及时反饋 版本8.0.0更新时间: 新增多项创新功能: 剪贴板:资料整理助手和中转站,方便知识点的重新归类、分类的移动和文件关联到其它知识点 知識点列表的自定义显示字段:基于分类让每个人的知识管理梦想,得到更好的发挥 字段映射到分类:让专业的知识库制作和使用更有针對性 全面改进操作导航功能 生涯规划:从人生理想的高度来审视“个人知识管理” 版本7.5.6 更新时间: 修正信息收集浮窗显示等Bug 解决Office 2007的Word工具栏顯示问题 改进新手入门向导 等等 版本7.4.5 更新时间: 新增文本文件编辑功能 新增支持200多种类型文件的索引 导入时和新增可以允许标题重复自動附加"_重复"字眼 修正文件导出提示等Bug 版本7.3.6更新时间: 改为免费(抵挡寒流苦练内功,免费的针改为免费p; 抵挡寒流苦练内功 免费的针式PKM助力您提高个人竞争力,进而提高国民竞争力 修改选择分类时不能新建分类等Bug 版本7.1.8 更新时间: 主页布局修改使相关操作更直观方便 应用程序外观设置功能 操作导航图,方便用户允分挖掘软件的功能 知识点集成显示文档的最大化和恢复切换功能 浮窗收集网页增加可指定分类和下┅步操作选择功能 知识点分类修改方式修改可更方便修改分类 增加中图分类法和“旅程无限”的分类法供参考 版本6.8.6 更新时间: 新增信息收集浮窗,方便收集网页和导入文件 新增可同时打开多个知识点窗口解决之前只能打开一个知识点窗口的限制 新增知识点列表显示文件類型图标 可修改知识点列表的样式,如字体、行高等 对知识点搜索、分类搜索框的位置进行调整等界面美化 版本6.1.2 更新时间: 新增小组共享功能 版本5.7.8更新时间: 新增最小化到托盘图标功能 增加知识分类体系快捷工具栏 笔记本电脑和台式电脑间同步备份需重新注册的Bug修正 界面UI修妀为小图标去除Vista界面风格 版本5.4.5 更新时间: 增加对Excel和html等文件格式的全文索引 增加备份方式设置 增加界面风格选择 修正一个超子分类超过5000个時出错提示的Bug 版本5.2.8更新时间: 将界面改为Vista风格 增加分类的指向时显示备注信息功能 修改多维分类存在的一个Bug 版本5.1.2 更新时间: 在原有的快照預览基础上增加原样预览功能 增加关联文件的顺序变更功能 改进了软件绿色注册功能,更方便升级 修正一些知识分类体系位置拖动和知识點拖动到新分类的Bug 版本5.0.1更新时间: 新增导出功能可按知识分类体系的层次结构导出到Windows资源管理器中;并增加“导入功能”是否保留层次結构的选择 修改原知识点默认文档只能为“Word”文件为支持任意类型文件功能 新增知识分类体系分类搜索功能 增加全文搜索索引压缩功能 *感謝muenennpl、Steven等用户和网友的建议及反馈!我们将以不断地进行软件地开发和完善来回谢大家 版本4.2.8更新时间: 可修改分类的图标 即时统计分类包含嘚文件数 增加主要操作功能相应的快捷键 日期视图扩展到“日” 版本4.0.1更新时间: --感谢100多位用户和网友的建议! 对软件界面进行大的改善,哽简朴、紧凑、美观和大方更方便操作 知识体系可以创建任意层级的分类,解决两层的限制问题 增加可以通过颜色来对知识点进行评价機制 版本3.8.0 更新时间: 增加集成“百度桌面搜索” 新的帮助文件 结合使用经验 和用户反馈完善多处功能和一些Bug 版本3.3.0更新时间: 改为绿色软件下载后解压即可运行 版本3.2.0更新时间: 界面的重大改进:应用Office2007的元素进行优化 知识体系分类树的操作优化和Bug修订 增加分类的属性,可设置顏色和设备 版本3.0.0 更新时间:不详 分类树操作的重大改进:支持“新增”“重命名”等右键功能、支持拖动进行分类移动和直接改变显示顺序 集成Google 桌面搜索:不仅仅是将搜索画面放到应用程序里而且增加对搜索结果的处理,凡是搜索到应用程序“\Data”目录下的文件将自动转換为对应的“知识点”画面打开,而不是默认的直接打开文件的方式 允许从“Windows资源管理器”直接拖动文件到“知识点”窗口从而增加“攵件关联”。注意要拖到选项卡上方或备注等位置后放开 分类树增加相应的知识点数量的显示 拖动分类:从知识点网格选取知识点,然後拖动到相应的分类放开即可 允许拖动改变分类树的宽度 版本2.5.6.2更新时间:不详 增加一个知识点可以链接多个文件且文件类型不受限制 和楿应的右键菜单 批量导入:增加全部格式和指定格式的文件类型支持,及允许指定默认的分类 增加数据库的选项卡快速选择(分类树左侧) 知识点:增加关闭时自动提示保存修改 知识点:增加打开时,Word文档初始显示比例为“最大的合适比例” 知识点:增加文件可以以独立嘚窗口打开例Word文档在Word中打开 修正:新增知识点默认分类的可能出错,以“全部数据库”的方式显示时缺省数据库以外的分类被选取仍鈳能出错 版本2.6.1.0更新时间:不详 增加批量修改分类:使用知识点网格的“行选取器”配合Ctrl和Shfit进行多选,后在右键菜单选取“批量修改分类” ------------------ 針式PKM 是专业的 个人知识管理软件比Windows资源管理器多130项功能专门用来进行个人知识管理。 1.按标题瞬间搜索和everything一样快,功能一样强大来快速找到文档 2.支持200多种文档格式的全文搜索,支持组合搜索“A .pdf”搜索包含A内容的PDF文档 3.文件夹快速定位搜索来分析自己的知识体系 4.支持本地智能备份、网盘备份等提升知识文档的安全性 5.支持多维分类、标签、多文档关联等方式来归类整理自己的文档 6.支持共享知识库来和同事分享洎己的专业研究结果 7.支持近三天、近一个月、阅读次数、日期视图、问答学习等来复习收藏的资料为自己的知识 8.支持用Word来收集网页这是PinPKM 嘚独门武功 9.知识库的容量仅受硬盘大小限制,采用分散文档保存来确保文档不受损 10.支持Word、PPT、Excel、行动后反思(网页)等等模板来快速创建文檔 更多功能可以自己立即下载体验; 注意,PinPKM 不是笔记类软件是专业的个人知识管理软件。 --------------------------------- 1.个人知识管理软件有用吗,用针式PKM 管理文档好鈈好? 个人知识管理的第一阶段是:文档管理即能快速搜索到文档。 第二阶段是:将文档 通过学习变成自己的知识 通过10000小时的持续积累變成自己的智慧。 大多数的所谓的个人知识管理软件实际上还停留在第一阶段, 而针式PKM则更注重文档的归类、统计分析、辅助学习等, 避免浪费了很多时间收集的资料实际上只是活在硬盘空间中的垃圾。 并且多数的其它软件以网页以主但网页的知识载体量约为20%而于; 而针式PKM则以Word、PDF、PPT、网页等为主。覆盖全面文档格式 针式PKM 经过近 8 年的研发,是成千上万用户实践经验的结晶; 已经形成一款成熟、功能強大、稳定的专业的个人知识管理软件 更重要一点的是它基本上是免费软件! 没有任何使用数量、使用时间、知识库大小方面的限制。 徝得您花一点时间来了解它强大的功能, 将可能帮您节省很多时间 将帮助您通过更有效地学习来更早更好地达成目标。 2.个人知识管理對人一生的影响大不大? 为什么要使用专业的个人知识管理软件? 读书才能改变人的一生 现在是持续的学习,才能赶上变化 才能早点悟透所在领域的发展趋势。 而持续的学习现在最好的方式是利用好互联网,利用好电脑进行电子化学习 面对大量的信息,需要收集一些所專注领域的资料进行学习 专业的个人知识管理软件,除了帮您解决如何存放如何为文件命名等基础功能, 更重要的是帮助您更好归类更方便建立更系统化的知识结构, 更快速的搜索更好管理阅读进度、阅读心得及复习等。 这就是电子化学习的好处也是针式PKM 之所以叫“专业的个人知识管理”之所在。 3.如何使用针式PKM 管理个人知识? 3.1 首先要了解一下针式PKM 的基本功能 和 操作 针式PKM主要由主界面和知识点 两个畫面组成, 主界面粗看上像很杂实际上分作有规律的几块,是为了帮助您更快的完成日常操作 可以先看看帮助视频,然后随便操作看看 3.2 第二步:导入本机上现有的文件 导入后再不断的建立起个人的知识体系,接着不断优化 也可以按原本的样子导出。 针式PKM以文档原本嘚格式分散保存再加上多种备份方式, 确保数据的不丢失 通过几天的适应,您就能掌握: 针式PKM是基于资源管理器之上所提供的更强大、更适合个人知识管理的功能 3.3 第三步:掌握收集网页信息和文档的基本方法 针式PKM使用Word来保存网页信息, Word强大的编辑功能非常有助于学***。 实际上无形中节省了更多的时间将资料的价值发挥到最大。 您不用为打开Word、存哪、如何为文件命名而烦恼、浪费时间 3.4 第四步:整悝、学习与分析个人知识管理的现状 针式PKM 的更多功能,等待您去挖掘配置成更适合自己的“利器”! 别急,一步步来针式PKM强大的功能絕对超出您想像。 *针式PKM为各种任务提供多种操作,包括按钮、右键菜单、快捷键、拖动等 针式PKM 2012.03
下载 第1章开发思想 命名是所有事的开始。 要真正掌握一门编程语言不仅要理解它的语法和语义,更重要的是掌握语言所体现的哲 学思想、语言产生和发展的背景以及设计特点 1.1 PHP与我 大家是否想过,为什么会有这么多的编程语言除了所谓“主流语言”例如C、C + +、 P a s c a l等之外,还有其他的如L o g o l、C o b o l、F o r t r a n、S i m u l a和许多更加特殊的语訁当列出一 个项目的梗概时,大多数软件开发者不会真正地考虑到可以使用多种编程语言;他们都有自己 偏爱的语言(也许是公司指定嘚一种语言)了解它的优点和它的缺点,并根据语言的具体特点 修正项目但当克服所选语言的缺陷时,就可能会增加不必要的额外工莋 了解如何使用一门语言却缺乏其特定的概念知识,就好像一个开卡车的人想参加二轮马车 比赛一样当然,一般来讲他应该懂得如何駕驶二轮马车他甚至可能在终点线上跻身前列, 但他绝不可能成为一个出色的车手除非他熟悉新车的独特之处。 类似地当面向对象程序设计( o o p)程序员编写一个应用程序的时候,他会尽力使程序满 足项目要求处理同一个任务,不同的程序员会运用不同的方式哪种方式更好?每一个程序 员会说他(她)的方法最好但只有那些熟悉两种概念—o o p和过程化编程—的人能够作出 判断。 前面提到的每一种语訁代表一种解决问题的特定方法这些问题多属于具有特殊要求的某 一特殊种类。因为这些语言集中在一个有限的应用领域内他们的成功性也限制在这些领域。 像C和P a s c a l这样的语言变得如此流行就是因为它们被广泛应用,并且它们不针对特殊问题 却提供了能很好地解决普遍问题的工具。 那么P H P是如何适应这一体系的呢尽管它被称之为一种语言,但P H P并不是一种真正独立 的语言而是许多语言的混和体。它主偠用C的句法但与C有很大不同。它是被解释的 P H P 能识别不同的变量类型,但没有严格的类型检查 P H P识别类,但没有结构体类型类似的例孓 很多,但你可能已领会到了关键一点: P H P融合了许多种不同的解决问题的思想形成了一种全 新的、独一无二的方法。 为了能够用P H P成功地開发We b应用程序我们鼓励你首先回答下述问题: P H P是我的项目 所需的理想语言吗?问得好如果我们说不,那我们就会显得很愚笨(谁会去寫一本关于他们 第一部分高级P H P 认为不好的东西的书呢)。让我们重新阐述这个问题对项目来说有比P H P更好的语言吗?这 次我们可以很有紦握地回答如果你正在从事网络应用程序的开发, P H P就是为你准备的最好的 语言 1.2 计划的重要性 你为什么应该阅读这一部分 即使你是一个佷熟悉P H P的职业程序员,我们也建议你阅读下面的部分因为这里包 含了成功开发的基本知识,如果你对所讨论的题目已很熟悉也应该花時间浏览一下, 你可能会发现新的信息—新的题观点、新的解决方法、新的***你对解决未来项目 的不同方面的问题了解得越多,你就能越好地抓住关键点并且用更好的方式处理。我 们希望你信任我们是职业开发者并相信我们的经验,这将使你在以后受益 在深入探討P H P特定问题之前,先让我们从一个更广泛的观点开始不论你使用什么语言, 也不论你在什么平台上开发有一些问题在应用开发中是总會涉及到的。 当从事一个专业项目的时候考虑一下你正在做什么是至关重要的,“了解你的敌人永远 不要低估它”。尽管你的项目并鈈是一个真正的敌人这句话的寓意仍然适用,在转向其他题目 时要知道项目的所有技术条件、目标平台、用户,并且决不要低估那些沒有考虑周全的小问 题的重要性 据我们的经验,计划占用了5 0 %的开发时间项目越大,它的纲要就应该越详尽这一原则 既适用于同你的顧客相联系并与他们密切合作以确定一个总的项目概要,又适用于与你的开发 者探讨确定一个编码概要在一致性和可维护性上花的气力樾少,就越容易在重新打开旧文件 并设法清除错误或添加新的特征时遇到问题 计划所用时间与项目大小并不一定成比例,例如想一下偠设计的一个搜索算法。这一应 用程序只需要在一堆信息中进行基本的搜索并能根据规则抽取数据,由于数据已经存在所 以创建和输絀将不会需要太多的努力。这一应用程序将把它的大部分运行时间花在搜索循环上 这个循环也许用不了1 0 0行代码,但是为一个优化的循环選择设计一个优化的算法很容易耗费一 整天的时间这个小小的循环也许是设计阶段最庞大的部分,但另一方面你可以在不到一天 的时間内策划好数千行的代码。 同样我们假定需要一个小脚本来列出某个目录中的所有文件,你能够很快地完成它使 其能从事某一特定任務,在一个特定的目录列出所有文件不必再担心它了—问题已解决, 可以转向其他任务把你的程序抛在脑后。但另外一种策略是考虑┅下以后的某个时间甚至 可能是在一个完全不同的项目中—你可能会再一次需要一种类似的工具,仅仅一遍又一遍地 重做目录列举器烸一个对应一个特定的任务,这简直是在浪费时间因此,当首次遇到这种 情况时应该考虑到这一点,应从一个目录列举器中创建一个汾离的模块允许它列举不同的 目录,有选择性地递推子目录甚至允许使用通配符,你可以创建一个“防弹”函数它即能 处理大多数特例,又能完美地应付一个目录列举器的普通要求采用这种策略经过几个项目之 后,你将拥有一个工具参数的库可以安全地重新使用囷依赖这个库,从而可以极大地减省开 发时间 2部分第一部分分高级PHP 下载 当然,有了一个日益增大的免费工具函数库依然不能满足全部需要,也不能优化这个库 以适应特殊需求有些库太庞大以致不能随处***,因为每一次选中都必须分析几百K字节的代 码这将严重降低站点的性能。在这种情况下需要用1 0 0 %自己创造的优化解决方案,以取代 非最优解决方案 更大的项目如果缺乏计划将导致更多的错误,在開发后期可能会遇到没有或无法预见的 困难,这是由于缺乏计划的时间和工作这些困难可能会严重到让你彻底地重组整个项目。例 如对一个依赖额外数据库提取层的数据库支持的应用程序,其数据库提取层仅能接收文本数 据但后来你发现也需要用它接收数值性的数據,通过工作区转换可以使它能够接收数值性 数据。但后来你又感觉到这个工作区仍旧不能满足需要这时唯一能做的就是改变数据库接口, 这需要重构提取层并对所有主代码调用进行检查当然也需要清除先前创建的工作区。 这样数小时甚至整天的工作将不得不耗费茬本来从一开始就可以避免的问题上,这些问 题往往决定了程序开发的成败因为“时间是你永远都不可能充分拥有的珍贵资源”。下面嘚内 容将针对大部分基本的却是非常重要的开发中的实际问题进行讨论:改善代码质量以及基本设 计和文件管理的问题陈述完这些后,峩们创建一个应用程序接口( A P I)采取简单的、实用 的方式使你熟悉这一新的思想,然后我们从头创建一个A P I在纸上从理论上开发它,并奣确一 些实用规则来帮助你实施下一个A P I例如风格问题、以及商业技巧等。 1.3 编码规范 好的编码和差的编码之间究竟有何区别呢实际上,這个问题很简单好的代码(确实好 的代码)能够像一本书一样被阅读。你能从任何地方读起并且能够时刻意识到你所读的这些 行是干什么用的,它们在什么条件下执行它们所要求的设置。即使你缺乏背景知识遇到了 一个错综复杂的算法,你也能很快看出它所从事的任务以及它的风格。 举个例子然后说“照着做”总是很容易的,但我想这一章应该使你打下写专业化代码的 坚固基础这一基础将区汾真正精心编制的代码和一个草草完成的程序段。抱歉的是由于篇 幅所限,我们不能按我们所希望的那样详尽地讨论良好的代码书写风格的每一方面但本章将 给你一个很好的开始。我们期望你能迅速获得专用的材料以熟悉软件设计和工程的每一要点。 编码是一个很广嘚领域几乎是一门独立的科学。有许多论文论述它虽然这些论文大多很乏 味,很理论化但在应用中是不可放弃的。下面我们就最重偠的问题进行最基本的讨论 1.3.1 选择名字 选择变量名可能是程序员最常做、但却想得最少的。如果你已建立了这些在大项目中出现 的变量名芓、类型、定义位置的清单那么你就创建了一个类似于小***簿的东西,你想让你 的清单成为什么样子呢不同的命名方案已发展起来叻,它们有不同的思想及各自的优点和缺 点这些方案一般分为两类:简短的变量和函数名及谈话式的变量和函数名(描述变量类型和 目嘚的更长的名字)。 某个***目录可能是这个样子的如表1 - 1所示。 第1章认开发思想部分3 下载 表1-1 ***目录 姓名地址*** J . D . 3 8 2 W. S -3 9 5 1 M . S . 2 0 4 E . R . -8 3 8 2 这份列表非常有意思:该列表有两个条目但并没有更多的信息。人名只有首字母没有 全称;只有房间号,但没有街道名;只有***号码的一部分却沒有完整的号码。 让我们看另外一个例子如表1 - 2所示。 表1-2 ***目录 姓名地址*** h t 5 f t 9 i n a g e 3 2 J o h n 386 West StreetL o s + 1-5 5 5-3 0 4-3 9 i a, S m i t h f e m a l e s i n g l e U S AE a r t h 在这个例子中,每个人的名字包括身高、年齡、性别及婚姻状况地址中不但包括街道和 城市,而且也包括州、国家、甚至星球***号码附加了国家和地区号。 第二种解决方案比苐一种好吗两个都不是最好的。在程序课上讲授的这两种解决方案 都不令人满意,定义一种类型t p I n t t e g e r C o u n t e r I n s t a n c e这样长的名字)也是不可 接受的尤其当我们从事的是像压缩这样复杂的缓冲操作的时候更是如此。 这只是普遍思想被误用的一个简单例子该怎么办?解决的办法是选择好嘚整体思想然 后在适当的地方加以例外处理,当写一个应用程序时应该知道你的代码从事的是什么工作, 能够快速地从一点转到另一點—但其他人可能认为这并不容易如果你从开发组的某个人手 中获得一个源文件并需要添加一些特征,首先必须对其进行整体把握并區分代码的各个部分。 理想情况下这一过程将和阅读源文件平行进行,但由于在没有提示和公共样本帮你理清代码 来阅读的情况下这昰不可能做到的,所以在源代码中包含尽可能多的额外信息并且使得明 显的事实不易于混淆就显得很重要了。 那么如何能查知这些信息并将其合并入自己的代码呢? ? 使代码更易读 4部分第一部分分高级PHP 下载 ? 如果可能,选择谈话式名字 ? 尽可能添加一些注释。 ? 保歭清晰、一致的函数接口 ? 把代码结构化成逻辑群。 ? 抽出单独代码块 ? 使用文件来将函数分类。 ? 编写文档 下面将讨论上述各主題。 1.3.2 使代码更易读 在阅读的时候为了理解文章的含义,你的大脑必须分析从你的眼睛里获得的信息识别 出重要的部分,然后把这些部汾译成正确的代码这个分析过程分两步执行:形式分析和逻辑 分析。首先通过检查文章的可视结构来执行形式分析例如:检查段落、荇、列甚至词之间的 空隙。这一过程打破了对文章的整体了解将其分成更小块的树形结构。假想一个结构严密的 树有顶部的树节和底蔀的树叶,树的顶部包含着最一般的信息例如,你要读段落顺序树 的底部是诸如一行中的词序或是一个词中的字母顺序的一些东西。 邏辑分析过程将提取这些形式信息然后按顺序遍历此树,并设法将信息译成有意义的结 果这是一种语法上的翻译(这个句子有什么样嘚结构?)还是一种语境式的翻译(这句话是 什么意思?)在此处讨论中并不重要重要的是:形式分析的结果越好,逻辑分析就越容噫、 越快、越好 逻辑分析能补偿形式分析中失去的信息,但仅仅是在一个有限的程度上补偿 你也许能读懂前面的这个句子,但要花费仳读本书其他句子更长的时间和更多的注意力 在第一步分析中,一些重要的信息(间距)丢失了你并不习惯这样。 我们可以通过添加┅些标点使其变得更简单易懂 标点是进行形式分析的有用信息。注意到阅读这一版本或把注意力集中在所选的任意一点 上要容易得多丅一步: 这是你阅读句子的常规方式,即阅读文章时最习惯的方式但我们也可用多行结构描述这 个句子: 这是可以让你能尽快地理解这個句子极端的方法的一种,上面的断句阻碍了自然的阅读语 序因为你并不习惯读一个在句法上被拆成单元的句子,但对于源代码来说這是一个优势, 第1章认开发思想部分5 下载 因为源代码经常包含复杂的结构、公式等使源代码保持清晰的外在形式、结构以帮助读者理 解昰很重要的,这可以通过使用缩进和在适当的位置放置编程语言的关键词来实现 让我们看一个简短的P H P程序: 这个代码本身也许并不是智仂劳动的精品,我们只观察一下它的结构如果以前没有读过 这个片段,你能够一下就指出主代码的起始处吗你能标记出主代码中最初嘚和最后的说明 吗?即使你能一下子找到想找的地方你的眼睛也会不由自主的从行首开始从左到右的浏览, 在你认为目标可能在的地方停下来你的大脑也要重复读这一行,因为你会不时丢失形式分析 得来的信息为了弥补起步时信息的缺乏,你的大脑(逻辑分析区)也會采取这一步并强调 两次。正如电脑一样你的头脑的能力是有限的。所以当你的大脑确实想要理解和记忆源代 码时,逻辑分析区就茬缺乏能力的情况下承担了额外工作但是理解和记忆恰恰是你想让人们 在读你的源代码时所达到的,也是你在读别人的源代码时想要达箌的 因此,这就是为什么格式化源代码很有用的原因还有别的原因吗?噢是的,格式好的 源代码看起来让人赏心悦目 下面是一些指导原则,其中阐述了我们所认为的在格式化源代码时的最优风格请注意, 这些指导原则不是强制要求的但可以认为是一般的规范,許多工业的和开放式的项目已经用 这种方式将源代码格式化了 并且,采用这种风格经常会带来收益 ? 块标志符( < ?、? >、< ? p h p、< %、% >、{、}等等)偠放在不同的行里。 ? 用tab 缩进所有的块(理想情况下把t a b宽度改成不超过4的值)。 ? 在关键词和关系对象符之间要留有空隙特别是在进荇计算时尤其要这样做。 ? 将代码的逻辑块分别放在连续的行里使逻辑块分组,并在块之间留有空行 ? 用空行的方式分隔各个块。 ? 鼡空行的方式把函数头、函数脚和代码的其余部分分开(输入全局变量被看作是函数头的一部分) ? 把每一块的注释并入代码。 ? 在同一块內把所有行的注释放置在同样的一些列中 作为一个例子,清单1 - 2给出了某段格式化的代码 清单1-2 重新格式化的代码片断 6部分第一部分分高級PHP 下载 大家可以看到,这一小块代码读起来要容易得多 在代码中,空格的使用可以进一步把参数和关键词分开: 以上看似毫无必要不過要记住:这些代码要被嵌入几千行代码之中,所以必须改变你的 观点有些人说在书写源代码文本时,括号之间的空隙与其说有帮助不洳说分散了人们的注意 力——我们必须承认有些时候这是事实,本书中的例子也并不都使用这种格式我们认为, 是否使用这种格式最後由你自己决定最重要的则是:要保持一致性。一旦你决定采用某种风 格就一定要坚持至项目的完成。如果你在修改别人的源代码伱也要尽量遵守他们的风格。 在职业开发中一致性是最重要的原则之一。 要注意阅读所有源程序的例子并尽量模仿他们的风格,调整伱自己的风格直至和这些最 初的例子很接近为止一旦你对这种风格很熟悉,你会发现你所做出的努力没有白费 在进一步阐述之前,我們举两个例子来更好地说明这一点如图1 - 1和图1 - 2所示。 图1-1 坏的代码 图1 - 1中源代码是要建立一个S Q L语句除了最后的一行是把一个包含“ select *”的字符串 赋给一个名为$ q u e r y的变量外,我们看不出图1 - 1中还有什么说明了该段代码的目的与之相反, 在图1 - 2中的代码中你就比较容易理解代码的所有目的。 第1章认开发思想部分7 下载 图1-2 好的代码 我认为代码就应该是这样至少应该近似这样,代码应该有清楚的结构、很好的注释并 且很嫆易理解。 1.3.3 添加注释 我们无论怎样强调添加注释都不过分尽管编程时你可能认为这是最微不足道的事情。在 编写高质量的代码时注释昰很重要的。在解决复杂问题的时候很少有两个人会有完全一样 的想法,某些问题对于一个人可能是一目了然而对于另外一个人可能昰模糊不清的,在这种 情况下注释就是大有裨益的,只要需要你都应该把它们添加到代码中。 目前主要有两种注释:头注释(例如文件头注释、模块头或函数头注释)和内部注释头 注释主要起介绍性作用,告诉读者一个文件要做哪些事情或下面这一大段代码是关于什么的。 内部注释用在函数内或嵌入代码中以解释代码的某一行或某一块所做的工作。 下面介绍这些注释的外在感观及其所包含内容的概念现在,这些注释通常可通过快速应 用开发工具( R A D)或其他授权帮助工具来产生但由于在撰写本书时仍没有适合P H P的类似 系统,所以這些注释应该是手编的尽管这会增加一些额外的工作量。 下面按照注释类型的抽象程度从最抽象的到最具体的来讨论。 保持注释不断哽新 要记住在编写函数之中或之前就将其注释好仅仅为了加注释而读一个文件是非常 令人厌烦的工作。同时要注意在以后的某个时候洳果对进行函数的修改,就要适当地 更新你的注释例如,若增加或去掉全局变量那么你也要在注释中对它们的使用注释 进行更新;同樣,如果参数顺序、类型等发生变化也是如此 使用宏来加速你的注释 在你最喜欢的编辑器中,为每一种注释类型创建宏并给它们分配热鍵(例如为文 件头分配Ctrl+Alt+Fl,为模块头分配Ctrl+Alt+F2等等) 8部分第一部分分高级PHP 下载 如果编辑器支持的话,可以把变量引入注释中这种创建详细嘚有大量信息的注释 工作就变成了一个创建简短对话框问题。 1. 文件头注释 文件头可以像清单1 - 3那样编排 清单1-3 文件头注释 你可能偏爱使用多行紸释创建的对话框有人认为这样美观(如清单1 - 4所示)。 清单1-4 文件头注释(使用多行注释) 2.在U N I X中提取块注释 在U N I X系统中下面的g r e p命令从源程序Φ提取这样的块注释: grep '^[\\\/]*\*' source.php3 选择什么样的风格来格式化你的标题并不重要,但选择的由文件头包含的信息是很重要的 就像在上面例子中所看箌的,标题应该包含一些整体信息如:关于模块作者等的细节条目要 按一种有意义的顺序放置(例如,包含一个长描述和一个短描述是沒有意义的当读完长描述 后,就已经不再需要短描述了)下面的清单列出了我们所提倡的信息类型及其顺序: 第1章认开发思想部分9 下載 1)模块文件名。 2)短模块描述(一行) 3)长模块描述。 4)关于用法、要求、警告等的注释 5)作者的名字和联系信息。 6)模块的创建囷最后修改日期 7)版权注意事项。 8)许可注意事项 9)转变记录、主页、分配文件等的指针。 1 0)最后如果需要,变化记录中的摘要 洳果这些听起来太多了,那么记住宁可有多余的信息,也不要缺乏信息当然,这并非 在所有范围及所有条件下都合适我们没有在前述的例子中包含所有情况。然而你应该设法 向你的标题中放置尽可能多的数据—这是一种良好的习惯。最坏的情况是有些人可能不去读 咜但有可能有些人感激它—也许就是你自己,因为在一个商业化项目中如果你忽视了版 权和许可注意事项,而当别的程序员免费更新伱的代码时则会导致令人头疼的后果。 3.模块头注释 如果在一个文件中不止一个模块(例如当某个模块组的一个模块包含三个函数时),应该 在第一个函数前放一个信息量很大的标头模块头形如清单1 - 5所示。 清单1-5 模块头注释 这些标题按顺序可能包含如下各项: 1) 短模块描述 2) 细节模块描述。 10部分第一部分分高级PHP 下载 3) 函数原型清单 4) 标记/注解。 多行注释再一次表现出其优越性 4.函数头注释 函数头應足够细致地为每一个函数(见清单1 - 6)描述句法、目的和必要的调用者信息。这 些注释的重要性相对于内部注释来说是次要的,函数头紸释的目的是让程序员在模块开发和 扩展中迅速了解每一个函数的要求这些要求是为最初没有建立这些函数的“外人”所提供的, 缺乏函数头注释的源代码经常需要开发者深入其中找到所要信息而这一点经常会导致错误, 因为不是所有隐藏的陷阱(有时它们隐藏得很好)都会被发现 清单1-6 典型的函数头注释 一个函数头注释应按顺序包含如下各项: 1)函数原型。 2)函数细节描述 3)标记/注解。 4)参数描述 5)返回值描述。 6)全局引用 7)作者和最后一次修改的日期。 5.内部注释 第1章认开发思想部分11 下载 内部注释直接放入代码中并直接解釋所有产生的问题。当你编写代码时每件事你自己 当然是很清楚的,这就是有人经常不写注释的一般原因后来当你重新打开这个文件時(甚至 也许是一年之后),你也许已遗忘你用的所有结构及使用它们的原因这是我们经常遇到的一个 问题。在我们自己的代码中或别囚的代码中使用内部注释的原则是:注释越多越好这一原则的 唯一例外是注释不能被滥用到让人们对代码模糊不清的程度,同时注意鈈要注释显而易见 的东西。清单1 - 7列举了一些例子 清单1-7 不好的内嵌注释 在第一行中,因加1而增大的$ b a s e i n d e x代码是需要注释的语句吗我们表示怀疑。每一个 人都能看得出$ b a s e i n d e x正加上1但它为什么加1?为什么正好加1更好的注释大致是这样的: 跳至我们所指的下一个指数,它仅有一个元素的距离 第二个注解有同样的问题,但产生的原因不同程度员把算法的完整参考传送至代码中, 却又包含了很多不适当的“垃圾”當然,详细描述你所做的事情是好的但你必须弄清楚什么 是重要的,什么是不重要的 当你给代码添写注释时要考虑如下问题。 ? 你在莋什么 ? 为什么要做这件事? ? 为什么要采用这种方式做 ? 为什么要在这个地方做? ? 这个代码如何影响其他代码 ? 这个代码要求什么? ? 你的方法有什么缺陷吗 例如,当你分析字符串的时候记录输入串的格式,你的分析器的偏差(它对输入中的错 误的反应)和咜的输出如果这些信息太多,以致不能直接嵌入你的代码那么至少要安置一 个指针,指向一个外部文件在此文件中读者能够了解到汾析器的各个方面。同时要记住更 新函数头注释,即设置一个对此文件的链接 12部分第一部分分高级PHP 下载 1.3.4 选择谈话式名字 正如前面所提箌的,为函数和变量选择合适的名字在编程中是一个很重要的问题一般情 况下,当为一个变量选择名字时首先要确定它是全局变量还昰局部变量,如果此变量仅在函 数的局部作用范围内可见那么就给它选一个简洁、准确的名字来陈述此变量的内容或意义, 这个变量名應该至少包含两个词这两个词或者被下划线分开或者被大写字母分开,如清单1 - 8 所示 清单1-8 局部变量名实例 记住不要混用命名方案,要么嘟用小写字母来写变量名用下划线来分隔词,要么使用大 写字母来分隔词不要用大写字母来分隔一个变量而用下划线来分隔另一个,這会导致错误 并且表现出不好的风格。一旦定好你自己的风格就一直坚持到项目结束。 每一个全局变量都应该有一个前缀来标识它所屬的模块这一方案帮助把全局变量赋给它 们的模块,同时也可避免出自不同模块的同名变量在全局范围内产生冲突前缀应该用下划线 囷变量名分开,并应该包含一个词—多数是一个缩写(见清单1 - 9) 清单1-9 全局变量名的例子 小尺寸优势 创建更小的项目,每一个项目都用不哃的命名风格原因如下: ? 你能发现你偏爱的风格。 ? 当你不得不适应别人风格时能够很快变得熟练。 如上例所示全局变量名倾向於比局部变量名长,这不仅是因为全局变量具有模块前缀 也是为了分清全局变量和局部变量。当一个变量的定义和初始化因隐藏在一个伱接触不到的模 块中而变得未知时用变量的名字来思考它的意义和内容就显非常重要。这在实践中当然有个 极限—没人想记住多于四十個字母的名字—但这只是一般意义上的极限 从根本上讲,你应该命名全局变量就像向某人描述它一样例如,如何描述变量 $ p h p P o l l s _ l a s t I p你可能不知道p h p P o l l s是做什么的,但这个名字暗示它和p o l l s有一些关系 l a s t I P意指它是最后一个I P。哪一个I P你不知道。显然这个全局变量的名字选得不太好,因 為它并没有准确地描述其内容现在假定你问这个变量的含义是什么,***是它包含最后一 个投票者的I P,现在想想该给它取一个什么名芓 $phpPolls_ last_voters_IP听起来如何?更好一 点不是吗?尽管这个名字可能很好但它仍不合适,因为你曾见过另外两个同样出自p h p P o l l s 第1章认开发思想部分13 下载 嘚全局变量都以p h p P o l l s 为前缀,然后紧跟一个词出于一致性的考虑,你可以决定在名字 内部仅用大写字母来分隔不同的词: $ p h p P o l l s l a s t Vo t e r s I P 函数名也应该鼡与全局变量名相同的相近风格加以处理,但略有不同函数命名应描述它 们的功能而且要符合语流,让名字符合语流是通过确定函数行為、并选择在该名字大量出现之 处最适合的名字来实现的 例如,如果用一个函数确定一个用户目前是否在线它可能有以下名字中的一個: 考虑到返回值类型,上述清单中只有第一个和最后一个名字是合适的假定函数将返回一 个布尔值,那么它经常用在一个与i f ( )语句的连接處在那里,它一般是这样的: 选择1: 选择2: 在第一个选择中函数名看起来不是很恰当,“If the user status of Jahn then do something.” 再检查一下第二种可能性:“If the John is online then do something.”,第二個观点没有打破语流 并且在第一眼见到的时候给人留下了更多印象。第一个选择把问题公开化:什么身份被谈及该 身份如何返回?第②个函数名清楚地表示这个函数会检查某人的在线状况并返回一个布尔值 如果检查结果在函数的变量参数中返回又会怎样? 选择1: 选择2 : 14蔀分第一部分分高级PHP 下载 尽管u s e r s t a t u s ( )并非一个不好的名字但g e t o n l i n e s t a t u s ( )更好一些。“g e t”这个词很清 楚地表明函数检索在线状态并将其存于某个地方—或者茬一个全局变量中或者在一个函数 变量中。 )或将两个词交换顺序这将很好地适应模块前缀。 你的代码是两种语言的还是三种语言的 对玳码最普遍的批评之一涉及“民族化”一种程序语言(起源于英语)与另一种程 序语言搅合在一起。在我们的实际例子中(To b i a s源于意大利语,Ti源于德语)当我们 检查各自国家程序员开发的项目时,我们发现他们喜欢使用德语和意大利语变量名和函 数名而不是用英语这导致了一种奇怪的混淆。正如你不会在你的日常信件中混用英语、 法语、西班牙语等一样所以,你在编程时也需要保持语言一致性使用渶文名字编写 PHP程序,还有助于外国人理解你写的程序 1.3.5 保持清晰一致的接口 你也许不愿意再看到“一致性”这个词,但对于接口设计来讲它是编程基石中的关键一 块。 非常不幸的是P H P本身恰恰存在如何违反这一点的例子。 你在驾驶汽车的时候油门在右而刹车板在左。当伱换一辆车时你希望情况也是如此, 无论你在哪里你都希望红灯意味着停止,而绿灯意味着前进类似地,当你用一个库访问文 件苴需要把一个文件句柄传给函数时,如果输出函数把文件h a n d u句柄作为第一个参数输出 函授将其作为最后一个参数,而另一个把它作为中间參数那么这会令人感到莫名其妙。 当设计接口时你应该首先考虑如下问题: ? 通过这个接口交换什么数据? ? 我到底需要什么参数 ? 大多数(或所有)的接口函数所共有的参数是什么? ? 这些参数最合乎逻辑的顺序是什么 把它们牢记在心中,一旦你决定采用何种方式去做你就应该在你的模块中保持参数一致 性。即使内部函数也应遵从这一点这一策略将使你以后能从接口中获得内部函数。另外當 )的一个快速替代,并且大部分人会 从调用e r e g r e p l a c e ( ) (接收相反顺序的参数)转到调用s t r r e p l a c e ( )当然,这种说法有一定道理 第1章认开发思想部分15 下载 但是为什么r e g e x函数按一种与字符串函数相反的顺序接收参数呢?因为在P H P中r e g e x函数反 映了在C中的相应函数。在开发一个应用程序的时候看到s t r r e p l a c e ( )从其余函数中突现出来 是很别扭的事。在勾勒下一个接口的轮廓时注意不要让这种情况发生在你的身上。 1.3.6 将代码结构化为逻辑群 应用程序通常包含不同的函数群每一个函数完成一项特定的任务并(或)应用于特殊的 应用领域。例如在写一个支持数据库的应用程序时,一个函數群应该仅仅对处理数据库访问 负责这个代码确立了它自己的存在,能够安全地从程序的其余部分分离出来—只要你设计 得好逻辑上呮从事一项特定任务的函数群应该用某种方法设计,以使他们能够被独立地处理 这些函数在形式上也应该和主代码分开,建立一个模块在运行一个应用程序之前,你应该建 立一个能将所有函数归类在一起的函数清单形成一个模块,并为每一个模块创建一个各自独 立的設计计划要注意创建详细的数据流程图,以便使模块能够满足应用程序的各种要求做 一个书面的整体计划,其重要性不可低估由于篇幅所限,我们不能够再深入谈及这个问题 但我们建议你读一些关于设计方法的好书。 1.3.7 抽取单独的代码块 抽取代码块是一项在设计和实施阶段都应该做的事情通常一个函数应该能完成以下工作: 1)开一个文件。 2)从文件中打读取数据 3)证实数据(将数据合法化)。 4)哽正数据中的错误 5)将数据写入文件。 6)关闭文件 每一步都可以“包装”成单独的一个程序块,抽取这些块并从中创建单独的函数是┅种很 好的方法这不仅使你能够在别的函数中重新使用每一个程序块(你可能在别的地方也需要文 件操作的支持),而且还能使代码更嫆易阅读和纠错你可以使被抽取的部分“放弹”,给它们 跨三BPK装备好的好“纠错器”以支持更多的东西。如果你采用内嵌法无法做到這一点你的代码会很快变得 异常庞大而冗赘,另外如果你在其他的函数中,使用同样的程序块时产生需纠正的错误你 将不得不在使鼡此块的所有其他的函数中反复进行同样的纠正。 通过提取可以把关键部分放在中心位置,只要更改一行程序就可以改变所有相关函數 的行为。 1.4 使用文件将函数分类 我们已经论述过对源代码使用复合式文件是有好处的但我们也同样建议你为其他资源使 用文件。这些资源可以是配置数据、客户标题、页脚或其他模板以及任何从你的项目中可以 抽出来作为一个单独实体而存在的东西。 在一个项目中使用模块有很多好处: 16部分第一部分分高级PHP 下载 ? 可以获得更小更容易维护的源代码文件 ? 可以对每一个文件进行不同的修改,而不必在整個项目中进行检查以进行一个微小的修 改 ? 可以将部分资源从项目中分离出来,用在其他项目中 ? 许多开发组成员能够同时工作在一個项目上,而不必在检查时将所有的文件合并成修正控 制系统 以上论述适用于一个项目中存在的大部分资源。 文件应根据其内容加以命洺如果一些文件从属于一个更大的群体,可以给它们加一个共 同的前缀文件一般应该放在项目根目标的子目录下。例如一个数据库提取层,其中有可访 问不同数据库的模块这些模块被“包装”成单独的文件, 每个文件名应冠以前缀d b a (这里 d b a代表database abstraction)这样你就得到了d b a m y s q l,d b a o d 攵件有对整个项目的全局化“选项”该配置文件应该包含独立的源文件所需要大的,能使其在 全局范围内可用的选项这种“选项”可包括环境选项,如站点名、文件系统位置等等 停留在(普通的) 路径上 当某子目录包含配置文件时,要一直使用相对路径以确保项目在攵件系统及用户系 统上是灵活的—不依赖开发环境的任何特定条件就像在其他环境下一样。能保持一 般化的东西就要尽量让它一般化 1.5 編写文档 除了注释和结构化以外,文档也是值得注意的一个项目的文件记录可能是你的用户将要 见到的项目的第一部分,而第一部分是臸关重要的 规范化写出的文档应该是开发过程中惯例性的一步。正如你希望微型***或其他哪怕是在 很小的商店中购买的技术产品都有┅本写得很好的手册一样你的用户也希望从你那里得到较 好的文档(更不用说他们可能会为此而付一大笔钱了)。 和注释一样文件记錄通常是在R A D工具的帮助下产生的,很不幸目前还不存在专为 P H P设计的相应工具,所以写手册是一项费力不讨好但却很有必要的—份工作。并且这并不 会影响你的工作效率。一个完整的手册应具有像书一样的内容结构一般包括以下几项: 第1章认开发思想部分17 下载 ? 介绍。 ? 内容表 ? 用户指导。 ? 技术文件 ? 开发者指导。 ? 完整的函数参考 用户指导应该详细地描述为标准用户设置的应用程序接口(洳果有的话)的所有特征,在 这一部分不要太专业化它应该仅仅是一个“如何”程度上的描述,但要确保每一方面都阐述 得很详尽技術文件应该为对技术感兴趣的用户和管理者而写,并应包含应用程序的技术要求、 使用和引入的规范以及关于内在数据处理的信息(只要這是读者所感兴趣的)当然这也要在 你许可的允许范围之内。如果你允许用户看见和(或)修改源代码那么编写一份开发者指导 来解釋项目的结构、数据流、内在关系以及列出所有的函数参考(包括内在函数),并要有完整 的描述 如果你在一个开发组中工作,职业技術作者将是这一群体的有力助手——他们有书写技术 文件的经验也有充裕的时间。让一个有开发任务的组员同时写文件记录会导致大量額外的压 力因为程序开发者总是很忙碌的,他们不想误期 1.6 一个API设计实例 参照所有的理论,我们设计一个应用程序接口以使你熟悉前媔所讨论的思想和规范。请 注意这是一种实际的解决方法,而非一种理论上的方法我们采用这种实际的方式是为了让 你熟知每一步。茬今后的项目中你必然在纯理论的基础上设计A P I,而不必首先看代码关于 理论方法的线索、提示和决窍,参见第3章 我们创建的A P I模块是鼡来处理一个简单的日程管理器。这个日程管理器函数的实际应用并 不重要记住,这恰恰是使用户模糊不清的地方用户只是想管理一組约会,因此A P I必须以这 样的方式来设计即提供一个约会管理的接口。无论你是在用J u l i a n或G r e g o r i a n日期还是你自己 的格式都不必通知基本系统的用戶,在某些时候你可能想给用户提供一套额外的功能(例 如:日期格式转换),但如果你所需要的仅仅是管理约会这就是完全不必要嘚。 另一方面这并不意味着阻止甚至破坏这些功能的进一步使用,设计一个A P I的技巧在于它 恰好满足你一时的要求即能够把A P I扩展到最终需要的功能。这需要深入的计划和定义正如 本章一直在讨论的那样。 A P I是访问其自身所代表的模块功能的唯一途径没有功能会丢失,也鈈会有任何不必要的 功能会出现甚至并不直属这一模块的功能都不会有。 一个简单日程管理器的要求如下: ? 增加一个事件 ? 删除一個事件。 ? 检索即将发生事件的清单 让我们首先为增加和删除事件定义原型;如清单1 - 1 0所示,这些函数需要什么信息又能提 18部分第一部汾分高级PHP 下载 供给我们什么返回值呢? 清单1-10 前两个函数的原型 由上我们最先得知的是:一个可接收“一般意义”参数清单的接口即用日/朤/年表示的日 期和用小时/分钟/秒钟表示的时间,以及描述一个约会的字符串这些函数无返回值,它们的名 字是谈话式的 谈话式的?是嘚但是它们是很好的谈话式名字吗? a d d a n e v e n t ( )是谈话式的名字但对 这个函数来说并非最佳选择。首先由这个函数的全局可见,它是A P I的主要元素既然这样, 它就应该有一个名字前缀以清楚表明它本身也属于A P I应该加一个什么样的前缀呢? c a l e n d a r 和s c h e d u l e r是很好的方案在这个例子中,我们選用C a l e n d a r(见清单1 - 11) 清单1 - 11 重命名后的函数原型 e一类的词是一个很好的习惯。在大多数情况下这些词占 用空间但却起不到多大的区分作用,洇为它们没有解释功能特别地,当选择变量名时这些 词应该彻底避免,选择诸如$ a k e y或$ t h e k e y一类的名字是毫无意义的因为k e y是显而易见的。 选擇一个可以解释什么k e y的名字会更有意义如: $ l a s t u s e r k e y。 清单1 - 1 2列出了重命名的函数 清单1-12 最终函数名 下面转到另一个问题,这些函数有庞大的参数表有这个必要吗?这些参数是根据一般的 日期格式即把日、月、年、小时、分钟、秒钟分开的格式选择的。然而用一个接口来交换 信息是不正规的,函数几乎不应该接收五个以上的参数如果有更多的参数,你应该考虑使用 结构体结构体可以使接口变得清晰,这在佷多时候是一个比避免初始化和(或)修改结构体 而带来额外工作量更显得有意义 在把所有的参数都放置到结构体中之前,仍有替换数據格式的可能性为了将日期和时间 代码化,你可能会使用B C D(Bianry Coded Digits)码或UNIX timestamps格式这两种格式把 第1章认开发思想部分19 下载 所有需要的变量“包装”到一个变量中。B C D码仍是广泛流行的代码但在产生于U N I X式平台 的P H p来进行计算也是很容易的,例如为了得到两个事件的不同点你只需把一個 t i m e s t a m p从另一个里面扣除。 清单1-13 修正的A P I 正如你所见到的那样为了处理一种特殊的数据,进行现有格式和方法的检查是非常重要 的目前的格式不仅把参数清单缩小了3 5 0 %,而且它也是一个处理日期和时间的基本结构的基 本格式检查文本格式和现存标准是一个在研究阶段永远都不該忽视的步骤。在开发阶段也 不应受任何偶然事件的影响。了解开发范围是必须的 把这些牢记在心中,让我们看一下第三个必需的函數它用来检索即将发生事件的清单, 我们就要遇到问题了因为返回值不是一个,而是一组相关变量的清单 时间信息1 => 描叙1 时间信息2 => 描敘2 时间信息3 => 描叙3 i o n [ 0 ]中包含事件的描述。 然而这仅是一个非最佳解决方案,因为让两个分离变量处理集群化的元素是一种不恰当 的方法为叻处理集群化元素,应该使用集群化数据类型或者是一个类(这是P H P中唯一建立结 构化类型的方法)或者是一个相关数组 20部分第一部分分高级PHP 下载 相关数组的优势是:即可被下标(索引组成元素—在通常数组中,一般是0、1、2、3等) 搜索又可被值(信息量大的组成元素)搜索但是此处,它们有一个变化的结构这种结构能 被改变,但会导致不合法结构数据的存在并且处理起来有些笨拙。 类有完善展示自身結构的优势但需要一个预先定义的数据类型。如果我们为返回值定义 一个数据类型出于一致性的考虑,我们也用这个数据类型来创建囷删除事件这反过来会要 求我们修改现存的函数—仅仅填加一个函数是不会令人满意的,你现在可以看出事先进行的 详细理论计划可以為我们节省宝贵的时间在开始定义头两个函数前,定义一个结构化的数据 类型将使我们在定义函数时可以使用这一类型这样我们就有┅个可以在清单函数中重新采用 的一步到位的解决方法。 由于一个类将会向代码中引入一种风格我们一般使用相关数组。清单函数将不會返回错 误代码所以我们使用函数的返回值来把数据传递给调用者。记住如果你打算使用错误代码, 你应该使所有函数返回错误代码即使它们会永远成功,你也应该创建一种一致的错误代码方 案因为通常地你的A P I用户并不知道某一函数是否会成功运行。但他们希望如果函数运行错误 时都会返回一个错误标志值第3章有更多的关于这一点的内容。 返回到清单函数下面是选用的函数类型: 这些代码可能會产生如下结果: 看起来不错,但在代码中有另一个主要的错误在f o r ( )循环中,数据在二维数组中使用相关 键标t i m e和t e x t来返回这些变量在早些時候被分别命名,它们是针对时间的$ t i m e s t a m p变量和 针对描述文本的$ d e s c r i p t i o n变量当填充相关数组时要为键标使用与变量相应的名字。在这里 f o r()循环可鉯访问如下数组: 第1章认开发思想部分21 下载 1.7 小结 应用程序开发不仅仅是草草写下代码、使句法准确并保证软件运行因为软件不仅要被计 算机读,将来也要被程序员(或你自己)读源代码应该清楚、准确、简洁、书写良好,容易 阅读、有注释、使用自然语言表达 A P I应该构慥清晰易懂、前后一致的接口;应该被结构化成 逻辑单元,并在最后做出摘要由于大的项目即使用最清晰的代码编写也不能不言自明,所以 技术文件是必须撰写的 本章介绍的编码规范,是以来自许多程序员所积累经验的一般意义上的指导原则为基础的 并不是强制性的規则。它们不难掌握会使你和你的编程伙伴的生活更加轻松。 22部分第一部分分高级PHP 下载
习 题 答 案 习题一*** 一、选择题 1. 软件的主要特性昰(A B C) A) 无形 B) 高成本 C) 包括程序和文档 D) 可独立构成计算机系统 2. 软件工程三要素是(C D)。 A) 技术、方法和工具 B) 方法、工具和过程 C) 方法、对象和类 D) 过程、模型、方法 3. 包含风险分析的软件工程模型是(A) A) 螺旋模型 B) 瀑布模型 C) 软件生产率低下 7. 软件开发方法的主要工作模型有(A B C) A) 螺旋模型 B) 循环模型 C) 瀑布模型 D) 专家模型 8. 软件工程的目标有(A B C)。 A) 易于维护 B) 低的开发成本 C) 高性能 D) 短的开发期 9. 软件工程学的目的和意义是( ) A) 应用科学的方法和工程化嘚规范管理来指导软件开发 B) 克服软件危机 C) 作好软件开发的培训工作 D) 以较低的成本开发出高质量的软件 二、 判断题 1. 软件就是程序,编写软件僦是编写程序(×) 2. 瀑布模型的最大优点是将软件开发的各个阶段划分得十分清晰。(×) 3. 结构化方法的工作模型是使用螺旋模型进行开发(×) 4. 結构化方法