cxm-C语言程序设计课件第4章.ppt

上传人:tia****nde 文档编号:12805463 上传时间:2020-05-25 格式:PPT 页数:65 大小:3.51MB
返回 下载 相关 举报
cxm-C语言程序设计课件第4章.ppt_第1页
第1页 / 共65页
cxm-C语言程序设计课件第4章.ppt_第2页
第2页 / 共65页
cxm-C语言程序设计课件第4章.ppt_第3页
第3页 / 共65页
点击查看更多>>
资源描述
2020/5/25,1,C语言程序设计,第四章程序流程控制,主讲:计算机学院曹晓梅,2020/5/25,3,内容提要,算法的基本概念以及表示方法,简单介绍流程图C程序的3种基本流程控制结构:顺序结构、选择结构(也叫分支结构)、循环结构,每种结构的控制语句:if、switch控制选择结构for、while、dowhile控制循环结构break、continue、goto等语句的用法循环嵌套程序的设计及运行过程一些常用算法的基本思想:分段函数求解问题判断一个整数是否为质数求两个正整数的最大公约数各种求和问题,掷骰子游戏的多种解法,求阶乘,打印规则的图形,穷举问题的多种求解方法,2020/5/25,4,算法与语句,算法(Algorithm)就是为解决一个具体问题而采取的有限的操作步骤,算法通过语句来实现计算机算法分两类:数值运算算法、非数值运算算法程序=数据结构+算法算法的正确性衡量标准:有穷性:算法包含有限步操作确定性:每一步都应确定无歧义有效性:每一步都应能有效执行且能得到确定的结果0或多个输入:程序允许无输入1或多个输出:任何程序都必须有输出,哪怕是提示信息,解决求数值解的问题,解决需要用分析推理、逻辑推理才能解决的问题,数据的描述和组织形式,对操作或行为的描述,即操作步骤,2020/5/25,5,算法与语句,常用的算法描述方法有:自然语言、传统流程图、NS流程图、伪代码等,这里只介绍传统流程图。例:求n!的算法思想:n!=1*2*3*n由于计算机执行乘法时每次只能求两个数相乘,因此上面的公式在程序中必定需要通过反复相乘来实现。第一个变量,存放求多少的阶乘(intn);第二个变量,存当前累乘的结果(intfac);第三个变量存当前将要与累乘器相乘的因子,并且该因子的变化是从1到n每次增加1(inti)流程图如下页所示,2020/5/25,6,3种基本结构的特点:单入口,单出口,2020/5/25,7,C语句分类,C语言的语句有五大类:(1)9种控制语句:这一类语句用于实现流程控制,选择结构和循环结构必须通过控制语句实现。ifelse语句:是实现选择结构最常用的语句switch语句:用于控制某些多分支的选择结构for()语句:最常用最灵活的循环控制语句,当型循环while()语句:循环结构最安全的控制语句,当型循环dowhile()语句:控制先执行后判断的直到型循环结构continue语句:表示提前结束本次循环,忽略其后循环体中的其他语句break语句:可用于switch语句(结束switch)或循环体中(结束本层循环)goto语句:流程跳转语句,很灵活,可实现各种结构,建议少用或不用return语句:专门用于函数返回,被调函数执行到return就返回到调用点(2)变量定义语句:用来定义变量,形如:inta,b;(3)表达式语句:C语言中任何一个表达式最后加上分号构成表达式语句,赋值语句和函数调用语句是最常用的表达式语句(4)复合语句:以一对大括号括起的0或多条语句,在语法上仍为一条语句(5)空语句:只有一个分号构成的语句,表示什么也不做,2020/5/25,8,顺序结构,顺序结构的特点:语句按顺序依次执行,不涉及到任何条件的判断。顺序结构所使用的语句:变量定义语句、函数调用语句、赋值语句、return语句等。无需用其他流程控制语句优点:结构简单易懂缺点:对程序的健壮性、完备性往往无法兼顾例:程序4.1从键盘上输入a,b,c的值,并以它们为三角形的三条边,求三角形的面积。算法思想:根据数学知识,设一个变量s用于求三角形周长的一半,即s=(a+b+c)/2,再利用一般三角形求面积的公式求解:,2020/5/25,9,程序4.1求任意三角形的面积#include#include/包含平方根函数sqrt的声明intmain()doublea,b,c,s,area;/定义5个double变量printf(“Pleaseinputa,b,c:n”);/屏幕提示scanf(%lf%lf%lf,顺序结构,输入345输出area=6.000000,编程提示:存原始数据的变量,用读入方式使其获得的值更灵活,也可赋值,但是通用性下降,问题1:可能会输入负数问题2:即使输入的都是正数,未必能构成一个三角形顺序结构无法解决需要作出判断的问题!,2020/5/25,10,选择结构的特点:通过某一个或若干条件的约束,有选择性地执行特定语句-在符合一定条件时,执行特定操作;在不符合条件时,不执行操作或执行另外的操作选择结构使用的流程控制语句:if语句、switch语句优点:保证程序的健壮性、完备性ifelse语句形式:if(表达式)语句块1else语句块2执行过程:先计算表达式,若非0(真)则执行语句块1;如果表达式为0(假)则执行语句块2,选择结构,不平衡的ifelse语句(单分支if),ifelse语句(双分支if),表达式的值可以是任何类型,条件表达式和逻辑表达式最常用,不平衡的ifelse语句(if语句),不执行操作,2020/5/25,11,程序4.1求任意三角形的面积#include#include/包含平方根函数sqrt的声明intmain()doublea,b,c,s,area;/定义5个double变量printf(“Pleaseinputa,b,c:n”);/屏幕提示scanf(“%lf%lf%lf”,选择结构(if语句),问题1:可能会输入负数问题2:即使输入的都是正数,未必能构成一个三角形顺序结构无法解决需要作出判断的问题!,程序4.2改进程序4.1,在构成三角形时求面积,否则给提示信息,if(a0,此else分支不能省略,否则在不能构成三角形时将没有任何输出,就不是一个正确的算法了,2020/5/25,12,程序4.3生成50以内的两个随机数,比较大小,输出较大者及两者之差的值。若第1个数大于第2个数,输出youarelucky!#include#include/含srand和rand函数的原型#include/含time函数的原型intmain()inta,b;/定义两个整型变量a和bsrand(time(NULL);/调用当前系统时钟产生随机种子a=rand()%50;/产生一个50以内的随机数赋给ab=rand()%50;/产生另一个50以内的随机数赋给bif(ab)/如果a大于bprintf(thelargernumberisa:%dn,a);/输出较大者printf(a-b=%dn,a-b);/输出a与b的差值else/如果a不大于b,即ab)printf(youarelucky!n);/if语句return0;,选择结构(if语句),若删除此句,则每次产生的随机数都是一样的,这是调用系统时钟产生随机种子,上机运行观察结果,上机测试观察运行结果并分析:(1)删除srand(time(NULL);(2)删除else后的一对大括号,若删除此一对括号,则语句printf(“b-a=%dn”,b-a);成为一条不受条件控制的语句,2020/5/25,13,ifelse语句形式:if(表达式)语句块1else语句块2if语句形式:if(表达式)语句块1最常用的嵌套ifelse语句形式:if(表达式1)语句块1elseif(表达式2)语句块2else语句块n,选择结构(if语句),else总是与其前面与之最靠近的并且未与其它else匹配过的if相对应;每个else都代表了与其对应if完全相反的条件,编程时应充分利用else所代表的条件简化程序,整个嵌套的ifelse语句从语法上仍为一条语句,2020/5/25,14,选择结构(if语句),程序4.4用嵌套if进行符号函数求解#includeintmain()intx,sign;printf(Pleaseinputx:);scanf(%d,/语句2处嵌入ifelse,此else代表的条件是x0)sign=1;elsesign=0;elsesign=-1;,语句1处嵌入ifelse,此else代表的条件是x0,此else代表的条件是x=0,显然左边的方法更直观,此题还有多种其他写法请读者思考,2020/5/25,15,选择结构(if语句),程序4.5根据输入的百分制成绩score,转换成相应的五分制成绩grade并打印输出。转换标准为:.intscore;chargrade;/定义两个变量scanf(%d,/输出百分成绩及等级.,有效的分数应满足:0=score=100,此else代表的条件为:0=scorechargrade;/定义两个变量scanf(%d,.,选择结构(switch语句),方法二:用switch语句实现百分制转五级分制,此break可以省略,在VC+下运行程序观察结果,遗憾:每次运行程序只能输入一个成绩,一次运行无法输入多个百分成绩进行转换!,9月22日8:00-9:30教2-325上机,做实验一顺序结构编程练习,请务必提前做好准备!,#include#definePI3.14159intmain()doubler,h,s1,s2,v;printf(“请输入圆柱地面半径和高(用空格格隔开,输入完请回车):);scanf(r=%lf,h=%lf,r,h);s1=2*r*PI*h;s2=s1+r*r*PI*2;v=r*r*PI*h;,1、程序纠错,printf(侧面积:s1=%dn,s1);printf(表面积:s2=%dn,s2);printf(体积:v=%dn,v);return0;,课堂练习,2.分析以下程序的运行结果:main()intx,y,z,w;z=(x=1)?(y=1,y+=x+5):(x=7,y=3);w=y*a/4;printf(“%d%d%d%dn”,x,y,z,w);,正确答案177169,3.以下程序的输出结果是,#includemain()inta=1,b=-1,c=3;if(ab)if(bn)break;,循环次数确定,2020/5/25,24,程序4.7输入1个正整数m,判断m是否为质数,输出判断结果质数的概念:大于1的自然数中,除了1和它自己外,不能被任何其他整数所整除的数。算法思路:设一个变量prime表示结果,值为1表示是质数,值为0则不是质数最初可以先假定m是质数,即prime初值为1,设一个变量i作为除数,从2变化到m-1,只要其中有一个能被m整除(即满足m%i=0),就说明m不是质数,立即修改prime为0,否则继续取下一除数计算除数终值到底取多少:除数的终值需要到m-1吗?数学已上证明,除数最大只要到sqrt(m)就已经保证所有可能的因子均已被判断循环条件的控制:本题是循环次数不可确定的循环问题,用for语句也可以解决.以上分析表明循环终止有两种可能:(1)被某一个i整除,(2)i的值已变到终值处.因此循环条件体现为两个条件共同控制,即:primedoublefac=1;printf(Pleaseinputn:n);scanf(“%d”,方法二:改用while循环求阶乘,i=1;while(i=n)fac*=i;i+;,2020/5/25,28,程序2.2:三位的非负整数按位分离输出,#includeintmain()inti,n;/定义两个整型变量i,n,变量先定义后使用n=578;/通过赋值语句使n获得一个3位整数值i=n%10;/对10取余求得个位数printf(%d,i);/输出个位数i=n/10%10;/先整除10再对10取余求得十位数printf(%d,i);/输出十位数i=n/100;/用整除100求得百位数printf(%dn,i);/输出百位数return0;,该程序显然不具有通用性,不能处理任意位数的整数按位分离问题,2020/5/25,29,循环结构(while语句),程序4.8从键盘读入任意位的非负整数,按位分离后逆序输出#includeintmain()inti,n;scanf(“%d”,算法思想:在被处理的数不等于0时:(1)利用对10取余得到个位数(2)输出该个位数(3)对被分离的数利用整除10降一阶,若不为0回到步骤(1)若为0停止处理,等价于n!=0,用循环求解问题的关键:(1)以什么作为控制循环的条件(2)重复不断地执行的是哪些操作,即循环体是什么(3)在循环体内对变量如何变化每个变量的意义要明确,2020/5/25,30,循环结构(while语句),程序4.9从键盘读入两个正整数,用辗转相除法求最大公约数#includeintmain()intdividend,divider,remainder;./读入dividend,dividerremainder=dividend%divider;while(remainder)dividend=divider;divider=remainder;remainder=dividend%divider;printf(hcd:%dn,divider);return0;,算法思想:(1)将两个正整数分别作为被除数(dividend)和除数(divider)(2)被除数整除除数得余数(remainder)(3)若余数不为0,则除数转为被除数,余数转为除数,继续步骤(2)(4)若余数为0则结束循环,使余数为0的除数就是最大公约数,余数不为0为循环条件,上一次的除数作为下次的被除数,上一次的余数作为下次的除数,求新的余数,使余数为0的除数就是最大公约数,第一次求余数,2020/5/25,31,while语句与for语句都控制当型循环,共同特点:先判断循环条件,为真才执行循环体,故循环体最少执行0次dowhile语句控制直到型循环,其特点是:先执行循环体,再判断条件,当条件为真时继续执行循环体,条件为假,循环结束。因此循环体至少执行1次。dowhile语句的形式:do语句块while(表达式);执行过程见右边流程图,循环结构(dowhile语句),假,表达式,真,语句块,循环控制条件,循环体,可以是多条语句,此处一定要有分号,2020/5/25,32,循环结构(dowhile语句),程序4.10模拟投骰子,以6点为目标,投中目标两次获胜,最多允许投10次(方法1:用dowhile语句)#include#include#includeintmain()intcount=0,y=0,dice;srand(time(0);dodice=1+rand()%6;count+;if(dice=6)y+;while(count10,模拟投骰子可以通过调用随机函数产生1至6之间的随机数.在程序中必须设置一个变量用来统计已经投了多少次,再设另一个变量统计投中了多少次。投骰子的动作肯定要做,且做一次还不能完成,因此适合使用dowhile语句实现。循环体应该完成:(1)调用随机函数产生一个随机数来模拟投骰子;(2)统计投掷次数的变量无条件加1;(3)如果随机数的值等于6,则统计投中次数的变量值加1循环条件是:投掷次数小于10并且投中次数小于2,记录投中的次数,记录投掷的次数,记录点数,产生随机种子,生成16随机数模拟投骰子,投掷次数无条件加1,如果点数等于6,投中次数加1,投掷次数小于10且投中次数小于2为循环条件,输出投掷次数和投中次数,2020/5/25,33,循环结构(dowhile语句),程序4.10模拟投骰子,以6点为目标,投中目标两次获胜,最多允许投10次(方法1:用dowhile语句)#include#include#includeintmain()intcount=0,y=0,dice;srand(time(0);dodice=1+rand()%6;count+;if(dice=6)y+;while(count10,while(count10,(方法2:用while语句),此处不能加分号,如果加了分号,语法上正确,表示该循环体为空语句,而语句块就成为一条无条件的语句,结果将出错,(方法3:用for语句),for(;count0:n);scanf(%d,读到第一个大于0的整数就停止,本节作业:P74三1,2,3,有条件的同学可以打印作业。,2020/5/25,37,循环嵌套,循环嵌套最主要的是理解其三种循环控制语句的循环体内可以嵌入更深层次的循环控制语句,从而构成了循环的嵌套,3种语句可以互相嵌套。,执行过程:(1)先对外层循环控制变量取一个值,满足条件进入循环体(2)执行循环体中的内层循环,内层循环结束后,回到外层(3)改变外层循环控制变量的值,回到步骤(1)(4)当外层循环条件不满足时停止整个循环,例如:小时,例如:分,例如:秒,2020/5/25,38,例4.12:从键盘上输入1个正整数n,求1!+2!+3!+n!的结果#includeintmain()inti,j,n;doublef,sum=0;doprintf(Pleaseinputn:n);scanf(%d,内循环,求i!,外循环,求1!+2!+n!,如果读入3,结果sum=9.000000E+000,2020/5/25,39,循环嵌套,程序4.13打印一个由*号组成的五行等腰上三角形。#includeintmain()inti,j;for(i=1;i=5;i+)for(j=1;j=(5-i)+14;j+)/+14使图形居中printf(%2c,);/打印前导空格for(j=1;j=2*i-1;j+)/打印本行图形printf(%2c,*);printf(n);/换行return0;,外层循环控制行的变化,n,n;,scanf(“%d”,n,n-i,打印一个n行等腰上三角形,每行图形依次为ABCD,读入控制的完整代码如教材所示,用dowhile保证n在一定的范围内,i+64);,算法:一般用两层循环打印一个形状规则的图形外层循环控制行变化外层循环体中依次完成下面3个步骤:(1)根据行数和图形的形状,打印每行的前导空格(确定本行图形的起始位置)。若行号为i,i从1开始计,考虑最后一行(假设为n)前不留前导空格,则第i行前导空格的单位为:n-i,用一个内层循环控制打印前导空格(2)根据行号与当前行图形的个数及形状的关系进行控制输出当前行的图形。等腰三角形,其图形元素个数为2*i-1,这里i为当前行的行号,用一个内层循环打印图形(3)换行,2020/5/25,40,一个用穷举法解决问题的典型例,注意算法设计的重要性,同一题有多种解法,效率不一样.程序4.14百钱百鸡问题:鸡翁一,值钱5;鸡母一,值钱3;鸡雏三,值钱1。百钱买百鸡,问鸡翁、母、雏各几何?分析:设公鸡,母鸡和雏鸡的数量分别为x,y,z,有下列关系成立:x+y+z=100(百鸡)5x+3y+z/3=100(百钱)15x+9y+z=300(百钱)3个变量的范围:0=x=20,0=y=33,0=z=100,循环嵌套,2020/5/25,41,/例4.14百鸡百钱问题方法1/用3层循环控制#includeintmain(void)intx,y,z;for(x=0;x=20;x+)for(y=0;y=33;y+)for(z=0;z=100;z+)if(x+y+z=100,满足百鸡,满足百钱,同时满足,2,两,z=100-x-y;,利用百鸡条件用x,y的表达式表示z,从而去掉第3层循环,if(,这时只需要判断百钱的条件就可以了,2020/5/25,42,break语句的用法1:用于switch语句中,表示结束该分支的操作,从而结束switch语句,真正实现了多分支控制break语句的用法2:用于3种循环语句的循环体中,配合一定的条件,执行到break直接退出本层循环,从而增加了从循环体中结束循环的方式(此前只能因循环控制条件为假而终止循环)程序4.10模拟投骰子问题的第4种实现方法使用break语句模拟投骰子循环条件是两个:投掷次数小于10并且投中次数小于2,前3种方法都是将这两个条件同时列在控制循环的条件表达式中,用break就可以减少一个循环条件,其他流程控制语句(break),2020/5/25,43,程序4.10模拟投骰子问题的第4种实现方法循环体中使用break语句,#include#include#includeintmain()intcount=0,y=0,dice;srand(time(0);while(count10,两个条件同时满足,这是原方法2的代码,用while语句控制循环,if(y=2)break;,),减少一个条件,break用于循环体中,一般要配合if使用才有意义,流程图,增加了从循环体中退出循环的出口,2020/5/25,44,continue语句的用法:只能用于循环语句的语句块中continue语句的功能:提前结束本次循环,忽略循环体中其后的语句,直接进入下一次条件的判断与break语句不同:continue不能退出循环程序4.10模拟投骰子问题的第5种实现方法使用continue语句模拟投骰子的循环体中,变量y自增1是有条件的,必须在dice=6时,换句话说,当dice!=6时,y+不执行,这可以用continue来改写,其他流程控制语句(continue),2020/5/25,45,程序4.10模拟投骰子问题的第5种实现方法循环体中使用continue语句,#include#include#includeintmain()intcount=0,y=0,dice;srand(time(0);while(count10,两个条件同时满足,这是原方法2的代码,用while语句控制循环,流程图,!,continue;,增加了一种提前结束循环体回到循环条件重新判断的方式,1设有程序段intk=10;while(k=0)k=k-1;这下面描述中正确的是_.a)while循环执行10次b)循环是无限循环c)循环体语句一次也不执行d)循环体语句执行一次,C正确,因为k被赋值为0,while中的条件为假,随堂练习,2.下面程序段的运行结果是_.intn=0;while(n+=2);printf(%d,n);a)2b)3c)4d)有语法错,正确答案选C,因为n+是先取n的当前值作为表达式的结果,之后n再自增。因此当n+表达式的值为3时退出循环,此时n的值已自增为4,随堂练习,3.以下程序段_.x=-1;dox=x*x;while(!x);a)是死循环b)循环执行二次c)循环执行一次d)有语法错误,正确答案选C,随堂练习,4.下面程序的运行结果是_.#includevoidmain()inta,s,n,count;a=2;s=0;n=1;count=1;while(count=6)n=n*a;s=s+n;+count;printf(“s=%dn,s);,正确答案126,随堂练习,5.下面程序段的运行结果是_i=1;s=3;dos+=i+;if(s%7=0)continue;else+i;while(s15);printf(%d,i);,正确答案8,随堂练习,6.下面程序段的运行结果是_#includemain()intk;for(k=1;k5;k+)switch(k)case1:case2:printf(“%dn”,k);case3:printf(“%dn”,k);break;default:printf(“OK!n”);,正确答案11223OK!,随堂练习,7.调试下面程序,并给出的运行结果_#includemain()inti,j,k;charspace=;for(i=1;i=4;i+)for(j=1;j=i;j+)printf(“%c”,space);for(k=1;k=6;k+)printf(“*”);printf(“n”);,平面图形、表格的处理和输出,常见题型!,双重for循环,随堂练习,8.求Sn=a+aa+aaa+aaaa之值,其中a是一个数字,例如2+22+222+2222,此时n=4,a,n由键盘输入。,算法分析:等式Sn=a+aa+aaa+aaaa可以写成Sn=T1+T2+T3+.Tn,其中T1=a,Tn=Tn-1*10+a在程序中用sn表示累加之和,tn表示第n项,编程,单重循环求解累加和问题,前后项之间相关的累加求和,随堂练习,用for循环语句实现,#includemain()intn,j;longinta,sn=0,tn=0;scanf(“%ld,%d”,前后项相关的累加(累乘),常见题型!,关键:寻找累加项的构成规律单重循环for循环次数已知while,dowhile循环次数未知,随堂练习,9.利用右式求pi,#includemain()inti;floatterm,pi=1;for(i=2;i寻找一定范围内所有的质数,哥德巴赫猜想求两个整数的最大公约数-求两数的最小公倍数,多个数的最大公约数按位分离十位数的每一位数字-进制转换问题项数确定或要求精度的格里高利公式求和-求和题的解法模拟投骰子游戏的多种实现-猜字谜游戏的灵活设计打印等腰三角形-规则图形的打印方法百鸡百钱问题的多种解法-穷举题的一题多解及算法效率掌握一些实用技术:用dowhile语句保证读入符合特定要求的数据调用srand(time(NULL)产生随机种子,保证数的随机性调用rand()函数产生一定范围的随机整数,下周一13:45-15:20教2-325实验二选择和循环结构编程练习务必提前做好准备,本节作业:P74三4,5,7,9,第6,8题选做,有条件的同学可以打印作业。,下周一13:00-13:45教2-316答疑,静候光临!,Theendofchapter4,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!