利用计算机进行程序设计时,不仅仅只处理一些简单的数据,在大部分的程序设计里处理的问题还是相当复杂的。对于那些复杂的程序设计,读者不可能直接就能写出程序的源代码,而是要通过一些具体的设计方法(如用程序流程图)把程序设计思想先写出来,然后根据程序流程图编写代码。本章将具体介绍进行程序设计时使用的基本方法和C程序的流程控制。 3.1 程序设计的基本知识 3.1.1程序流程图
在描述一个程序的基本结构思想时有很多种方法,其中程序流程图是最常用也是最基本的方法。
1. 传统程序流程图
传统流程图表示法的特点是用一些图框表示各种类型的操作,用线表示这些操作的执行顺序。美国国家标准化协会ANSI规定了一些常用的流程图符号,现已为世界各国普遍采用。我国也有自己的国家标准GB 1526-89与该标准基本相同,本书就参照
ANSI标准做具体介绍。标准中各种图示如图3.1所示。
起止框 输入输出框 判断框 处理框
或
流程线 连接点 注释框
图 3.1 传统流程图表示法
下面对其中一些主要符号作简要说明: (1)起止框是用来标识程序的开始和结束位置的。规定流程图以起止框开始,以起止框结束。
(2)输入输出框也叫数据框,其中可以注明数据名称、来源、用途或其它的文字说明。
(3)菱形框的作用是对一个给定的条件进行判断,根据给定的条件是否成立来决定如何执行其后的操作。
(4)处理框用矩形表示各种处理功能。例如,执行一个或一组特定的操作,从而使信息的值、信息的形式或所在位置发生变化。另外在矩形框内可注明特定处理名称或其简要功能。
(5)流程线用带箭头的直线表示程序
的执行顺序。当流程自左向右或自上向下时流程线可以不带箭头,其它情况应加箭头表示流程。
(6)连接点用小圆圈表示将画在不同地方的流程线连接起来。下图中有两个以①为标志的连接点,它表示这两个点是互联在一起的,实际它们是同一个点。这种连接通常用在图形画不下而需要分开画时。
①
①
(7)注释框不是流程图的必要部分,其不反映流程操作,只是为了流程图中某些操作做解释补充的,以帮助阅读流程图的人更好的理解流程图的作用。
2. N-S流程图
灵活的流程线在程序设计中有它自己的优点,但也隐藏着许多导致错误的祸根。因为它允许用流程线使流程任意转移,这对程序设计是一个隐患,它使程序流程看起来很乱,使程序难以理解和维护。针对这一弊病,1973年美国学者I . Nassi和B . Shneiderman提出了一种无流程线的流程图,称为N-S图。
它的基本表示方法是用一个矩形框,把整个程序算法像堆积木一样组成。其基本结构如图3.3、3.4、3.5、3.6所示。 3.1.2 程序的三种基本结构
结构化的程序设计方法是面向过程的程序设计的基本方法。1996年意大利Bobra和Jacopini提出了三种基本程序结构。已经证明,这三种算法可以解决任何复杂的问题。
1. 顺序结构 (传统流程图表示)语句组 1 (N-S流程图表示) 语句组1 图3.3 顺序结构流程图 语句组2 语句组2 2. 选择结构
成立 条件P 条件P 流程图表示) 假 (传统流程图表示) 真( N-S语句组 1 语句组2 图3.4 选择结构流程图不成立 语句组1 语句组2 3. 循环结构(1)while循环结构
当条件P成立
条件P 语句组 不成立 成立 ( 传统流程图表示) (N-S流程图表示)
图3.5 当型循环结构流程图
语句组 (2)do…while循环结构
语句组 直到条件P成立
语句组 条件P 成立 不成立( 传统流程图表示) (N-S流程图表示)
图3.6 直到型流程图
例3.1 画出求s=1+2+3+ … +100的传统流程图和N-S流程图。 开始 i=1; s=0;
i=1; s= 0; i<=100 3.2 C语言的基本语句 s=s+i; i=i+1; 输出s 3.2.1 表达式语句 s=s+i; i=i+1; C语言是一种表达式语言,所有的操作i<=100? 运算都是通过表达式来实现的。由表达式组成立 不成立 成的语句称为表达式语句,它是由一个表达输出s 式后接一个分号组成。这里要特别强调,没有分号的不是语句。 结束 1. 赋值语句 赋值语句由赋值表达式加一个分号组成。例如:i = 1 ;
2. 函数调用语句
函数调用语句由函数调用表达式后跟一个分号组成。例如:
strcpy( s1, \"student\
printf(\"good afternoon\\n \" );
3. 空语句
空语句是只有一个分号而没有其他表达式的语句。例如:
;
它不产生任何操作运算,只作为形式上的语句,被填充在控制结构之中。 3.2.2 复合语句
C语言还允许把一组语句放在一对花括号之中,称为复合语句。要特别强调一点,一个复合语句的后花括号之后不应再写分号。例如: {
c = getchar(); b = b + c ; putchar(); }
3.2.3 流程控制语句
选择型结构语句 循环控制结构语句 流程转向语句 ……
3.3 选择结构程序设计
在C语言中实现选择结构的语句有两大类:if语句和switch语句。 3.3.1 if语句
(1)简单if语句
格式:if(表达式)语句;
功能:如果表达式的值为真,则执行其后的语句,否则不执行该语句。其N-S流程图如图3.9表示。
表达式 图3.9 真简单 if 语句流程图 假 (2)基本if … else语句 格式:if(表达式)语句1; else 语句2;
功能:如果表达式值为真,则执行语句1,否则执行语句2。其执行过程如图3.10所示。
表达式 真 假 1 语句2 图3.10 基本语句if … else语句流程图
语句 例3.3 从键盘输入任意一整数,求其绝
对值并输出。 # include int x; printf(\" please enter a number: \"); scanf(\"%d\ if(x<0) x=-x; else x=x; printf(\"number abs is d%\} (3)if语句的嵌套 当if语句中执行的语句又是if语句时,那么就构成了if语句的嵌套。其一般形式可以表示如下: if(表达式) if 语句1; else 语句2; else if 语句3; else 语句4; 在if语句的三种形式中,如果所要执行的语句超过一条必须用花括号括起来,构成一条复合语句,才能被完全执行。 例如:if(a>b) { a++; b++; } else { a=10; b=100; } 3.3.2 switch语句 一种用于多分支选择的语句——switch语句,用该语句编写的程序简洁、易懂。而且,其执行效率要比同样功能的阶梯式 if …else if …else语句要高的多。 1. switch语句的一般形式 switch语句的一般形式如下: switch(表达式) { case 常量表达式1:语句组1; case 常量表达式2:语句组2; ·· · case 常量表达式n:语句组n; default :语句组n+1; } 2. switch语句的执行过程 系统首先计算“表达式”的值,并逐个与其后的“常量表达式”的值相比较,当“表达式”的值与某个“常量表达式”的值相等时,就以此作为程序执行的入口,执行switch结构中后面的各语句。如果没有任何一个case后面的“常量表达式”的值与“表达式”的值匹配,则执行 default后面的语句(组)。 例3.6 用switch语句实现例3.4的功能。 # include int score; printf(\"please input score(0-100):\"); scanf(\" %d \ /*从键盘输入学生成绩*/ switch(score/10); { case 10: case 9:printf(\"excellent\\n\");break; case 8:printf(\"good\\n\"); break; case 7:printf(\"medium\\n\"); break; case 6:printf(\"pass\\n\"); break; default:printf(\"fail\\n\"); } } 3.4 循环结构程序设计 C语言提供了循环控制的三种语句:while语句、do…while循环语句和for循环语句。 3.4.1 while语句 while语句是一种条件循环结构,其控制结构如下: while(条件表达式) 循环体 例3.7 计算并输出从1加到100的和:s = 1+2+3+┅100。 # include int sum = 0 , i = 1; /*设置和与循环变量*/ while(i<=100) { sum = sum+i; i++; } printf(\" Sum=%d \} 程序执行结果如下: The sum of 1 to 100 equals is:5050 3.4.2 do…while循环语句 do…while结构在C语言中用于实现“直到型”循环。其一般形式为: do 循环体 while(条件表达式); 例3.9 用do…while语句求1+2+3+…+100的和。 # include int i =1 , sum=0; do { sum = sum+i; i++; } while(i<=100); printf(\"sum= %d\} 3.4.3 for循环语句 for语句的使用最为灵活,既可以用于循环次数确定的情况,也可以用于循环次数未知的情况。 for语句的一般形式如下: for(表达式1;表达式2;表达式3) 循环体 如图3.13所示,for语句的执行流程是: 求解表达式1 图3.13 for语句的执行流程 表达式2 例3.10 输入一个整数,求出它的所有因子。 true 求一个整数n的所有因子可以采用穷举语句(循环体) 法,对1~ n的全部整数进行判断,凡是能够 3 整除n的都是n求解表达式的因子。由分析可知,这是一个已知循环次数的循环,因此可以使用for语句。 # include int n, k; false printf(\"Please input a positive integer:\"); scanf(\" %d \ printf(\" Number %d Factors:\ for(k=1;k<=n;k++) if(n%k= =0) printf(\" %d\ printf(\"\\n\"); } 程序某次的运行结果如下: Please input a positive integer:36↙ Number 36 Factors:1 2 3 4 6 9 12 18 36 3.4.4 循环嵌套 一个循环体内又可以包含另外一个完整的循环结构,从而构成多重循环结构,这就是循环的嵌套。 3.4.5 continue和break语句 1. continue语句 continue语句可以出现在循环体中,其作用是结束本次循环,但不退出循环结构。它跳过循环体中下面尚未执行的语句,直接进行下一次是否执行循环的判定。 例3.12 输出60~600之间所有不能被9整除的数。 # include int m; for(m=60; m<=600 ; m++) { if(m%9= =0) continue ; printf(\"%d\\n\ } } 由这个程序可以看出,当某个自然数m被9整除时,就利用 continue语句结束本次循环(其后的输出语句不执行),但不退出for循环结构,接着对下一个数进行判断。 2. break语句 break语句只能用在switch结构或循环结构,而不能用于其他结构。但用在循环结构中时,只能跳出(或终止)它所在的循环,而不能同时跳出(或终止)多层循环。 本章小结 从程序执行的流程来看,程序可分为三种最基本的结构:顺序结构、分支结构以及循环结构。本章从学习程序的流程图画法入手系统的介绍了这三种基本结构。 程序中执行部分最基本的单位是语句。本章主要介绍了以下三种类型的语句: (1)表达式语句,任何表达式末尾加上分号即可构成表达式语句,常用的表达式语句为赋值语句。 (2)复合语句,由{}把多个语句括起来组成一个语句。复合语句被认为是单条语句,它可出现在所有允许出现语句的地方,如循环体等。 (3)控制语句,用于控制程序流程,由专门的语句定义符及所需的表达式组成。主要有条件判断执行语句,循环执行语句,转向语句等。 C语言提供了多种形式的条件语句以构成分支结构。 (1)if语句主要用于单向选择。 (2)if…else语句主要用于双向选择。 (3)if …else if…else语句和switch语句用于多向选择。 这几种形式的条件语句一般来说是可以互相替代的。 C语言提供了三种循环语句。for语句主要用于给定循环变量初值、步长增量以及循环次数的循环结构。循环次数及控制条件要在循环过程中才能确定的循环可用 while或do-while循环。三种循环语句可以相互嵌套组成多重循环。循环之间可以并列但不能交叉。可用转移语句把流程转出循环体外,但不能从外面转向循环体内。在循环程序中应避免出现死循环,即应保证循环变量的值在运行过程中可以得到修改,并使循环条件逐步变为假,从而结束循环。 因篇幅问题不能全部显示,请点此查看更多更全内容