关关雎鸠南邮C语言课件第4章_第1页
关关雎鸠南邮C语言课件第4章_第2页
关关雎鸠南邮C语言课件第4章_第3页
关关雎鸠南邮C语言课件第4章_第4页
关关雎鸠南邮C语言课件第4章_第5页
已阅读5页,还剩87页未读 继续免费阅读

下载本文档

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

文档简介

高级语言程序设计

2022/12/191高级语言程序设计2022/12/171第四章程序流程控制主讲:计算机学院朱立华第四章程序流程控制主讲:计算机学院朱立华内容提要算法的基本概念以及表示方法,简单介绍流程图C程序的3种基本流程控制结构:顺序结构、选择结构(也叫分支结构)、循环结构,每种结构的控制语句:if、switch控制选择结构for、while、do~while控制循环结构break、continue、goto等语句的用法循环嵌套程序的设计及运行过程一些常用算法的基本思想:分段函数求解问题判断一个整数是否为质数求两个正整数的最大公约数各种求和问题掷骰子游戏的多种解法求阶乘打印规则的图形穷举问题的多种求解方法2022/12/193内容提要算法的基本概念以及表示方法,简单介绍流程图掷骰子游戏算法与语句

算法(Algorithm)就是为解决一个具体问题而采取的有限的操作步骤,算法通过语句来实现计算机算法分两类:数值运算算法、非数值运算算法程序=数据结构+算法算法的正确性衡量标准:有穷性:算法包含有限步操作确定性:每一步都应确定无歧义有效性:每一步都应能有效执行且能得到确定的结果0或多个输入:程序允许无输入1或多个输出:任何程序都必须有输出,哪怕是提示信息解决求数值解的问题解决需要用分析推理、逻辑推理才能解决的问题

数据的描述和组织形式

对操作或行为的描述,即操作步骤

2022/12/194算法与语句算法(Algorithm)就是为解决一个具体问题算法与语句

常用的算法描述方法有:自然语言、传统流程图、NS流程图、伪代码等,这里只介绍传统流程图。例:求n!的算法思想:n!=1*2*3*…*n由于计算机执行乘法时每次只能求两个数相乘,因此上面的公式在程序中必定需要通过反复相乘来实现。需要设定一个变量n,表明求多少的阶乘;第二个变量,存当前累乘的结果;第三个变量存当前将要与累乘器相乘的因子,并且该因子的变化是从1到n每次增加1流程图如下页所示2022/12/195算法与语句常用的算法描述方法有:自然语言、传统流程图、NSno开始n<0?输入n图4.2计算n!的传统流程图fac=1,i=1fac=fac*ii=i+1i<=n?yes输出fac值no结束输出错提示yes开始结束框输入/输出框判断框一般处理框循环结构3种基本结构的特点:单入口,单出口流程线选择结构顺序结构查看程序2022/12/196no开始n<0?输入n图4.2计算n!的传统流程图facC语句分类C语言的语句有五大类:(1)9种控制语句:这一类语句用于实现流程控制,选择结构和循环结构必须通过控制语句实现。if~else语句:是实现选择结构最常用的语句switch语句:用于控制某些多分支的选择结构for()~语句:最常用最灵活的循环控制语句,当型循环while()~语句:循环结构最安全的控制语句,当型循环do~while()语句:控制先执行后判断的直到型循环结构continue语句:表示提前结束本次循环,忽略其后循环体中的其他语句break语句:可用于switch语句(结束switch)或循环体中(结束本层循环)goto语句:流程跳转语句,很灵活,可实现各种结构,建议少用或不用

return语句:专门用于函数返回,被调函数执行到return就返回到调用点(2)变量声明语句:用来定义变量,形如:inta,b;(3)表达式语句:C语言中任何一个表达式最后加上分号构成表达式语句,赋值语句和函数调用语句是最常用的表达式语句(4)复合语句:以一对大括号括起的0或多条语句,在语法上仍为一条语句(5)空语句:只有一个分号构成的语句,表示什么也不做2022/12/197C语句分类C语言的语句有五大类:2022/12/177顺序结构顺序结构的特点:语句按顺序依次执行,不涉及到任何条件的判断。顺序结构所使用的语句:变量声明语句、读写函数调用语句、赋值语句、return语句等。无需用其他流程控制语句优点:结构简单易懂缺点:对程序的健壮性、完备性往往无法兼顾例:程序4.1从键盘上输入a,b,c的值,并以它们为三角形的三条边,求三角形的面积。

算法思想:根据数学知识,设一个变量s用于求三角形周长的一半,即s=(a+b+c)/2,再利用一般三角形求面积的公式求解:2022/12/198顺序结构顺序结构的特点:语句按顺序依次执行,不涉及到任何条件程序4.1求任意三角形的面积#include<stdio.h>#include<math.h> //包含平方根函数sqrt的声明intmain(){doublea,b,c,s,area;//定义5个double变量printf(“Pleaseinputa,b,c:\n”);

