高级语言讲课第28次课c2ch_第1页
高级语言讲课第28次课c2ch_第2页
高级语言讲课第28次课c2ch_第3页
高级语言讲课第28次课c2ch_第4页
高级语言讲课第28次课c2ch_第5页
已阅读5页,还剩81页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第十二章第十二章 程序开发程序开发n自顶向下、逐步求精自顶向下、逐步求精n结构化程序设计原则结构化程序设计原则n程序风格程序风格n穷举与试探穷举与试探作业作业: 12.8 编程序并不难,只要有算法,会程序设计语言,任何人都编程序并不难,只要有算法,会程序设计语言,任何人都可以编出程序,但是不同人编出的程序却大不相同。针对同一可以编出程序,但是不同人编出的程序却大不相同。针对同一个问题个问题: 有人编的程序风格好、易读、易维护、易重用、可靠性高、有人编的程序风格好、易读、易维护、易重用、可靠性高、运行得既快又节省存储空间;运行得既快又节省存储空间; 有人编的程序风格差、晦涩难懂、难于维护、冗长、

2、正确有人编的程序风格差、晦涩难懂、难于维护、冗长、正确性和可靠性极低、运行起来既慢又占用空间。性和可靠性极低、运行起来既慢又占用空间。编程序易,编好程序难编程序易,编好程序难 要想编出一个风格优美、正确可靠、各方面均优秀的好程要想编出一个风格优美、正确可靠、各方面均优秀的好程序,必须按照现代软件工程的规范进行。同时也必须遵循好的序,必须按照现代软件工程的规范进行。同时也必须遵循好的程序设计原则和使用好的程序设计方法。程序设计原则和使用好的程序设计方法。 本章介绍程序开发、结构化程序设计。本章介绍程序开发、结构化程序设计。12.1 求玉米单产求玉米单产自顶向下、逐步求精自顶向下、逐步求精 【例例

3、12.1】如图所示,现有一个近似四边形的地块位于如图所示,现有一个近似四边形的地块位于南北方向路东侧,东西方向路北侧。其一个顶点距离南北方南北方向路东侧,东西方向路北侧。其一个顶点距离南北方向路向路547米,距离东西方向路米,距离东西方向路411米;另一个顶点距离南北米;另一个顶点距离南北方向路方向路804米,距离东西方向路米,距离东西方向路77米;第三个顶点距离南北米;第三个顶点距离南北方向路方向路39米,距离东西方向路米,距离东西方向路208米;第四个顶点距离南北米;第四个顶点距离南北方向路方向路116米,距离东西方向路米,距离东西方向路332米。该地块去年种植玉米。该地块去年种植玉米,已

4、知总产量米,已知总产量130吨,求玉米每亩产多少公斤。吨,求玉米每亩产多少公斤。C2083911677ABD547411332804北北东东 Y X计算该地块面积计算该地块面积折合成亩折合成亩计算单位产量计算单位产量开始开始结束结束该问题可以描述为:该问题可以描述为:求精求精“求总面积求总面积”: 连接连接B、D,构成两个三角形,构成两个三角形ABD和和BCD,然后分别计,然后分别计算两个三角形面积并相加,得算两个三角形面积并相加,得PAD。 C2083911677ABD547411332804北北东东 Y X计算三角形计算三角形ABD的面积,设为的面积,设为S1计算三角形计算三角形BCD的面

