| | 首页 | 文章中心 | 下载中心 | 本站特供 | 软硬件结合论坛 | | |
![]() | |
| 您现在的位置: 中国软硬件结合技术网 >> 文章中心 >> 软件技术 >> C++程序设计 >> 正文 |
|
|||||
| C程序的流程设计 | |||||
| 作者:佚名 文章来源: 点击数: 更新时间:2008-5-19 | |||||
| C程序的流程设计 目标:了解算法的概念、组成要素以及描述算法的几种方法;了解C语言语句的分类;熟练掌握if语句和switch语句的使用方法及其应用;熟练掌握while语句、do…while语句和for语句的使用方法及其应用;掌握break和continue语句的使用方法及其应用。 重点:if语句和switch语句的使用方法,while语句和for语句的使用方法,break和continue语句的使用方法。 难点:嵌套if语句的使用方法,while语句的使用方法,for语句的使用方法,break和continue语句的使用方法。 §3.1 算 法 计算机尽管可以完成许多极其复杂的工作,但是实质上这些工作都是按照人们事先编好的程序的规定进行的。随着计算机应用的日益广泛和深入,人们在研究和开发新的软、硬件技术的同时,也对程序本身和程序设计方法进行了深入的探讨。1976年瑞士计算机科学家N.Wirth在他的惊世之作中提出一个著名的公式: 程序=数据结构+算法 他认为程序就是在数据的某些特定表示方式和结构的基础上对抽象算法的具体描述。从今天的观点来看,它只能是对过程化程序的一个抽象定义,对面向对象的程序而言则不尽然。不过对我们学习C语言这样的面向过程的程序设计语言而言是完全适合的。也就是说,面向过程的程序有两大要素:算法和数据结构。数据结构是程序所处理的对象即数据的表示和组织形式,高级语言中的数据类型是其重要内容。算法是解决某个特定的问题而进行操作的方法和操作步骤。 3.1.1 算法的性质与组成要素 (1) 算法的性质 有穷性,确定性,有效性,有零个或多个输入输出。 (2) 算法的组成要素 操作:每个操作的确定不仅取决于问题的需求,还取决于它们取自哪个操作集,它与使用的工具系统有关。在高级语言中所描述的操作主要包括:算术运算、逻辑运算、关系运算、函数运算、位运算和I/O操作。计算机算法是由这些操作所组成的。 控制结构:控制结构控制组成算法的各种操作的执行顺序。结构化的程序设计要求一个程序只能由三种基本结构(顺序结构、选择结构和循环结构)或其派生出来的结构组成。1966年Bohm和Jacopini证明出由这三种基本结构可以组成任何复杂结构的算法。 3.1.2 算法的描述 (1) 流程图:流程图的特点是用一些图框表示各种类型的操作,用线表示这些操作的执行顺序。P58图3.2是用国家标准流程图表示顺序结构、选择结构和循环结构。 (2) N-S图:N-S图的特点是没有流线的流程图。P59图3.6是用N-S图表示顺序结构、选择结构和循环结构。 (3) PAD图:PAD图的特点是没有流线并且有规则地安排了二维关系,从上到下表示执行顺序,从左到右表示层次关系。P60图3.8是用PAD图表示顺序结构、选择结构和循环结构。 (4) 伪代码与逐步细化的程序设计方法:流程图、N-S图和PAD图是描述算法的三种图形工具。使用这些工具描述出的算法直观、易懂、逻辑关系清晰,但画起来比较费事,修改起来比较困难。伪代码是用介于自然语言与计算机语言之间的文字符号算法描述的工具。它的特点是没有固定的、严格的语法规则,通常借助某种高级语言的控制结构,中间的操作可以用自然语言也可以用程序设计语言,或是用自然语言与程序设计语言的混合体。 按自顶向下的方法,解题之初不要一下子就力图触及到问题解法的细节,而应当从问题的全局出发,给出高度概括、抽象的算法。这时常常用自然语言来描述,这样容易与用户交流。这时的算法主要是描述“做什么”的问题,或者说把问题分解成若干个子问题或子功能。 下一步是在子问题一级描述算法。它是对全局算法的细化。这一阶段的工作可能包括好几个步骤,要因问题的大小而定。在这一阶段设计的算法中,已经越来越多地含有具体的程序设计语言的成分。 随着算法不断细化,逐步进入对“如何做”的考虑,算法中程序设计语言的成分越来越多。当最后把算法全部细化为程序设计语言描述时,“如何做”的问题也就完全解决了,程序设计也就随之完成。这种方法是一种处理复杂问题的科学方法。下面我们通过举例说明用逐步细化的方法设计程序的过程。 例3.1 求三个数中的最大数。 S1:输入三个数a,b,c。 S2:从a,b,c中找出最大数赋给予max。 S3:输出最大数max。 下面设计max3(float x,float y,float z)函数。 S2.1:从x,y中取大数送入m中。 S2.2:从m,z中取大数送入m中。 S3.3:返回m的值给主调函数。 float max3(float x,float y,float z) { float m; if (x>y) m=x; else m=y; if (m<z) m=z; return(m); } main( ) { float a,b,c,max; scanf(“%f%f%f”,&a,&b,&c); max=max3(a,b,c); printf(“the max is :%f\n”,max); } §3.2 用C语句描述算法 程序就是对计算机要执行的一组操作序列的描述。高级语言源程序的基本组成单位是语句。语句按功能可以分为两类:(1)操作运算语句用于描述计算机要执行的操作运算;(2)流程控制语句控制操作运算的执行顺序。 3.2.1 表达式语句 C语言是一种表达式语言。所有的操作运算都通过表达式来实现。由表达式组成的语句称为表达式语句,它由一个表达式后接一个分号组成(注意没有分号不能构成语句,分号是语句的组成部分)。表达式语句分为赋值表达式语句、函数调用表达式语句、空语句和逗号表达式语句(C语言允许把几个表达式用逗号组合起来形成逗号表达式,逗号表达式的值是其中最后一个表达式的值)。 3.2.2 形成流程控制结构的语句 对同样的数据先乘除后加减与先加减后乘除得到的结果是不同的,原因在于流程改变了,所以设计程序时不仅要设计合适的操作,而且要构造适当的流程。高级语言一般提供两种形式的流程控制:形成流程控制结构和简单的流程转向。本章主要内容是介绍这两种控制方式的应用。本节我们先对控制结构的形式予以概略介绍。 顺序、选择和循环是结构化程序的三种基本结构。结构化程序设计方法学出现以后,大多数高级语言都提供这三种控制结构。准确地说是后两种,因为顺序结构是自然形成的,无须在程序中加以专门控制。 1. 选择型结构 if…else是选择型结构的基本形式,它实现了“二选一”的控制结构。在处理问题时只有“二选一”往往是不够的,有许多情况是“多选一”的。可以由“二选一”结构扩充为“多选一”的结构。为了应用起来更方便,许多高级语言提供了一种专门的控制结构—多路选择控制结构。C语言用switch语句实现多路选择控制结构。 2. 循环控制结构 循环控制结构一般由三个部分组成:进入条件,退出条件和循环体。根据进入和退出条件,循环控制结构可以分为三种形式: (1) while语句的功能是实现“先判断后执行”的循环控制结构语句。 (2) do…while语句的功能是实现“先执行后判断”的循环控制结构语句。 (3) for语句的功能是实现“先判断后执行”的循环控制结构语句,但for语句的结构比while语句结更加紧凑,使用起来更加灵活,功能更强。 3.2.3 限定转向语句 这一类语句不形成控制结构,只是简单地使流程从其所在处转向另一处。但是它不允许用户自己指定转向,而是按照系统事先规定的原则向某一点转移,用户不必指定转向。 (1) break语句:break语句的功能是把流程从所在处转向所在的循环结构或多路选择结构之后,或者说终止执行这些结构,见P67图3.14。 (2) continue语句:提前结束本次循环,然后再根据循环条件决定是否进入下次循环,见P67图3.15。 (3) 函数调用和返回:函数调用的功能是使程序流程转向被调函数的函数体。函数返回的功能是使程序流程从被调函数返回主调函数。这两种流程控制都可能伴随参数传递,详细内容见§4.1。 3.2.4 goto语句 goto语句的功能是实现流程无条件地转移到本函数内的某个目的地,目的地用一个合法的标识符表示。结构化程序设计方法不提倡使用goto语句,除非使用goto语句能够较大地提高程序的运行效率而不破坏程序结构化的原则。本书的程序都不使用goto语句。 3.2.5 C基本语句一览表 P68对C语言中的基本语句进行了归纳。 3.2.6 复合语句 C语言把括在一对花括号中的一组语句称为复合语句。复合语句在语法上是一个整体,相当于一条语句。凡是能够用简单语句的地方都可以用复合语句。复合语句中可以定义变量,因此复合语句又称分程序。在分程序中定义的变量只在本分程序中有效,详细内容见§4.2。 3.2.7 exit语句 exit是标准库stdlib中的一个函数。它的作用是立即停止当前程序的执行并退回到操作系统状态。它常常作为一个特殊的表达式语句控制程序停止执行。 §3.3 选择型程序设计 选择型程序所解决的问题称为判断问题,它描述了求解规则:在不同的条件下所应进行的相应操作。因此,在书写选择结构之前,应该首先确定要判断的是什么条件,进一步确定判断结构为不同情况(“真”或“假”)时应该执行什么样的操作。下面分别介绍C语言中用来实现选择结构的三种语句。 3.3.1 if…else结构的应用 (1) 语法格式:if (exp) s1;else s2; (2) 执行流程:先对条件表达式exp进行判断,若为真(成立,值为非零)则执行if分结构s1;否则(不成立,值为零)则执行else分结构s2。其中条件表达式exp可以是关系表达式、逻辑表达式,也可以是算术表达式,因为判断的标准是其值是否为0。 例3.2 求一个数的绝对值。 分析:设有任意实数 double abs(double x) { if(x<0.0) x=-x; else x=x; return(x); } 下面是函数abs被main函数调用的情况: main( ) { double a; scanf("%lf",&a); printf("%lf",abs(a)); } C语言还允许使用缺省else分结构的if…else结构。缺省else分结构的if…else的语法格式为: if (exp) s1; 它的执行流程是先对表达式exp进行判断,若为真(成立,值为非零)则执行if分结构s1,否则什么也不执行。例如,上述函数abs的定义可以写成如下的形式: double abs(double x) { if(x<0.0) x=-x; return(x); } 这种结构称为不平衡的if结构,它不如平衡的if结构使人容易理解。下面我们看一个稍微复杂的例子,这个例子在if…else语句或缺省else的if语句中的if分结构或else分结构中再次嵌套if…else语句或缺省else的if语句。 例3.3 设计一个求三个数中的大数的函数。 下面有人写了一个函数max3: float max3(float x,float y,float z ) { float max=x; if (z>y) if (z>x) max=z; else if (y>x) max=y; return(max); } 程序设计者主观上认为这个函数是正确的,但实际上这个函数不正确。原因是使用嵌套的if结构时,没有搞清楚在嵌套的if结构中else和哪个if进行匹配的问题。C语言规定:当程序中存在嵌套的if…else结构时,由后向前使每一个else都与其前面的最靠近它的还没有匹配的if匹配。 通过这个例子可以看到: (1) 嵌套的if…else结构会增加阅读和理解程序的困难。建议在设计程序时应尽量避免使用if…else的多重嵌套结构。 (2) 正确的缩进格式可以帮助人们的理解程序,但是错误的缩进格式反而会使人迷惑。建议在程序设计时应尽量采用缩进格式书写程序。 (3) 不要太相信自己的判断,要严格按照语法关系检查程序。在不容易弄清的地方可以加花括号来保证自己构思的逻辑关系的正确性。 正确的函数设计代码如下: float max3(float x,float y,float z ) { float max=x; if(z>y) {if (z>x) max=z;} else if(y>x) max=y; return(max); } 3.3.2 else if结构的应用 else if结构是if…else多重嵌套结构的一种变形(每次在else分结构中嵌套if…else结构)。else if结构通过一连串的判断来寻找问题的解。下面通过一个具体程序来说明其应用。 例3.4:输入学生成绩,打印对应的等级。 main( ) { int g; scanf("%d",&g); if(g>=90) printf("A"); else if(g>=80) printf("B"); else if(g>=70) printf("C"); else if(g>=60) printf("D"); else printf("E"); } | |||||