//屏幕提示

scanf("%lf%lf%lf",&a,&b,&c);//输入a,b,c的值s=(a+b+c)/2;//求周长的一半area=sqrt(s*(s-a)*(s-b)*(s-c));//求面积printf("area=%f\n",area);//输出面积

return0;}顺序结构<运行结果>输入345输出area=6.000000

编程提示:存原始数据的变量,用读入方式使其获得的值更灵活,也可赋值,但是通用性下降编程提示:如果变量的值需要根据其他变量或一定的计算规则计算出来,则使用赋值语句而不能读入问题1:可能会输入负数问题2:即使输入的都是正数,未必能构成一个三角形顺序结构无法解决需要作出判断的问题!!动态演示过程2022/12/199程序4.1求任意三角形的面积顺序结构<运行结果>编程提示:选择结构的特点:通过某一个或若干条件的约束,有选择性地执行特定语句--在符合一定条件时,执行特定操作;在不符合条件时,不执行操作或执行另外的操作

选择结构使用的流程控制语句:if语句、switch语句优点:保证程序的健壮性、完备性if~else语句形式:

if(表达式)语句块1

else

语句块2执行过程:先计算表达式,若非0(真)则执行语句块1;如果表达式为0(假)则执行语句块2

选择结构不平衡的if~else语句(单分支if)

if~else语句(双分支if)

表达式可以是任何类型的,条件表达式和逻辑表达式最常用语句块通常用复合语句实现,若复合语句内只有一条语句,则一对大括号可以不写表达式真假语句块1语句块2不平衡的if~else语句(if语句)不执行操作2022/12/1910选择结构的特点:通过某一个或若干条件的约束,有选择性地执行特程序4.1求任意三角形的面积#include<stdio.h>#include<math.h> //包含平方根函数sqrt的声明intmain(){doublea,b,c,s,area;//定义5个double变量printf(“Pleaseinputa,b,c:\n”);

//屏幕提示

scanf(“%lf%lf%lf”,&a,&b,&c);//输入a,b,c的值s=(a+b+c)/2;area=sqrt(s*(s-a)*(s-b)*(s-c));//求面积printf(“area=%f\n”,area);//输出面积

return0;}选择结构(if语句)问题1:可能会输入负数问题2:即使输入的都是正数,未必能构成一个三角形顺序结构无法解决需要作出判断的问题!!程序4.2改进程序4.1,在构成三角形时求面积,否则给提示信息if

(a>0&&b>0&&c>0&&a+b>c&&a+c>b&&b+c>a){elseprintf("Errorinput!\n");

}此else分支不能省略,否则在不能构成三角形时将没有任何输出,就不是一个正确的算法了动态演示过程2022/12/1911程序4.1求任意三角形的面积选择结构(if语句)问题1:可程序4.3生成50以内的两个随机数,比较大小,输出较大者及两者之差的值。若第1个数大于第2个数,输出youarelucky!#include<stdio.h>#include<stdlib.h>

//含srand和rand函数的原型#include<time.h>//含time函数的原型intmain(){ inta,b; //定义两个整型变量a和b srand(time(NULL));//调用当前系统时钟产生随机种子

a=rand()%50;//产生一个50以内的随机数赋给a b=rand()%50;//产生另一个50以内的随机数赋给b if(a>b) //如果a大于b

{printf(“thelargernumberisa:%d\n”,a);

//输出较大者printf("a-b=%d\n",a-b);}

//输出a与b的差值

else {

//如果a不大于b,即a<=b printf(“thelargernumberisb:%d\n”,b);

//输出较大者

printf("b-a=%d\n",b-a); }//输出b与a的差值 if(a>b) printf(“youarelucky!\n”);//if语句

return0;}选择结构(if语句)若删除此句,则每次产生的随机数都是一样的,这是调用系统时钟产生随机种子上机运行观察结果上机测试观察运行结果并分析:(1)删除srand(time(NULL));

(2)删除else后的一对大括号若删除此一对括号,则语句printf(“b-a=%d\n”,b-a);成为一条不受条件控制的语句动态演示过程2022/12/1912程序4.3生成50以内的两个随机数,比较大小,输出较大者及if~else语句形式:

if(表达式)语句块1

else

语句块2if语句形式:

if(表达式)语句块1最常用的嵌套if~else语句形式:

if(表达式1)语句块1

else

if(表达式2)语句块2…else语句块n选择结构(if语句)在语句块处还可以嵌入if或if~else语句,形成形式多样的嵌套if语句,以解决多分支(>=3)的处理问题else总是与其前面与之最靠近的并且未与其它else匹配过的if相对应;每个else都代表了与其对应if完全相反的条件,编程时应充分利用else所代表的条件简化程序整个嵌套的if~else语句从语法上仍为一条语句2022/12/1913if~else语句形式:选择结构(if语句)在选择结构(if语句)程序4.4用嵌套if进行符号函数求解#include<stdio.h>intmain(){intx,sign;printf("Pleaseinputx:");scanf("%d",&x);