5、积,设为的面积,设为S2总面积总面积 = s1+s2计算总面积计算总面积area开始开始结束结束 计算三角形计算三角形ABD、BCD的面积的算法一样的,可以写的面积的算法一样的,可以写一个函数一个函数areaTtriangle,分别调用,分别调用areaTtriangle函数。函数。 求精求精 areaTtriangle: 计算三角形面积有很多方法,选择一种合适的即可。根计算三角形面积有很多方法,选择一种合适的即可。根据本问题的条件,可以选择海伦公式:据本问题的条件,可以选择海伦公式:得计算三角形面积得计算三角形面积areaTtriangle的的 PAD ) c)(b)(a( ssssS 2c

6、ba s其中:其中: S 为三角形面积为三角形面积 a、b、c 分别为三条边长分别为三条边长求第一条边长度求第一条边长度求第二条边长度求第二条边长度求第三条边长度求第三条边长度计算三角形面积计算三角形面积areaTtriangle计算计算s计算计算S开始开始结束结束求精该图:求精该图: 计算计算s和和S都只是数学公式计算,不用求精;都只是数学公式计算,不用求精; 求各条边长度的算法是一样的,数学上有两点间求各条边长度的算法是一样的,数学上有两点间距离公式,可以写一个函数距离公式,可以写一个函数away,求精成右图,求精成右图 求两点间距离求两点间距离away(x1,y1,x2,y2)结束结束r

7、eturn sqrt(x2-x1)2+(y2-y1)2) 至此已经把解决该问题的各个步骤分析清楚。通过自顶向下的逐至此已经把解决该问题的各个步骤分析清楚。通过自顶向下的逐步求精,找到了问题求解算法。按得到的步求精,找到了问题求解算法。按得到的PAD编出程序如下:编出程序如下: / /* * 计算四边形面积,参数:四个顶点计算四边形面积,参数:四个顶点x x、y y坐标坐标 * */ /float area( float xa ,float ya ,float xb ,float yb ,float xc ,float yc ,float xd ,float yd ) float s1,s2;/

8、 / 计算用变量;计算用变量; / ABD/ ABD面积面积 s1 = tareaTtriangle (xa, ya, xb, yb, xd, yd ); / BCD / BCD面积面积 s2 = tareaTtriangle (xb, yb, xc, yc, xd, yd ); return s1+s2; / / 返回面积返回面积/ /* * 计算三角形计算三角形uvwuvw面积,参数:面积,参数:u u、v v、w w三点的三点的x x、y y坐标坐标 * */ /floa tareaTtriangle ( float xu,float yu ,float xv,float yv ,flo

9、at xw,float yw )float uv , uw , vw ;/ / 三条边长三条边长float s ;uv = away ( xu, yu, xv, yv ); /边边uvuv长长uw = away ( xu, yu, xw, yw );/边边uwuw长长vw = away ( xv, yv, xw, yw );/边边vwvw长长s=(uv+uw+vw)/2;/s/sreturn sqrt( s*(s-uv)*(s-uw)*(s-vw) );/ 返回面积返回面积/* areauvw */ / /* * 计算计算r r、s s两点距离:参数:两点的两点距离:参数:两点的x x、y y

10、坐标坐标 * */ /float away(float xr,float yr,float xs,float ys)return sqrt( (xr-xs)*(xr-xs)+(yr-ys)*(yr-ys) );/* away */例例12.1和本书所有稍微复杂点的例题,全和本书所有稍微复杂点的例题,全部都是使用部都是使用“自顶向下、逐步求精自顶向下、逐步求精”的方法开发的方法开发的。的。“自顶向下、逐步求精自顶向下、逐步求精”的程序设计技术是的程序设计技术是目前较为时髦的(当然也是较为合理的)找出一目前较为时髦的(当然也是较为合理的)找出一个问题的解题算法的一种思维方法。该技术的基个问题的解题

11、算法的一种思维方法。该技术的基本思想在第五章已经初步介绍过。本思想在第五章已经初步介绍过。 “自顶向下、逐步求精自顶向下、逐步求精”过程中的每一步,分解过程中的每一步,分解某一具体问题时,主要用到如下四种求精技术:某一具体问题时,主要用到如下四种求精技术: 1. 顺序连接的求精顺序连接的求精 2. 分支、选择的求精分支、选择的求精 3. 循环的求精循环的求精 4. 递归的求精递归的求精“自顶向下,逐步求精自顶向下,逐步求精”的分析技术实质上是上图所示过程的反复。的分析技术实质上是上图所示过程的反复。 求解一个问题求解一个问题粗略的解决方案粗略的解决方案细细 化化第一步子问题第一步子问题第二步子

12、问题第二步子问题第第n步子问题步子问题.前处理前处理 结束条件结束条件后处理后处理进进展展一一步步前处理前处理后处理后处理条条件件处理处理1处理处理2处理处理n. .条件条件2条件条件n 条件条件1前处理前处理后处理后处理递归递归条件条件递归递归顺序顺序 连接连接循环循环 分支分支 选择选择 递归递归 当问题的子解具有前后关系时,采用第一种顺序连接的求精当问题的子解具有前后关系时,采用第一种顺序连接的求精技术,将问题分解成互不相交的几个子问题的顺序执行。技术,将问题分解成互不相交的几个子问题的顺序执行。 当问题是分别不同情况而应该进行不同处理时,采用分支、选择当问题是分别不同情况而应该进行不同

13、处理时,采用分支、选择的求精技术,构造分支。这时要注意分支的条件一定要正确。的求精技术,构造分支。这时要注意分支的条件一定要正确。当问题的子解具有特性:如果有向解的方向前进一步的方法,且当问题的子解具有特性:如果有向解的方向前进一步的方法,且不断重复该步骤,即能解决问题,最终达到完全解。则应该采用不断重复该步骤,即能解决问题,最终达到完全解。则应该采用循环的求精技术(构造循环)。这时一定要弄清循环的初始条件、循环的求精技术(构造循环)。这时一定要弄清循环的初始条件、结束条件和有限进展的一步都是什么。结束条件和有限进展的一步都是什么。 当问题的某步解法与前边高层次的某步解法具有相同性质,只是当问

14、题的某步解法与前边高层次的某步解法具有相同性质,只是某些参数不同时,可采用递归的求精技术。这时应注意递归的参数某些参数不同时,可采用递归的求精技术。这时应注意递归的参数变化规律以及递归出口。变化规律以及递归出口。 “自顶向下、逐步求精自顶向下、逐步求精”是一种思维方式,它不是计算机程是一种思维方式,它不是计算机程序员独有的。事实上在日常生活、工作中也经常的使用该技术,序员独有的。事实上在日常生活、工作中也经常的使用该技术,只不过不自觉或没意识到罢了。只不过不自觉或没意识到罢了。 例如写一本书、或文章,总要作一个提纲,全书分成几章;例如写一本书、或文章,总要作一个提纲,全书分成几章;然后对每一章

15、又列出本章分几节;对每一节又分出几小节等等;然后对每一章又列出本章分几节;对每一节又分出几小节等等;最后再具体着手写每个小节。最后再具体着手写每个小节。 又如,设计生产某产品的一个工厂(比如汽车厂):首先又如,设计生产某产品的一个工厂(比如汽车厂):首先应考虑全厂应该分成几个车间(例如,生产发动机的发动机车应考虑全厂应该分成几个车间(例如,生产发动机的发动机车间、生产底盘的底盘车间、生产车轮的车轮车间、总装车间、生产底盘的底盘车间、生产车轮的车轮车间、总装车间、间、.);然后再考虑每个车间应分成几个工段(例如,发动);然后再考虑每个车间应分成几个工段(例如,发动机车间应分成生产机壳的机壳工段、

16、生产活塞的活塞工段、负机车间应分成生产机壳的机壳工段、生产活塞的活塞工段、负责工件热处理的热处理工段、责工件热处理的热处理工段、.);然后再考虑每个工段应该);然后再考虑每个工段应该配备多少种设备,每种设备应配备多少台,配备多少种设备,每种设备应配备多少台,. 等等。等等。 这就是自顶向下、逐步求精。这就是自顶向下、逐步求精。 采用自顶向下、逐步求精方法构造程序有如下优点采用自顶向下、逐步求精方法构造程序有如下优点: 1. 程序的层次分明、结构清晰。程序的层次分明、结构清晰。 2. 便于集体开发程序。对于大型程序来讲,可以每组便于集体开发程序。对于大型程序来讲,可以每组负责一个模块(一个子部分

17、),在一个组内又可以每个人负负责一个模块(一个子部分),在一个组内又可以每个人负责一个子模块(更小的子部分)等等。而各个模块之间以及责一个子模块(更小的子部分)等等。而各个模块之间以及各个子模块之间相对独立,互相之间没有制约,各个模块的各个子模块之间相对独立,互相之间没有制约,各个模块的负责人员可以独立的进行各自的程序设计。负责人员可以独立的进行各自的程序设计。 3. 便于调试。若程序有错误,可以很容易的将错误局便于调试。若程序有错误,可以很容易的将错误局部于某一子部分,找出错误,同时每一部分的错误是独立的,部于某一子部分,找出错误,同时每一部分的错误是独立的,也不至于影响其它的部分。也不至于

18、影响其它的部分。12.2 结构化程序设计原则结构化程序设计原则 由于计算机硬件技术的不断发展,以及计算机的广泛应由于计算机硬件技术的不断发展,以及计算机的广泛应用,计算机软件系统也日益发展,并且软件在计算机系统中所用,计算机软件系统也日益发展,并且软件在计算机系统中所占比重也越来越大,使得作为软件主要组成部分的程序系统越占比重也越来越大,使得作为软件主要组成部分的程序系统越来越庞大,复杂度越来越高,造价也越来越昂贵,同时出错率来越庞大,复杂度越来越高,造价也越来越昂贵,同时出错率也不断增加,系统的可靠性越来越难以保证,维护也越来越困也不断增加,系统的可靠性越来越难以保证,维护也越来越困难。最后

19、终于在难。最后终于在20世纪世纪60年代中期引起了一场所谓的软件危机。年代中期引起了一场所谓的软件危机。在该背景下,在该背景下,1968 年年 Dijkstra 提出了结构化程序设计思想。提出了结构化程序设计思想。这种思想的基点是:这种思想的基点是:“清晰,易懂地书写程序逻辑,使程序结构表现得简单、明快清晰,易懂地书写程序逻辑,使程序结构表现得简单、明快” 从这点出发,人们经过艰苦实践,总结出了一套结构化程从这点出发,人们经过艰苦实践,总结出了一套结构化程序设计原则。这套原则要求程序员写出的程序应该是结构良好序设计原则。这套原则要求程序员写出的程序应该是结构良好的,即的,即: 1. 易于保证和

20、验证程序的正确性易于保证和验证程序的正确性 2. 易于阅读、维护和调试。易于阅读、维护和调试。这种良好结构的程序具体体现在:对任意程序段来讲这种良好结构的程序具体体现在:对任意程序段来讲 1. 仅有一个入口,一个出口仅有一个入口,一个出口 2. 没有死循环没有死循环 3. 没有死码区。没有死码区。为了达到上述目的,强调程序员在写程序时应该为了达到上述目的,强调程序员在写程序时应该: 1. 利用自顶向下、逐步求精的技术设计程序利用自顶向下、逐步求精的技术设计程序 2. 具有良好的程序设计风格具有良好的程序设计风格 3. 尽量利用标准的顺序、分支、重复控制结构。保证程尽量利用标准的顺序、分支、重复

21、控制结构。保证程序仅有一个入口、一个出口。序仅有一个入口、一个出口。 4. 限制使用限制使用 GOTO 语句。可能一个坏程序的缺点都是由语句。可能一个坏程序的缺点都是由 GOTO 语句引起的。语句引起的。 结构化程序设计的发展,使程序设计从技艺走向工程,为软件工程学发结构化程序设计的发展,使程序设计从技艺走向工程,为软件工程学发展奠定了有力基础。使软件生产由个体作坊式的艺术创作方式发展成为千千展奠定了有力基础。使软件生产由个体作坊式的艺术创作方式发展成为千千万万人参加的工程方式,达到了万万人参加的工程方式,达到了“系列化、产品化系列化、产品化 、工程化、工程化 、标准化、标准化”。“软件工程软

22、件工程”也从这一时期开始逐步发展起来。也从这一时期开始逐步发展起来。 能够反映结构化程序设计要求,便于书写结构化程序的程序设计语言,能够反映结构化程序设计要求,便于书写结构化程序的程序设计语言,称结构化程序设计语言。可以认为称结构化程序设计语言。可以认为C是结构化程序设计语言。是结构化程序设计语言。 结构化程序设计方法是结构化程序设计方法是20世纪世纪60年代末年代末70年代初逐渐发展起来的,目年代初逐渐发展起来的,目前程序设计领域的热点是前程序设计领域的热点是“面向对象程序设计面向对象程序设计”和和“基于构件的程序设计基于构件的程序设计”等。但是它们的主要特长在于程序的组织、信息封装、软件重

23、用等,而最终等。但是它们的主要特长在于程序的组织、信息封装、软件重用等,而最终对于足够小程序模块的编码,它们没有给人们带来益处。对于足够小程序模块的编码,它们没有给人们带来益处。 结构化程序设计方法针对每个小模块的设计起着十分关键的作用。所以结构化程序设计方法针对每个小模块的设计起着十分关键的作用。所以尽管目前面向对象程序设计技术和基于构件的程序开发技术受到人们广泛关尽管目前面向对象程序设计技术和基于构件的程序开发技术受到人们广泛关注与重视,但是结构化程序设计技术仍然是十分重要和不可缺少的。可以说注与重视,但是结构化程序设计技术仍然是十分重要和不可缺少的。可以说结构化程序设计是一切程序设计技术

24、的基础,是任何软件工作者必须掌握的结构化程序设计是一切程序设计技术的基础,是任何软件工作者必须掌握的技术。技术。本书的目标是讲授程序设计基础,主要介绍结构化程序设计技术本书的目标是讲授程序设计基础,主要介绍结构化程序设计技术 12.3 程序风格程序风格 程序风格是指程序的书写格式等与易读性、清晰性、互相交流有关的,程序风格是指程序的书写格式等与易读性、清晰性、互相交流有关的,而与程序执行无关或关系不大的一些的问题。而与程序执行无关或关系不大的一些的问题。写程序不仅仅是为了与计算机进行交流,而且也是为了与人进行交流,写程序不仅仅是为了与计算机进行交流,而且也是为了与人进行交流,进一步还为了给自己

25、或别人阅读,同时程序员自己也需要不断地查阅自己编进一步还为了给自己或别人阅读,同时程序员自己也需要不断地查阅自己编出的程序,更何况程序的维护很可能由别人来做。出的程序,更何况程序的维护很可能由别人来做。 在写程序时要考虑到:程序既是为了在计算机上运行,也是为了今后的在写程序时要考虑到:程序既是为了在计算机上运行,也是为了今后的交流和阅读,同时还是为了留下有用的参考文档。交流和阅读,同时还是为了留下有用的参考文档。 为此,程序必须是宜于阅读的,也就是必须是结构良好或风格优美的。为此,程序必须是宜于阅读的,也就是必须是结构良好或风格优美的。 程序设计风格不好不利于产生正确、高效、易读、易维护的程序

26、。风格程序设计风格不好不利于产生正确、高效、易读、易维护的程序。风格不好的程序会使程序维护费用与时间增加,甚至导致整个编程过程失败。不好的程序会使程序维护费用与时间增加,甚至导致整个编程过程失败。 程序设计风格是程序员必须的修养。良好的程序设计风格是程序员在长程序设计风格是程序员必须的修养。良好的程序设计风格是程序员在长期的编程实践中逐步发展,积累和提炼出来的。它是产生正确、高效、易读、期的编程实践中逐步发展,积累和提炼出来的。它是产生正确、高效、易读、易维护程序的一种重要的手段。易维护程序的一种重要的手段。 程序风格主要涉及程序的行文格式、注释和空白的合适用法、尽量使用合适的程序风格主要涉及

27、程序的行文格式、注释和空白的合适用法、尽量使用合适的助记名来命名标识符、明白地表示出程序结构和数据结构等。助记名来命名标识符、明白地表示出程序结构和数据结构等。 关于程序风格没有一个确定的统一标准。关于程序风格没有一个确定的统一标准。 很多组织,尤其是西方一些大的计算机公司都建立他们很多组织,尤其是西方一些大的计算机公司都建立他们自己的一些标准,并要求他们的程序员遵守和使用。自己的一些标准,并要求他们的程序员遵守和使用。 同时也有不少个人发表他们自己的标准,希望别人仿效。同时也有不少个人发表他们自己的标准,希望别人仿效。 如果程序员能养成良好的程序设计风格,大家按统一的如果程序员能养成良好的程

28、序设计风格,大家按统一的标准进行程序设计和书写程序,则有助于彼此交流,有助于标准进行程序设计和书写程序,则有助于彼此交流,有助于别人理解他们所编写的程序。别人理解他们所编写的程序。 我们对程序设计风格也提出一个建议,希望能给读者一我们对程序设计风格也提出一个建议,希望能给读者一个有益的提示和帮助。个有益的提示和帮助。 12.3.1 行文格式行文格式n程序的行文格式不好直接影响程序的可读性、清晰性和外观。程序的行文格式不好直接影响程序的可读性、清晰性和外观。/* A */ #include int i;main ()i=25+38;printf(“25+38=%d”,i);/* B */ #in

29、clude int i;main () i = 25+38; printf ( “25+38=%d” , i );/* C */ #include int i; /* 声明整型变量声明整型变量i */ int main (void) /* 主函数主函数 */ i = 25+38; /* 求和运算求和运算 */ printf ( “25+38=%d” , i ); /* 打印打印 */ 下面给出下面给出“适当使用空行、空格适当使用空行、空格”的建议的建议: if ( b ) S1 else S2 switch ( expr ) case a1: S1 case a2: S2 . case an:

30、 sn /* switch */ 图图1 函数定义函数定义 图图2 IF语句语句 图图3 SWITCH语句语句 int main ( ) DS DS . /* main */ do S while (b) for(expr1;expr2;expe3) S /* for */ while ( b ) S /* while */ 图图4 WHILE语句语句 图图5 FOR语句语句 图图6 DO语句语句12.3.2 标识符标识符 标识符是程序员给自己引进的常量、类型、变量、函数等标识符是程序员给自己引进的常量、类型、变量、函数等起的名字。程序设计语言对如何命名标识符没有限制,标识符起的名字。程序设计

31、语言对如何命名标识符没有限制,标识符也没有固定的含义。但是从使用角度看,标识符表记的每个对也没有固定的含义。但是从使用角度看,标识符表记的每个对象都有具体的含义。为了提高可读性和有助于记忆,应该使标象都有具体的含义。为了提高可读性和有助于记忆,应该使标识符在拼写上尽量和它所标记对象的物理、数学等含义相一致,识符在拼写上尽量和它所标记对象的物理、数学等含义相一致,并且要避免与系统预定义的标准标识符重名。例如,并且要避免与系统预定义的标准标识符重名。例如,n表示圆周率表示圆周率 用用 pai 就比用一个一般的就比用一个一般的 a 要好;要好;n表示面积用表示面积用 area 就比用就比用 s 要好

32、;要好;n表示长度用表示长度用 length 就比用就比用 l 要好;要好; . 9.3.3 注释注释 注释是间隔符的一种,在程序中的作用相当于一个空格。注释注释是间隔符的一种,在程序中的作用相当于一个空格。注释的存在不影响程序的意义,但是它有助于人们阅读和理解程序的存在不影响程序的意义,但是它有助于人们阅读和理解程序, 使使原来模糊的、意义不清的部分变得清晰明了。因此,在程序中适当原来模糊的、意义不清的部分变得清晰明了。因此,在程序中适当加入注释是一个好的程序设计习惯。但是也不要在不需要加注释、加入注释是一个好的程序设计习惯。但是也不要在不需要加注释、意义十分明显的地方加注释。究竟应该在程序

33、的什么地方加注释,意义十分明显的地方加注释。究竟应该在程序的什么地方加注释,以及注释应该如何来写,并没有一个统一的标准,这里也只是提一以及注释应该如何来写,并没有一个统一的标准,这里也只是提一些建议。通常些建议。通常: 1. 所有程序都应该从注释开始所有程序都应该从注释开始 2. 所有函数也都应该从注释开始所有函数也都应该从注释开始 3. 也可以对一个程序段、一个语句、一个声明等加注释,以注也可以对一个程序段、一个语句、一个声明等加注释,以注明某程序段的功能、一个语句的作用、一个常量或变量的意义等。明某程序段的功能、一个语句的作用、一个常量或变量的意义等。 当修改有注释的程序时,若程序内容被修

34、改,则相应当修改有注释的程序时,若程序内容被修改,则相应的注释也必须作修改。错误的注释往往比没有注释效果更的注释也必须作修改。错误的注释往往比没有注释效果更坏。坏。9.3.4 关于程序的关于程序的“说明和定义说明和定义” 常量:常量:一般的,程序中使用的全部常量都要引进一个常一般的,程序中使用的全部常量都要引进一个常量标识符,在程序中不应该出现除了量标识符,在程序中不应该出现除了0、1等极其简单的常量等极其简单的常量以外的其它字面常量。并且常量应该是全程的。在程序一开以外的其它字面常量。并且常量应该是全程的。在程序一开始就定义本程序使用的全部常量,并加注释标明每个常量的始就定义本程序使用的全部

35、常量,并加注释标明每个常量的意义、使用位置等。而在每个函数中一般不应该再包含常量意义、使用位置等。而在每个函数中一般不应该再包含常量定义。定义。类型名:类型名:大多数情况下,类型名也应该是全程的。但是,大多数情况下,类型名也应该是全程的。但是,对类型的要求要比对常量宽,也可以把类型说明成局部的。对类型的要求要比对常量宽,也可以把类型说明成局部的。变量:变量:应该按照作用和用途来选择变量的说明位置,并应该按照作用和用途来选择变量的说明位置,并且应该尽量把变量说明成局部的。且应该尽量把变量说明成局部的。 函数:函数:函数一般应该只访问它的形式参数和局部量。如函数一般应该只访问它的形式参数和局部量。

36、如果必须访问全局量,应该加必要的注释。果必须访问全局量,应该加必要的注释。 【例例12.2】验证三角形内心定理:一个三角形三个角的验证三角形内心定理:一个三角形三个角的平分线交于一点,且该点是三角形内接圆的圆心,如图平分线交于一点,且该点是三角形内接圆的圆心,如图CBYXAdefWEFDPRQ* 12.4 程序设计实例程序设计实例 解:不失一般性,假设三角形的任意一条边都不平行于解:不失一般性,假设三角形的任意一条边都不平行于任意一个坐标轴。依据解析几何知识,该问题的验证步骤应任意一个坐标轴。依据解析几何知识,该问题的验证步骤应该是:该是:读入三点读入三点a,b,c的坐标的坐标(x1,y1)、

37、(x2,y2)、(x3,y3);检验三点是否构成一个三角形;检验三点是否构成一个三角形;若三点构成三角形,则验证内心定理若三点构成三角形,则验证内心定理 。开始开始验证内心定理验证内心定理结束结束是三角形是三角形读入三点读入三点A、B、C坐标坐标印印“不是三角形不是三角形” 读入三点坐标读入三点坐标只是一个读语句,只是一个读语句,不必求精。不必求精。 下边求精检验下边求精检验是否三角形和验证是否三角形和验证内心定理。内心定理。 检验三点是否构成三角形使用一个检验三点是否构成三角形使用一个bool型函数型函数isTriange ,可以求精成:,可以求精成: 求两点求两点A,B确定的直线方程确定的

38、直线方程AB ; 判断若判断若C在在AB上,上,则不构成三角形,则不构成三角形,isTriange 为为false ,否则否则 isTriange为为 true 。 求求A,B两点直线方程两点直线方程AB:y = a * x + bisTriange结束结束C在在AB上上return falsereturn true 判断判断C是否在是否在AB上只要把上只要把C带入直线方程即可,只是一带入直线方程即可,只是一个个bool表达式表达式 求精求两点间直线方程求精求两点间直线方程求两点间直线方程可以写一个函数求两点间直线方程可以写一个函数 line(x1,y1,x2,y2, *a,*b )并求精成下

39、图并求精成下图 。 line*b = y1- (*a)*x1结束结束*a = (y2-y1)/(x2-x1)x1,y1,x2,y2:两点坐标:两点坐标 *a, *b :直线方程系数:直线方程系数开始开始验证内心定理验证内心定理结束结束是三角形是三角形读入三点读入三点A、B、C坐标坐标印印“不是三角形不是三角形”至此,至此,“检验三点是否构成三角形检验三点是否构成三角形”部分完成部分完成下边求精验证内心定理下边求精验证内心定理验证内心定理可以如下进行:验证内心定理可以如下进行:l 求每个角的角平分线;求每个角的角平分线;l 验证该三条直线是否交于一点;验证该三条直线是否交于一点; 若该三条直线交

40、于一点,则验证该点到三角形各边距离是否相等若该三条直线交于一点,则验证该点到三角形各边距离是否相等 验证内心定理验证内心定理validateIncenter结束结束三条直线三条直线交于一点交于一点验证该点到三角形验证该点到三角形各边距离相等各边距离相等return false求角求角A的平分线的平分线 dBisector (ax,ay,bx,by, cx,cy,&da,&db)求角求角B的平分线的平分线 eBisector (bx,by,ax,ay,cx,cy,&ea,&eb)求角求角C的平分线的平分线 fBisector (cx,cy,ax,ay,bx,by,

41、&fa,&fb)求精求精“求角平分线函数求角平分线函数Bisector”。可以利用几何中可以利用几何中“三角形内角平分线定理三角形内角平分线定理”1.先求出角平分线与角对边交点,先求出角平分线与角对边交点,2.然后求角顶点与该交点的直线方程,然后求角顶点与该交点的直线方程,即为角平分线。以角即为角平分线。以角 A 为例为例 求角平分线求角平分线Bisector结束结束求角平分线求角平分线 AP 的方程:的方程:Y=aX+b求角求角 A 的平分线的平分线 d 与与 BC 边交点边交点 P 的的y 坐标坐标求角求角 A 的平分线的平分线 d 与与 BC 边交点边交点 P 的的x 坐

42、标坐标 以角以角 A 为例,按上述为例,按上述公式,公式,P点点 x、y 坐标也坐标也满足上述比例关系。即有满足上述比例关系。即有先求精先求精 “求角求角 A 的平分线的平分线 d 与与 BC 边的交点边的交点 P 的的 X、Y 坐标坐标”。由。由 “三角形内角平分线定理三角形内角平分线定理”,三角形一个角的,三角形一个角的角平分线分割对边与两相邻边成正比。如图三角形角平分线分割对边与两相邻边成正比。如图三角形ABC的的三个角三个角A、B、C的平分线分别交对边于的平分线分别交对边于P、Q、R,则分别,则分别有:有: CBYXAdefWEFDPRQCACBBCBAACABPCBPRABR QCA

43、Q yyxxxxyyBPBPABABPCACPCAC 可以通过该公式求得可以通过该公式求得P点坐标。定义一个点坐标。定义一个求求P点一个坐标的函数,然后两次分别调用该点一个坐标的函数,然后两次分别调用该函数,以分别求出函数,以分别求出P点点X、Y坐标。以坐标。以x坐标为坐标为例例 d xxxxBPA BPCA C整理后得整理后得 Px = ( Bx + d * Cx ) / (1+d)于是求坐标用下图描述:于是求坐标用下图描述:求求x(或(或y)坐标)坐标coordinate结束结束d=AB/ACreturn ( Bx+d*CX )/(1+d)求求AC长长求求AB长长 求精求精“求求AB长长”

44、和和“求求AC长长”,算法是一样的。可以定,算法是一样的。可以定义一个函数义一个函数away,分别调用该函数即可。,分别调用该函数即可。 已知两点坐标,求两点间距离只是一个计算公式,已知两点坐标,求两点间距离只是一个计算公式,away由下图描述。由下图描述。 求两点间距离求两点间距离away(x1,y1,x2,y2)结束结束return sqrt( (x2-x1)2+(y2-y1)2) 已知角顶点、角平分线与对边交点,计算角平分线。就已知角顶点、角平分线与对边交点,计算角平分线。就是是“已知两点,求过该两点的直线方程已知两点,求过该两点的直线方程”,可以调用函数,可以调用函数line 。 验证

45、内心定理验证内心定理validateIncenter结束结束三条直线三条直线交于一点交于一点验证该点到三角形验证该点到三角形各边距离相等各边距离相等return false求角求角A的平分线的平分线 dBisector (ax,ay,bx,by, cx,cy,&da,&db)求角求角B的平分线的平分线 eBisector (bx,by,ax,ay,cx,cy,&ea,&eb)求角求角C的平分线的平分线 fBisector (cx,cy,ax,ay,bx,by,&fa,&fb) 至此至此 “验证内心定理验证内心定理”的的 “求角平分线求角平分线”

46、部分求精结部分求精结束。束。 下边求精下边求精 “判断三直线是否交于一点判断三直线是否交于一点” 。 “判断三直线是否交判断三直线是否交于一点于一点”。可以先求两直。可以先求两直线交点线交点W,再判断另一直,再判断另一直线是否过该点。得线是否过该点。得 三条直线三条直线交于一点交于一点isOnePoint结束结束求两直线求两直线 d 与与 e 交点交点Wreturn truereturn falseW满足方程满足方程 f已知两直线方程,已知两直线方程,求交点就是解联立求交点就是解联立方程,只是两个计方程,只是两个计算公式,表现为算公式,表现为 求两直线交点求两直线交点pointOFinters

47、ectiony = a1*x+b1结束结束x = -(b1-b2)/ (a1-a2)W满足方程满足方程 f,就是一个,就是一个bool表达式表达式 wy = wx * fa +fb 即即 fabs(a3*(*x) +b3-y)eps ,不用求精,不用求精 验证内心定理验证内心定理validateIncenter结束结束三条直线三条直线交于一点交于一点验证该点到三角形验证该点到三角形各边距离相等各边距离相等return false求角求角A的平分线的平分线 dBisector (ax,ay,bx,by, cx,cy,&da,&db)求角求角B的平分线的平分线 eBisector

48、(bx,by,ax,ay,cx,cy,&ea,&eb)求角求角C的平分线的平分线 fBisector (cx,cy,ax,ay,bx,by,&fa,&fb) 至此至此“验证内心定理验证内心定理”的的 “三条直线交于一点三条直线交于一点” 部分求精结部分求精结束。束。 下边求精下边求精 “验证该点到三角形各边距离相等验证该点到三角形各边距离相等”。 “判断判断w点到三条边距离是否相等点到三条边距离是否相等”。应该分别求。应该分别求w到三到三条边距离条边距离wd、we、wf;然后判断是否;然后判断是否 wd=we=wf 距离相等?距离相等?validateDista

49、nce结束结束求求w到到BC边距离边距离wd求求w到到AB边距离边距离wf求求w到到AC边距离边距离we印印 O.Kwd=we=wf印印 false分别求分别求 wd、we、wf 可以设计一个可以设计一个 “求一点到一条直线距求一点到一条直线距离离”的函数的函数 distance,然后分别三次调用该,然后分别三次调用该distance函数。函数。而求一点到一条直线距离只是一个数学公式。设直线方程为:而求一点到一条直线距离只是一个数学公式。设直线方程为:Ax+By+C=0 点(点(x0、y0)到该直线的距离)到该直线的距离 D 为:为:2200BACYBXAD点到直线距离点到直线距离distan

50、ce结束结束return abs(A*x0+B*y0+C)/sqrt(A*A+B*B)函数函数distance描述成:描述成:验证内心定理验证内心定理validateIncenter结束结束三条直线三条直线交于一点交于一点验证该点到三角形验证该点到三角形各边距离相等各边距离相等return false求角求角A的平分线的平分线 dBisector (ax,ay,bx,by, cx,cy,&da,&db)求角求角B的平分线的平分线 eBisector (bx,by,ax,ay,cx,cy,&ea,&eb)求角求角C的平分线的平分线 fBisector (cx,cy

51、,ax,ay,bx,by,&fa,&fb) 至此至此 “验证内心定理验证内心定理”整个求精结束。整个求精结束。 开始开始验证内心定理验证内心定理结束结束是三角形是三角形读入三点读入三点A、B、C坐标坐标印印“不是三角形不是三角形” 全部问题也整个求精结束全部问题也整个求精结束/*PROGRAM test*/#include stdio.h#include math.h#include stdlib.h#define eps 1e-5 / 精度控制精度控制/* 函数原型部分函数原型部分 */bool isTriangle(float,float,float,float,float

52、,float); / 判断三点是否构成三角形判断三点是否构成三角形void line(float,float,float,float,float*,float*); / 求由两点所确定直线方程系数求由两点所确定直线方程系数y=a*x+bvoid validateIncenter(float,float,float,float,float,float);/ 验证内心定理验证内心定理void Bisector(float,float,float,float,float,float,float*,float*); / 求角平分线求角平分线float coordinate(float,float,fl

53、oat,float,float,float,float,float);/ 求角平分线与对边交点求角平分线与对边交点x、y坐标的一个坐标的一个float away(float ,float ,float ,float ); / 计算两点距离计算两点距离bool isOnePoint(float,float,float,float,float,float,float*,float*); /三条直线交于一点三条直线交于一点?计算交点坐标计算交点坐标void pointOFintersection(float,float,float,float,float*,float*); / 求两直线交点求两直线

