1、1,Ch3 C程序流程设计,2,分析问题 确定算法 编写程序 调试程序 整理结果,3,Niklaus Wirth 公式: 程序=数据结构+算法,4,程序= 数据结构+算法+程序设计方 法+语言工具+程序设计人员,5,3.1 算 法,6,一、算法概念 1.算法概念 算法:解决问题的方法与步骤。 如:某菜品制作步骤就是加工该菜肴的算法;乐谱就是演奏某乐曲的算法;太极拳动作图解就是打太极拳的算法。 例1(清华P14例2.2)写出输出50个学生成绩中大于等于80分者的算法。 假设:i 为学生人数ni 为第i个学生的学号gi 为第i个学生的成绩,7,则算法如下: S1: 1 i S2: 输入ni, gi
2、 的值 S3: 如果gi80,则输出ni,gi 的值,否则不 输出 S4: i+1 i S5: 若i50,则返回S2;否则算法结束2.算法优劣标准: 正确、简单3.算法种类:数值计算算法与非数值计算算法(清华P14),8,二、算法特性(清华P18) 1.有穷性 2.确定性(无歧义性) 3.有效性 4.有零个或多个输入 5.至少有一个输出 三、算法的组成要素(高教P56) 1.操作(算数运算、逻辑运算、关系运算、函数运算、位运算、I/O操作等) 2.控制结构(顺序结构、选择结构、循环结构),9,四、算法的描述(清华P19,高教P57) 1.用自然语言描述算法 2.用传统流程图描述算法 (组成元件
3、见清华P19图2.3)例2(清华P20例2.7/高教P59求n!)例3.用传统流程图描述求解两个整数中的最大值的算法。,10,例3.,11,3. 用N_S流程图描述算法 (组成元件见 清华P20图2.24至2.27/高教P59图3.6)例4. 用N_S流程图描述求解两个整数中的最大值的算法。例5. (例1的N_S图),例4,例5,12,4.用伪代码描述算法用伪代码描述算法就是用介于自然语言与计算机语言之间的文字与符号来描述算法。 例6. (对应例5)BEGIN1 iwhile i50input ni,giif gi80 print ni and gii+1 iEND,13,5.用程序设计语言描
4、述算法 计算机无法识别流程图和伪代码,只有用程序设计语言描述的算法,才能被计算机执行、实现。 与伪代码不同,用程序设计语言描述算法时,必须严格遵守所用语言的语法规则。 例7. (例6中算法的C语言描述.高教P61例3.1类似) main() int i=1,n,g;while(i=80) printf(“%d,%dn”,n,g);i=i+1;,14,3.2 结构化 程序设计方法,15,一、程序设计方法及其发展 二、结构化程序设计方法 1.结构化程序设计方法(功能抽象,化整为零,逐步细化) 2.结构化程序设计原则(高教P61例3.1后归纳总结)(1).模块化(2).自顶向下(3).逐步求精 3.
5、结构化程序的特点(1).由三种基本结构顺序组成(清华P28)(2).每个程序块只有一个入口和一个出口(3).没有死语句(执行不到的语句)(4).没有死循环,设计的模块化。划分模块时,模块的独立性要强;扇出数要恰当(25个,9个);大小要适中(50100条语句, 500条)。 编码的结构化。应选择结构化程度高的程序设计语言编码。,16,4.三种基本结构(图示其传统框图和N_S图。高教P58)(1).顺序结构(2).分之结构(单分支、二分支、多分支)(3).循环结构(当型循环、直到型循环)任何一个结构化程序都由这三种基本结构顺序组成,在基本结构之间不存在向前或向后的跳转,流程的转移只存在于一个基本
6、结构之内。,17,3.3 C程序整体结构与C语句,18,一、C程序整体结构 ,C程序,源程序文件2,源程序文件n,函数1,源程序文件1,预处理命令,全局变量声明,函数n,函数说明部分,函数体,局部变量声明,执行语句,19,二、C语句(个高教P64,P68图示) 1.控制语句(清华P68,9种,控制程序流程) 2.函数调用语句(由一次函数调用加;构成)如:printf(“%d”,32+5); 3.表达式语句(由一个表达式+;构成)如:x=3; 4.空语句(由一个;构成): ; 5.复合语句(花括号括起的多个语句) 如:int x,y; x=2; y=3;,20,3.4 三种基本控制结构 程序设计
7、,21,3.3.1 顺序结构程序设计(按语句出现的先后顺序执行,高教习题) 例从终端输入三角形三边的值(假设能构成三角形),求三角形的面积 设a,b,c,s,area分别为三边,半周长和面积, 则 area=s=(a+b+c)/2 框图和程序如下:,22,开始输入a,b,c(a+b+c)/2 sarea输出area结束,#include main( ) float a,b,c,s,area;printf(“Input a,b,c:n”);scanf(“%f%f%f”,23,3.3.2 分支结构程序设计(根据一定的条件有选择地执行) 一、if语句的三种形式 1. if(表达式) 语句_单分支结构
8、表达式 0非0语句,如: if(xy) z=x; 说明: 格式中的”语句”称为if语句的内嵌语句 内嵌语句只能是一个语句;若有多个,应用大括号括起来,成为一个复合语句if(xy) z=x;x=y;,24,内嵌语句可以是空语句 if(xy) ;特别: if(xy) z=x; 可以写成:if(xy)z=x; 但不能写成: if(xy);z=x; 格式中的”表达式” 一般是表示条件的逻辑表达式或关系表达式,但它可以是任意的数值类型的表达式(整型,实型,字符型等)如 if(32) printf(“OK!n”);if(a) printf(“%dn”,a); 都是正确的,25,例2.输入二整数,求a,b中
9、的最大值,并放在maxv中。 main( ) int a,b,maxv;scanf(“%d%d”, ,开始输入a,ba maxvab非0 b maxv输出maxv结束,0,成本P29例3.4,26,例3.输入三个数,使它 们按由小到大的顺序输出. 三个数由x,y,z输入temp为中间变量 按比较交换法排序 板书算法框图 根据框图写出程序如右,main( ) floate x,y,z,temp; scanf(“%f%f%f”,成本P30例3.6,高教习题,27,2.if_else(二分支结构) 格式: if(表达式)语句1else 语句2功能: 根据条件控制程序流程表达式语句1 语句2,0,说明
10、: 格式中if语句,else语句的内嵌语句均可以是空语句,也可以是复合语句,还可以是分支语句 语句1与语句2只能被执行其一.,28,例4.用if_else结构改写例2中的程序 main( ) int a,b,maxv;scanf(“%d%d”, 思考: 如果第五行中没有else会怎样?可否将if和else的内嵌语句改为输出语句?,29,例5.(高教P69例3.3) 例6.(新清华P95例5.3)有一函数: 输入一个x值,输出相应的y值. 以下程序中哪些能输出正确结果? Why?,程序1: main() int x,y; scanf(“%d”, ,程序2:将程序1中的if语句改为: if(x=0
11、)if(x0) y=1;else y=0; else y=-1;,30,程序3:将程序1中的if 语句改为: y=-1; if(x!=0)if(x0) y=1; else y=0;,程序4:将程序1中的if 语句改为: y=0; if(x=0)if(x0) y=1; else y=-1;,分析之,并据程序画出相应的框图. 注意: if和else的内嵌语句后都必须有分号; else子句不能单独使用,必须与if语句配对 使用:从最内层开始,与前面最近的if配对.高教P70例3.4,31,3.if_else if(多分支结构) 格式: if(表达式1) 语句1 else if (表达式2) 语句2e
12、lse if (表达式3) 语句3else if (表达式n-1) 语句n-1else 语句n,32,功能:根据条件控制程序流程,表达式1表达式2 表达式n-1语句1 语句2 语句n-1 语句n,33,例7.某运输公司运费规定如 下(cost为运费,x为距离)0 x500.05 x50 cost= 0.075 x1000.10 x3000.15 x500 根据距离远近,输出运费. 程序如右:,main( ) int x; float cost;scanf(“%f”, ,思考:该程序中的if结构可否有其他表述形式?,34,例8(成本P36例3.11)输入一个简单表达式,形如:操作数 运算符 操作
13、数 如: 32*56输出该表达式的值。main( ) float value1,value2; char operator; printf(“type in your xpresssion.n”); scanf(“%f%d%f”, ,35,if(operator=+)printf(“%fn”, value1+value2); else if(operator=-)printf(“%fn”, value1-value2);else if (operator=*)printf(“%fn”, value1*value2);else if (operator=/)if(value2=0)printf(
14、“division by zero.n”);else printf(“%fn”, value1/value2);else printf(“unknwon operator.n”); ,36,说明: 格式中if语句,else语句的内嵌语句均可以是空语句,也可以是复合语句,还可以是分支语句 语句1,语句2,语句n只能被执行其一. if和else的内嵌语句后都必须有分号; else子句不能单独使用,必须与if语句配对 使用:从最内层开始,与前面最近的if配对. 当if或else后又含有一个或多个if语句时,称为if语句的嵌套,37,二、if语句的嵌套 一般形式如下: if( )if( )语句1els
15、e 语句2 elseif( )语句1else 语句2,内嵌if,内嵌if,例.下面程序段试图使第三行的else与第一行的if配对,能否实现?怎样实现? if ( )if( )语句1 elseif( )语句2else 语句3高教P70例3.4与此例类似,其正确程序见P72,38,对于if语句的嵌套,应特别注意else与if的配对关系:从最内层开始,else与前面最近的if配对. 一般应遵循如下原则: 内嵌的if语句最好含有相应的else语句,使if和else的数目相同,一一对应。例9:高教P72例3.5 or 清华P59例5.3程序1 如果if和else的数目不相同,可使用大括号来确定配对关系。
16、如上例 和 高教P72例3.4的正确程序 只嵌套在else子句中,构成if_else if结构。高教P74例3.6,39,三、switch语句 格式:switch(表达式) case 常量表达式1 : 语句1case 常量表达式2 : 语句2case 常量表达式n : 语句ndefault : 语句n+1 ,40,说明: switch后的表达式可以是整型字符型和枚举型数据 各case后的表达式必须为常量表达式;如:可以 3+6 ,但不可以 3+x 各case子句后的语句i可以是空语句,也可以是复合语句,并可缺省其大括号;如:case A: x=90; printf(“%d”,x); 各case
17、子句的前后顺序可以任意; default子句可以没有; 一个switch结构的case子句和default子句必须用大括号整体扩起来。,41,功能:根据switch后表达式的值是否与某case后常量表达式的值相等,确定程序流程 NS图:,42,注意: 任二case子句后的常量表达式的值不相等,否则会导致相同条件出现两种甚至多种执行方案的矛盾 多个case子句可共用一组执行语句;且除该组最后一case子句,前面若干case子句的执行语句可缺省不写如: case A:case B:case C: printf(“60n”);break;,43,执行完一个case子句后,流程转移到下一 case子句
18、继续执行,若只需执行一个语句后退出switch结构,可以在该case子句的执行语句序列最后使用break语句。 例10.清华P75例3.7,main( ) float value1,value2;char operator;printf(“type in your expresssion.n”);scanf(“%f%d%f”,例11.(用switch结构改写例8),44,case+: printf(“%fn”, value1+value2);break;case-: printf(“%fn”, value1-value2);break;case*: printf(“%fn”, value1*v
19、alue2);break;case/: if(value2=0)printf(“division by zero.n”);else printf(“%fn”,value1/value2);break;default: printf(“unknwon operator.n”); ,switch( ),operator,注意break;语句的有与无!,45,例12.假设学生成绩为A,B,C,D四等,其中A为90100分,B为8089分,C为7079分, D为6069分,E为不及格要求:输入成绩等级,输出百分制成绩段。 main( ) char grade; scanf(“%c”, ,switch( ),grade,A:,printf(“90100n”);,break;,46,思考: 如果上例中输入百分制成绩,输出成绩等级,程序应做何修改? 例12中的程序可否用if_else if结构实现?如何实现? 归纳与比较: if_else if结构与switch结构是多分支的两种 不同形式: if_else if多用于多条件并列测试,从中取一的情况; switch结构则用于单条件测试,从中取一的情况. 作业:清华P105 5.4, 5.5, 5.6, 5.8, 5.9高教P96:1,2(1,2,3,4),5,7,补充题自学教材P77例3.8,