if(x>0) sign=1;

else

if(x==0)sign=0;

else sign=-1;printf("x=%d,sign=%d\n",x,sign);return0;}

1sign=

0-1//语句2处嵌入if~else此else代表的条件是x<=0此else代表的条件是x<0if(x>=0) if(x>0)sign=1;

else sign=0;else sign=-1;语句1处嵌入if~else此else代表的条件是x<0此else代表的条件是x==0显然左边的方法更直观此题还有多种其他写法请读者思考动态演示过程2022/12/1914选择结构(if语句)程序4.4用嵌套if进行符号函数求解选择结构(if语句)程序4.5根据输入的百分制成绩score,转换成相应的五分制成绩grade并打印输出。转换标准为:……………..

intscore;chargrade;//定义两个变量scanf("%d",&score);//从键盘输入百分制成绩if(score>100||score<0)printf("Inputerror!\n");else{

if(score>=90)grade='A';

elseif(score>=80)grade='B';

elseif(score>=70) grade='C';

elseif(score>=60) grade='D';

elsegrade='E'; printf(“%d--%c\n”,score,grade);//输出百分成绩及等级}……………..A90≤score≤100B80≤score<90grade=C70≤score<80D60≤score<70E0≤score<60

有效的分数应满足:0<=score<=100此else代表的条件为:0<=score&&score<=100

完整的条件为:90<=score&&score<=100

此else代表的条件为:0<=score&&score<90

完整的条件为:80<=score&&score<90

此else代表的条件为:0<=score&&score<80

完整的条件为:70<=score&&score<80

此else代表的条件为:0<=score&&score<70

完整的条件为:60<=score&&score<70

此else代表的条件为:0<=score&&score<60

动态演示过程2022/12/1915选择结构(if语句)程序4.5根据输入的百分制成绩sco选择结构(switch语句)switch语句是控制选择结构流程的又一主要语句,某些嵌套的if-else语句可以改用switch语句switch~case的语句格式为:switch(表达式){case

常量表达式1:语句系列1case

常量表达式2:语句系列2…case

常量表达式n:语句系列n[default:

语句系列n+1]}表达式类型可以是整型、字符型、枚举型,但不能是实型

常量表达式是switch中的表达式可能得到的有限个常量值,类型应与switch中的表达式一致

每个case后只能有1个常量表达式,switch中的表达式计算得到的结果与哪一个常量表达式的值相等,程序流程就从该常量后开始,执行其后的语句系列default分支语法上可以省略,但是建议要有,这表示switch后的表达式与以上n个常量表达式都不相等的时候所进行的处理,有利于提高程序的健壮性break语句和switch最外层的右大括号就是该选择结构的出口,遇到第一个break结束,如果没有break则到右大括号才结束2022/12/1916选择结构(switch语句)switch语句是控制选择结构流程序4.5根据输入的百分制成绩score,转换成相应的五分制成绩grade并打印输出。转换标准为:……………..

intscore;chargrade;//定义两个变量scanf("%d",&score);//从键盘输入百分制成绩if(score>100||score<0)printf("Inputerror!\n");else{

if(score>=90)grade='A';

elseif(score>=80)grade='B';

elseif(score>=70) grade='C';

elseif(score>=60) grade='D';

elsegrade='E'; printf(“%d--%c\n”,score,grade);}……………..switch(score/10)//为减少常量的个数{ case10: case9:grade='A';break;

case8:grade='B';break;

case7:grade='C';break;

case6:grade='D';break;

case5: case4: case3: case2:case1:case0:grade='E';break;}选择结构(switch语句)方法二:用switch语句实现百分制转五级分制这些break都不能省略此break可以省略在VC++下运行程序观察结果,遗憾:每次运行程序只能输入一个成绩,一次运行无法输入多个百分成绩进行转换!动态演示过程2022/12/1917程序4.5根据输入的百分制成绩score,转换成swit循环结构的特点:某些操作在一定条件约束下在程序中可被重复执行,或者重复执行到满足一定的条件时停止

循环结构使用的流程控制语句:for语句、while语句、do~while语句;辅助语句:break语句、continue语句for语句形式:

for(表达式1;表达式2;表达式3)

语句块执行过程见右边流程图注意:for语句中的3个表达式可以省略

1个或多个,最多3个都可省略,但是

分号不能省,且应保证执行结果不变,不能死循环

循环结构当型循环

直到型循环

用于求初值,只计算一次用来作为控制循环的条件,非0值则执行语句块;若为0,则结束for语句语句块执行结束后自动执行此表达式,然后再重新计算表达式2就是循环体,通常用复合语句,只能是一条语句整个for语句在语法上就是一条语句假表达式2真语句块表达式1表达式32022/12/1918循环结构的特点:某些操作在一定条件约束下在程序中可被重复执行循环结构(for语句)程序4.6从键盘上输入一个非负整数n,求n!