54、交点wvoid validateDistance(float,float,float,float,float,float,float,float); /验证一点到三边距离是否相等验证一点到三边距离是否相等float distance(float ,float ,float ,float , float ,float ); / 计算点到直线距离计算点到直线距离编出程序如下编出程序如下 /*主程序主程序*/void main()float ax,ay,bx,by,cx,cy;/三点坐标三点坐标 /输入三角形三点坐标输入三角形三点坐标printf(please input coordinat of

55、point a:); scanf(%f%f,&ax,&ay);printf(please input coordinat of point b:);scanf(%f%f,&bx,&by);printf(please input coordinat of point c:);scanf(%f%f,&cx,&cy); if(isTriangle(ax,ay,bx,by,cx,cy)/ 判断是否三角形判断是否三角形 / 是三角形,则验证内心定理是三角形,则验证内心定理 validateIncenter(ax,ay,bx,by,cx,cy); else/

56、 不是三角形不是三角形 printf(false:the three points are on the same line!n);/* 图图12.3,判断三点是否构成三角形,判断三点是否构成三角形*/* 参数参数float x1,float y1,float x2,float y2,float x3,float y3 顶点坐标顶点坐标*/* 函数返回值为三点是否构成三角形标志函数返回值为三点是否构成三角形标志 */bool isTriangle(float x1,float y1,float x2,float y2,float x3,float y3) float a,b; line(x1,

57、y1,x2,y2,&a,&b);/第第1,2点连线的斜率和截距点连线的斜率和截距 if(fabs(a * x3 + b-y3)eps)/带入第带入第3点点,判断是否在同一直线判断是否在同一直线return false;/ 在直线上,则不是三角形在直线上,则不是三角形 elsereturn true;/ 不在直线上,则是三角形不在直线上,则是三角形/* 图图12.4,求由两点所确定直线方程系数,求由两点所确定直线方程系数y=a*x+b */* 参数参数float x1,float y1,float x2,float y2两点坐标;两点坐标;*/* 参数参数float *a,flo

58、at *b 指针类型,带回截斜式直线方程系数指针类型,带回截斜式直线方程系数 */void line(float x1,float y1,float x2,float y2,float *a,float *b) if (fabs(x1-x2)eps)/ 保障程序健壮性保障程序健壮性printf(直线平行于直线平行于Y轴:轴:(%f , %f)、(%f ,%f)n,x1,y1,x2,y2);exit(0); *a=(y1-y2)/(x1-x2); *b=y1-(*a)*x1;/* 图图12.5,验证内心定理,验证内心定理 */* 参数参数float ax,float ay ,float bx,f

59、loat by ,float cx,float cy 三个顶点坐标三个顶点坐标*/void validateIncenter(float ax,float ay ,float bx,float by ,float cx,float cy) float da,db,ea,eb,fa,fb;/ 角平分线角平分线 d、e、f系数系数 float wx,wy;/ 内心坐标内心坐标 bisector(ax,ay,bx,by,cx,cy,&da,&db);/ 求角求角A平分线平分线d bisector(bx,by,ax,ay,cx,cy,&ea,&eb); / 求角求角B平

60、分线平分线e bisector(cx,cy,ax,ay,bx,by,&fa,&fb); / 求角求角C平分线平分线f / 验证交于一点?并求内心验证交于一点?并求内心W if ( isOnePoint(da,db,ea,eb,fa,fb,&wx,&wy) ) / 交于一点!验证距离相等?交于一点!验证距离相等?validateDistance(ax,ay,bx,by,cx,cy,wx,wy); else / 不交于同一点不交于同一点printf(false: the three lines are not on the same point!);/* 图图12.6,求角平分线,求角平分线 */* 参数参数float rx,float ry是角顶点坐标是角顶点坐标 */* 参数参数float sx,float sy,float tx ,float ty分别是三角形另两点坐标分别是三角形另两点坐标*/* 参数参数float *a,float *b指

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论