#include<stdio.h>intmain(){intn,i;//定义两个整型变量,i表示乘数

doublefac=1;printf("Pleaseinputn:\n");//提示输入数据的信息scanf(“%d”,&n);//从键盘上输入一个整数值

if(n<0)printf("Errorinput!\n");//如果是负数

else

//此else所代表条件是n>=0

{ for(i=1;i<=n;i++)

//用for语句实现循环

fac*=i;

//累乘器作为被乘数与乘数i相乘

printf("%d!=%e\n",n,fac);//累乘器中的结果是n!的值

}

return0;}若输入为:-5<回车>输出结果为:Errorinput!若输入为:4<回车>输出结果为:4!=2.400000e+001若输入为:100<回车>输出结果为:100!=9.332622e+157查看流程fac的类型应当定义为double类型,因为阶乘的结果很容易非常大,应当定义范围最广的数据类型作为累乘器的类型,并且一定要初始化为1

对n作判断,保证程序的健壮性用%e以指数形式输出一个较大的结果比较合理

执行的操作不变,但是变量是在不断变化的for语句中表达式省略示例=1;++;{fac*=i++;if(i>n)break;}循环次数确定动态演示过程2022/12/1919循环结构(for语句)程序4.6从键盘上输入一个非负整数n程序4.7

输入1个正整数m,判断m是否为质数,输出判断结果

质数的概念:除了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的值已变到终值处.因此循环条件体现为两个条件共同控制,即:prime&&i<=(int)sqrt(m)特殊正整数的处理:当m为1时,直接给出prime=0,不必循环循环结构(for语句)2022/12/1920程序4.7输入1个正整数m,判断m是否为质数,输出判断结果循环结构(for语句)程序4.7

从键盘输入一个正整数m,判断m是否为质数,输出判断结果

#include<stdio.h>#include<math.h>

//包含sqrt的原型

intmain(){intm,i,k,prime=1; scanf("%d",&m);

if(m<=0){printf("Inputerror!\n");return0;}

if(m==1)prime=0;k=(int)sqrt(m); //求m的平方根

for(i=2;prime&&i<=k;i++)

//i为除数

if(m%i==0)prime=0;

if(prime)

printf("%disaprime\n",m);

elseprintf("%disnotaprime\n",m);

return0;}对prime的初始化不能缺少如果m是负数,则返回不再进行判断对于特殊正整数1直接给出不是质数的结论变量k存除数的上界变量i是每一次参与运算的除数,从2变化到k,增加步长为1用两个条件共同控制,循环必将因为prime为0或i>k而终止,前者表明m不是质数,后者表明m是质数,prime保持初值1判断m是否能被i整除,若能则prime赋值为0,不是质数循环终止时prime可能为1可能为0,根据其值输出不同的结论循环体是这一条if语句动态演示过程2022/12/1921循环结构(for语句)程序4.7从键盘输入一个正整数m,判while语句:与for语句一样能控制当型循环while语句的形式:

while(表达式)

语句块执行过程见右边流程图for语句与while语句的等价关系:(1)for中的表达式1相当于出现在while之前的对循环变量的初始化(2)for语句的表达式2相当于while语句的表达式,都表示当该表达式为真时执行循环体

(3)for语句的语句块和表达式3一起,相当于while循环的语句块,是被反复执行的循环体循环结构(while语句)假表达式真语句块循环控制条件循环体,通常用一条复合语句2022/12/1922while语句:与for语句一样能控制当型循环循环结构(wh循环结构(while语句)程序4.6从键盘上输入一个非负整数n,求n!

#include<stdio.h>intmain(){intn,i;

doublefac=1;printf("Pleaseinputn:\n");scanf(“%d”,&n);

if(n<0)printf("Errorinput!\n");

else

{ for(i=1;i<=n;i++)

fac*=i;

printf("%d!=%e\n",n,fac);

}

return0;}方法二:改用while循环求阶乘i=1;while(i<=n){fac*=i;i++;}

再论for与while:虽然都可处理当型循环,for语句一定可以转化为等效的whie语句,但是并不是所有的while都可以等效转为for。因为在while语句中,可以有条件地修改循环控制变量的值,而for语句中修改循环控制条件一般通过表达式3,是无条件执行的。从这个意义上看,while的使用范围比for更广,但for语句更简洁2022/12/1923循环结构(while语句)程序4.6从键盘上输入一个非负整程序2.2:三位的非负整数按位分离输出

#include<stdio.h>intmain(){ 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("%d\n",i);//输出百位数

return0;} 该程序显然不具有通用性,不能处理任意位数的整数按位分离问题2022/12/1924程序2.2:三位的非负整数按位分离输出#includ循环结构(while语句)程序4.8从键盘读入任意位的非负整数,按位分离后逆序输出#include<stdio.h>intmain(){inti,n;scanf(“%d”,&n);

//读入n

if(n<0)n=-n;

//保证n>=0

while(n)

{

i=n%10;

//求余

printf("%d",i);

//输出

n=n/10;

//n降阶

} printf("\n");

return0;}算法思想:在被处理的数不等于0时:(1)利用对10取余得到个位数(2)输出该个位数(3)对被分离的数利用整除10降一阶,若不为0回到步骤(1)若为0停止处理等价于n!=0用循环求解问题的关键:(1)以什么作为控制循环的条件(2)重复不断地执行的是哪些操作,即循环体是什么(3)在循环体内对变量如何变化每个变量的意义要明确动态演示过程2022/12/1925循环结构(while语句)程序4.8从键盘读入任意位的非负循环结构(while语句)程序4.9从键盘读入两个正整数,用辗转相除法求最大公约数

#include<stdio.h>intmain(){intdividend,divider,remainder;

…..

//读入dividend,dividerremainder=dividend%divider;while(remainder){dividend=divider;

divider=remainder;remainder=dividend%divider;} printf("hcd:%d\n",divider);

return0;}算法思想:(1)将两个正整数分别作为被除数(dividend)和除数(divider)

(2)被除数整除除数得余数(remainder)

(3)若余数不为0,则除数转为被除数,余数转为除数,继续步骤(2)(4)若余数为0则结束循环,使余数为0的除数就是最大公约数

余数不为0为循环条件上一次的除数作为下次的被除数上一次的余数作为下次的除数求新的余数使余数为0的除数就是最大公约数第一次求余数动态演示过程2022/12/1926循环结构(while语句)程序4.9从键盘读入两个正整数,while语句与for语句都控制当型循环,共同特点:先判断循环条件,为真才执行循环体,故循环体最少执行0次do~while语句控制直到型循环,其特点是:先执行循环体,再判断条件,当条件为真时继续执行循环体,条件为假,循环结束。因此循环体至少执行1次。do~while语句的形式:

do{

语句块}while(表达式);执行过程见右边流程图循环结构(do~while语句)假表达式真语句块循环控制条件循环体,可以是多条语句此处一定要有分号2022/12/1927while语句与for语句都控制当型循环,共同特点:先判断循循环结构(do~while语句)程序4.10模拟投骰子,以6点为目标,投中目标两次获胜,最多允许投10次(方法1:用do~while语句)

#include<stdio.h>#include<stdlib.h> #include<time.h> intmain(){intcount=0,y=0,dice;

srand(time(0)); do

{ dice=1+rand()%6;

count++; if(dice==6)y++;

}while(count<10&&y<2);printf("%d,%d\n",count,y); return0;}模拟投骰子可以通过调用随机函数产生1至6之间的随机数.在程序中必须设置一个变量用来统计已经投了多少次,再设另一个变量统计投中了多少次。投骰子的动作肯定要做,且做一次还不能完成,因此适合使用do~while语句实现。循环体应该完成:(1)调用随机函数产生一个随机数来模拟投骰子;(2)统计投掷次数的变量无条件加1;(3)如果随机数的值等于6,则统计投中次数的变量值加1循环条件是:投掷次数小于10并且投中次数小于2记录投中的次数

记录投掷的次数记录点数

产生随机种子

生成1~6随机数模拟投骰子投掷次数无条件加1

如果点数等于6,投中次数加1投掷次数小于10且投中次数小于2为循环条件

输出投掷次数和投中次数动态演示过程2022/12/1928循环结构(do~while语句)程序4.10模拟投骰子,以循环结构(do~while语句)程序4.10模拟投骰子,以6点为目标,投中目标两次获胜,最多允许投10次(方法1:用do~while语句)

#include<stdio.h>#include<stdlib.h> #include<time.h> intmain(){intcount=0,y=0,dice;

srand(time(0)); do

{ dice=1+rand()%6;

count++; if(dice==6)y++;

}while(count<10&&y<2);printf("%d,%d\n",count,y); return0;}while(count<10&&y<2)

{

dice=1+rand()%6;count++;if(dice==6)y++;

}(方法2:用while语句)此处不能加分号,如果加了分号,语法上正确,表示该循环体为空语句,而语句块就成为一条无条件的语句,结果将出错大部分情况下,do~while语句可以直接改写成while语句,达到同样的效果,需要保证循环体第一次执行不会出错

(方法3:用for语句)for(;count<10&&y<2;count++)

{

dice=1+rand()%6;if(dice==6)y++;

}2022/12/1929循环结构(do~while语句)程序4.10模拟投骰子,以程序4.11

利用格里高利公式求π的近似值格里高利公式为:π/4=1-1/3+1/5-1/7+┅┅

两种求解要求:算法分析:先求π/4,最后再乘以4,用一个累加器进行求和;分子无变化,分母可用项号i的表达式:2*i-1表示每一个累加项正负号交替,设一个符号变量,每项加过以后取负循环体内的主要操作:(1)求当前项,即符号变量*1.0/(2*i-1)(2)将当前项加入到累加器中

(3)改变符号变量的值,以保证累加项正负号交替

(4)表示第几项的变量i加1循环条件根据题目要求设定循环结构(3种语句)项数确定,适合用for语句规定求解精度,适合用whie或do~while语句2022/12/1930程序4.11利用格里高利公式求π的近似值循环结构(3种语//要求1:求前5001项的//累加和作为π的近似值#include<stdio.h>intmain(void){intsign,i;doubleitem,pi,sum=0;sign=1;

for(i=1;i<=5001;i++)

{

item=sign*1.0/(2*i-1); sum=sum+item;

sign=-sign;

}

pi=4*sum; printf("pi=%f\n",pi);return0;}//要求2:求π的近似值直到//最后累加项绝对值小于1E-4

#include<stdio.h>#include<math.h>intmain(void){intsign,i=1;doubleitem,pi,sum=0;sign=1;

do

{

item=sign*1.0/(2*i-1);sum=sum+item;

sign=-sign;

i++;

}while(fabs(item)>=1e-4);

pi=4*sum; printf("pi=%f\n",pi);return0;}动态演示过程2022/12/1931//要求1:求前5001项的//要求2:求π的近似值直到动态do~while语句一个非常实用的用法:保证读入的数据符合要求,也就是说,如果读入的数不符合要求,则提示重新读入,直到满足要求为止例4.7:判断一个输入的正整数m是否为质数当时对输入的m,如果小于等于0,则简单地返回不做任何处理。现在使用do~while可以要求读到m大于0为止。………………

intmain(){intm,i,k,prime=1; scanf("%d",&m);

if(m<0){printf("Inputerror!\n");return0;}………………

循环结构(do~while语句)do{ printf("inputadata>0:\n");scanf("%d",&m);}while(m<=0);读到第一个大于0的整数就停止2022/12/1932do~while语句一个非常实用的用法:保证读入的数据符合要3种控制循环结构的语句在语法上都是一条语句

for和while语句的循环体要求是一条语句,如果使用复合语句作循环体,实际上是允许有多条语句的;do~while语句本身循环体就可以是多条语句,因此,它们的循环体内可以嵌入更深层次的循环控制语句,从而构成了循环的嵌套,3种语句可以互相嵌套。循环嵌套最主要的是理解其执行过程:(1)先对外层循环控制变量取一个值,满足条件进入循环体(2)执行循环体中的内层循环,内层循环结束后,回到外层

(3)改变外层循环控制变量的值,回到步骤(1)

(4)当外层循环条件不满足时停止整个循环

循环嵌套2022/12/19333种控制循环结构的语句在语法上都是一条语句循环嵌套2022例4.12:从键盘上输入1个正整数n,求1!+2!+3!+…+n!的结果#include<stdio.h>intmain(){ inti,j,n; doublef,sum=0; do {printf("Pleaseinputn:\n"); scanf("%d",&n); }while(n<=0);

for(i=1;i<=n;i++) {f=1;

for(j=1;j<=i;j++)

f=f*j;

sum+=f;

} printf("sum=%e\n",sum);

return0;}保证输入一个正整数内循环,求i!外循环,求1!+2!+…+n!外层控制变量i值外层条件内层循环语句形式内层循环次数内层循环结束时j值f值sum值11for(j=1;j<=1;j++)f=f*j;

121.01.021for(j=1;j<=2;j++)f=f*j;232.03.031for(j=1;j<=3;j++)f=f*j;346.09.040不进入外层循环体,无内层循6.09.0如果读入3,结果sum=9.000000E+000动态演示过程2022/12/1934例4.12:从键盘上输入1个正整数n,求1!+2!+3!+…循环嵌套程序4.13

打印一个由‘*’号组成的五行等腰上三角形。#include<stdio.h>intmain(){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;}算法:一般用两层循环打印一个形状规则的图形外层循环控制行变化

外层循环体中依次完成下面3个步骤:(1)根据行数和图形的形状,打印每行的前导空格(确定本行图形的起始位置)。若行号为i,i从1开始计,考虑最后一行(假设为n)前不留前导空格,则第i行前导空格的单位为:n-i,用一个内层循环控制打印前导空格

(2)根据行号与当前行图形的个数及形状的关系进行控制输出当前行的图形。等腰三角形,其图形元素个数为2*i-1,这里i为当前行的行号,用一个内层循环打印图形

(3)换行外层循环控制行的变化外层循环的循环体n,n;scanf(“%d”,&n);nn-i打印一个n行等腰上三角形,每行图形依次为ABCD…读入控制的完整代码如教材所示,用do~while保证n在一定的范围内i+64);ABC演示过程动态演示过程2022/12/1935循环嵌套程序4.13打印一个由‘*’号组成的五行等腰一个用穷举法解决问题的典型例,注意算法设计的重要性,同一题有多种解法,效率不一样.程序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

循环嵌套为避免小数,

②左右两边同乘以3得到③2022/12/1936一个用穷举法解决问题的典型例,注意算法设计的重要性,同一题有//例4.14百鸡百钱问题方法1//用3层循环控制#include<stdio.h>intmain(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&&15*x+9*y+z==300)printf("%5d%5d%5d",x,y,z);return0;}//例4.14百鸡百钱问题方法3//用1层循环控制//方法:公式③-公式①得到:14x+8y=200即:7x+4y=100…④由公式④,显然0<=x<=14,在x确知的情况下根据④可求得y=(100-7*x)/4;再根据公式①得到:z=100-x-y#include<stdio.h>intmain(void){intx,y,z; for(x=0;x<=14;x++) { y=(100-7*x)/4; z=100-x-y; if(15*x+9*y+z==300)printf("%5d%5d%5d",x,y,z); }return0;}满足百鸡满足百钱同时满足2两{

z=100-x-y;利用百鸡条件用x,y的表达式表示z,从而去掉第3层循环if(这时只需要判断百钱的条件就可以了}这时只需要判断百钱的条件就可以了2022/12/1937//例4.14百鸡百钱问题方法1//例4.14百鸡百钱问题方break语句的用法1:用于switch语句中,表示结束该分支的操作,从而结束switch语句,真正实现了多分支控制break语句的用法2:用于3种循环语句的循环体中,配合一定的条件,执行到break直接退出本层循环,从而增加了从循环体中结束循环的方式(此前只能因循环控制条件为假而终止循环)程序4.10

模拟投骰子问题的第4种实现方法——使用break语句

模拟投骰子循环条件是两个:投掷次数小于10并且投中次数小于2,前3种方法都是将这两个条件同时列在控制循环的条件表达式中,用break就可以减少一个循环条件其他流程控制语句(break)2022/12/1938break语句的用法1:用于switch语句中,表示结束该分程序4.10模拟投骰子问题的第4种实现方法

——循环体中使用break语句

#include<stdio.h>#include<stdlib.h> #include<time.h> intmain(){intcount=0,y=0,dice;

srand(time(0)); while(count<10&&y<2)

{

dice=1+rand()%6;count++;if(dice==6)y++;

}printf("%d,%d\n",count,y); return0;}两个条件同时满足这是原方法2的代码,用while语句控制循环if(y==2)break;)减少一个条件break用于循环体中,一般要配合if使用才有意义流程图count<10?dice=1+rand()%6count++dice==6?y++y==2?真真假break真假假增加了从循环体中退出循环的出口动态演示过程2022/12/1939程序4.10模拟投骰子问题的第4种实现方法

——循环体中使continue语句的用法:只能用于循环语句的语句块中continue语句的功能:提前结束本次循环,忽略循环体中其后的语句,直接进入下一次条件的判断与break语句不同:continue不能退出循环程序4.10

模拟投骰子问题的第5种实现方法——使用continue语句

模拟投骰子的循环体中,变量y自增1是有条件的,必须在dice==6时,换句话说,当dice!=6时,y++不执行,这可以用continue来改写其他流程控制语句(continue)2022/12/1940continue语句的用法:只能用于循环语句的语句块中其他流程序4.10模拟投骰子问题的第5种实现方法

——循环体中使用continue语句

#include<stdio.h>#include<stdlib.h> #include<time.h> intmain(){intcount=0,y=0,dice;

srand(time(0)); while(count<10&&y<2)

{

dice=1+rand()%6;count++;if(dice==6)y++;

}printf("%d,%d\n",count,y); return0;}两个条件同时满足这是原方法2的代码,用while语句控制循环流程图!continuecount<10&&y<2?dice=1+rand()%6count++dice!=6?y++真假continue真假增加了一种提前结束循环体回到循环条件重新判断的方式动态演示过程2022/12/1941程序4.10模拟投骰子问题的第5种实现方法

——循环体中使goto语句:为无条件转移语句,它可以在不需要任何条件的情况下直接使程序转跳到语句标号所标识的语句处,但是通常与if语句配合使用,可以实现顺序结构、选择结构和循环结构这3种流程的控制。goto语句的格式:goto语句标号;语句标号:是一个用户自定义标识符,它标识程序的一个特定位置,只能在goto语句中引用

goto语句使用建议:因自由跳转破坏基本结构,影响可读性和和可维护性,不提倡使用goto语句,应合理、有节制地使用。程序4.10

模拟投骰子问题的第6种实现方法——使用goto语句实现循环结构

其他流程控制语句(goto)2022/12/1942goto语句:为无条件转移语句,它可以在不需要任何条件的情况程序4.10模拟投骰子问题的第6种实现方法

——使用goto语句实现循环

#include<stdio.h>#include<stdlib.h> #include<time.h> intmain(){intcount=0,y=0,dice;

srand(time(0));do

{

dice=1+rand()%6;count++;if(dice==6)y++;

}while(count<10&&y<2);printf("%d,%d\n",count,y); return0;}这是原方法1的代码,用do~while语句控制循环repeat:ifgotorepeat;此为语句标号,后面跟冒号,位于goto要跳转执行的第一句话之前原来的while改成if用goto语句跳转到repeat标识的语句处,从而使repeat和此if语句之间的语句成为循环体动态演示过程2022/12/1943程序4.10模拟投骰子问题的第6种实现方法

——使用got本章小结本章内容是C语言编程的基础,非常重要!!!重点掌握控制3种基本结构(顺序结构、选择结构、分支结构)实现的各种语句的使用方法3种if语句(if~else、if、嵌套的if)的正确使用switch与break语句配合使用,才能真正处理多分支问题for与while控制当型循环的执行过程,语法要点,以及for语句灵活多变的形式do~while控制直到型循环的执行过程,与当型循环的区别break与continue用于循环体中的不同作用:退出本层循环与提前结束本次循环进入下一次条件判断之间的区别一般了解goto语句,知道其用法,谨慎使用难点:正确设置控制循环的条件以及分析循环结构中的不变与变——哪些是不变的操作,这是循环体中的语句;每次循环如何变化哪些变量2022/12/1944本章小结本章内容是C语言编程的基础,非常重要!!!2022/本章小结重点理解本章经典算法并能举一反三解决类似问题:五级分制的两种求解方法--->用if或switch求解多分支问题判断某一个整数是否为质数--->寻找一定范围内所有的质数,哥德巴赫猜想求两个整数的最大公约数--->求两数的最小公倍数,多个数的最大公约数按位分离十位数的每一位数字--->进制转换问题项数确定或要求精度的格里高利公式求和--->求和题的解法模拟投骰子游戏的多种实现--->猜字谜游戏的灵活设计打印等腰三角形--->规则图形的打印方法百鸡百钱问题的多种解法--->穷举题的一题多解及算法效率掌握一些实用技术:用do~while语句保证读入符合特定要求的数据调用srand(time(NULL))产生随机种子,保证数的随机性调用rand()函数产生一定范围的随机整数2022/12/1945本章小结重点理解本章经典算法并能举一反三解决类似问题:202Theendofchapter4Theendofchapter4高级语言程序设计

2022/12/1947高级语言程序设计2022/12/171第四章程序流程控制主讲:计算机学院朱立华第四章程序流程控制主讲:计算机学院朱立华内容提要算法的基本概念以及表示方法,简单介绍流程图C程序的3种基本流程控制结构:顺序结构、选择结构(也叫分支结构)、循环结构,每种结构的控制语句:if、switch控制选择结构for、while、do~while控制循环结构break、continue、goto等语句的用法循环嵌套程序的设计及运行过程一些常用算法的基本思想:分段函数求解问题判断一个整数是否为质数求两个正整数的最大公约数各种求和问题掷骰子游戏的多种解法求阶乘打印规则的图形穷举问题的多种求解方法2022/12/1949内容提要算法的基本概念以及表示方法,简单介绍流程图掷骰子游戏算法与语句

算法(Algorithm)就是为解决一个具体问题而采取的有限的操作步骤,算法通过语句来实现计算机算法分两类:数值运算算法、非数值运算算法程序=数据结构+算法算法的正确性衡量标准:有穷性:算法包含有限步操作确定性:每一步都应确定无歧义有效性:每一步都应能有效执行且能得到确定的结果0或多个输入:程序允许无输入1或多个输出:任何程序都必须有输出,哪怕是提示信息解决求数值解的问题解决需要用分析推理、逻辑推理才能解决的问题

数据的描述和组织形式

对操作或行为的描述,即操作步骤

2022/12/1950算法与语句算法(Algorithm)就是为解决一个具体问题算法与语句

常用的算法描述方法有:自然语言、传统流程图、NS流程图、伪代码等,这里只介绍传统流程图。例:求n!的算法思想:n!=1*2*3*…*n由于计算机执行乘法时每次只能求两个数相乘,因此上面的公式在程序中必定需要通过反复相乘来实现。需要设定一个变量n,表明求多少的阶乘;第二个变量,存当前累乘的结果;第三个变量存当前将要与累乘器相乘的因子,并且该因子的变化是从1到n每次增加1流程图如下页所示2022/12/1951算法与语句常用的算法描述方法有:自然语言、传统流程图、NSno开始n<0?输入n图4.2计算n!的传统流程图fac=1,i=1fac=fac*ii=i+1i<=n?yes输出fac值no结束输出错提示yes开始结束框输入/输出框判断框一般处理框循环结构3种基本结构的特点:单入口,单出口流程线选择结构顺序结构查看程序2022/12/1952no开始n<0?输入n图4.2计算n!的传统流程图facC语句分类C语言的语句有五大类:(1)9种控制语句:这一类语句用于实现流程控制,选择结构和循环结构必须通过控制语句实现。if~else语句:是实现选择结构最常用的语句switch语句:用于控制某些多分支的选择结构for()~语句:最常用最灵活的循环控制语句,当型循环while()~语句:

温馨提示

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

最新文档

评论

0/150

提交评论