第4章 程序的控制结构.ppt_第1页
第4章 程序的控制结构.ppt_第2页
第4章 程序的控制结构.ppt_第3页
第4章 程序的控制结构.ppt_第4页
第4章 程序的控制结构.ppt_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

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

文档简介

第4章程序的控制结构,C程序设计语言,哈尔滨工业大学计算机学院苏小红sxh,内容提要,算法的描述方法基本控制结构基本控制语句常用算法,如累加、累乘、统计、递推、迭代、穷举等结构化程序设计的基本思想,C程序结构,什么是结构化程序设计?,StructuredProgramming,简称SP1965年,最早由E.W.Dijkstra在一次国际会议上提出1966年,C.Bohm和G.Jacopini首先证明了:只用顺序、选择、循环三种基本的控制结构就能实现任何单入口、单出口的程序给结构化程序设计奠定了基础1971年,IBM公司的Mills提出:程序应该只有一个入口和一个出口进一步补充了结构化程序的规则,什么是结构化程序设计?,目前,还没有一个严格的定义1974年,D.Gries教授将已有的对结构化程序设计的不同解释归纳为13种。一个比较流行的定义是:结构化程序设计是一种进行程序设计的原则和方法,它避免使用goto语句,采用“自顶向下、逐步求精”方法进行程序设计,按照这种原则和方法设计出的程序的特点为:结构清晰容易阅读容易修改容易验证,糟糕的goto,START_LOOP:if(fStatusOk)if(fDataAvaiable)i=10;gotoMID_LOOP;elsegotoEND_LOOP;elsefor(i=0;ix,A,A,x6,Y,B,B,结束,传统流程图,打印y,图,6!算法可以用N-S图表示如下:,1=x,2=y,x*y=y,x+1=x,直到x6,打印y,初始化部分,循环部分,输出部分,复合语句,括住的若干条语句构成一个语句块,称为复合语句语句块内可以定义变量变量仅在定义它的复合语句内有效变量必须在复合语句的开头定义复合语句可以用在任何可以使用语句的地方,if-else,选择结构的一种最常用形式if(表达式)语句1;else语句2;语句3,表达式值非0时,执行语句1,然后语句3;表达式值为0时,执行语句2,然后语句3,if-else,else部分可以没有if(表达式)语句1;语句3if-else嵌套使用时,注意else和谁配对的问题,当表达式值为0时,直接执行语句3,例4.4:年龄判断,#includemain()intyourAge,hisAge;printf(Pleaseenteryourage:);scanf(%d,条件表达式,含义:如果表达式1的值非0(为真),则该条件表达式的结果就是表达式2的值否则,是表达式3的值,表达式3,N,表达式2,Y,表达式1,例4.4:年龄判断,#includemain()intyourAge,hisAge;printf(Pleaseenteryourage:);scanf(%d,else-if,if的一种扩展形式相当于else分支嵌套if(表达式1)语句1;elseif(表达式2)语句2;elseif(表达式3)语句3;else语句4;语句5;,例4.5:体型判断,按“体指数”对肥胖程度进行划分:体指数t=w/h2(体重w单位为公斤,身高h单位为米)当t18时,为低体重;当18t25时,为正常体重;当25t27时,为超重体重;当t27时,为肥胖。编程从键盘输入你的身高h和体重w,根据给定公式计算体指数t,然后判断你的体重属于何种类型。用3种方法编程:算法1:用不带else子句的if语句编程算法2:用在if子句中嵌入if语句的形式编程算法3:用在else子句中嵌入if语句的形式编程,例4.5用不带else子句的if语句编程,#includemain()floath,w,t;printf(Pleaseenterh,w:);scanf(%f,%f,当t18时,为低体重;当18t25时,为正常体重;当25t27时,为超重体重;当t27时,为肥胖。,例4.5用在if子句中嵌入if语句的形式编程,#includemain()floath,w,t;printf(Pleaseenterh,w:);scanf(%f,%f,182527,当t18时,为低体重;当18t25时,为正常体重;当25t27时,为超重体重;当t27时,为肥胖。,例4.5用在else子句中嵌入if语句的形式编程,#includemain()floath,w,t;printf(Pleaseenterh,w:);scanf(%f,%f,当t18时,为低体重;当18t25时,为正常体重;当25t27时,为超重体重;当t27时,为肥胖。,182527,switch,多路选择switch(表达式)case常数1:语句序列1;case常数2:语句序列2;default:语句序列3;default可以没有,但最好不省略不要忘记break,例4.8:计算器程序,编程设计一个简单的计算器程序,要求根据用户从键盘输入如下形式的表达式:操作数1运算符op操作数2然后,计算并输出表达式的值指定的运算符为加(+)减(-)乘(*)除(/),main()intdata1,data2;/*定义两个操作符*/charop;/*定义运算符*/printf(Pleaseentertheexpression:);scanf(%d%c%d,例4.8,思考题,语句if(0=data2)的必要性1998年11月科学美国人杂志,描述了美国导弹巡洋舰约克敦号上的一起事故,除零错导致军舰推进系统的关闭如果要求程序能进行浮点数的算术运算,语句if(0=data2)还能用于比较实型变量data2和常数0的大小吗?if(fabs(data2)=1e-7)如果要求输入的算术表达式中的操作数和运算符之间可以加入任意多个空格符,那么程序如何修改?scanf(%d%c%d,取绝对值函数,作业,P143152习题4.7,4.9,循环while语句,for语句,while(表达式)语句;for(表达式1;表达式2;表达式3)语句;,while语句,while(表达式)语句;只要表达式的值为非0,就重复执行语句,直到表达式值为0时止,for语句,for(表达式1;表达式2;表达式3)语句;首先执行表达式1。如果表达式2的值为非0,就重复执行语句和表达式3,直到表达式2的值为0时止,循环起始条件,循环结束条件,循环增量,for语句,for(表达式1;表达式2;表达式3)语句;相当于:表达式1和表达式3可以没有或者是用逗号分隔的多个表达式的组合。但最好不要有太多的表达式组合,do-while语句,do语句;while(表达式);首先执行语句,然后判断表达式的值。如果表达式为0,继续向下执行,否则,再次执行语句,再次判断表达式的值语句会被至少执行一次,条件P,A,当型循环,直到循环,真,假,假,条件P,A,假,真,假,条件P,条件P,A,假,当循环条件第一次就为假时,选择三种循环的一般原则,如果循环次数已知,用for如果循环次数未知,用while如果循环体至少要执行一次,用do-while这只是“一般”原则,不是“原则”,注意,在for和while语句之后一般没有分号有分号表示循环体就是分号之前的内容(空循环体)while(i100);i+;for(i=0;i100;i+);printf(%d,i);for通常有一个循环变量控制循环的次数,不要在循环体内改变这个变量,现场编程计算1+2+100=?,分别用如下语句编程forwhiledo-while单步跟踪执行程序,且使用监视窗观测变量值的变化,循序渐进式编程例4.6:猜数游戏,想一个1100之间的数,猜对:right猜错:wrong并提示大小,循序渐进式编程例4.6:猜数游戏,猜数游戏用到的库函数,怎样模拟计算机“想”一个数呢?随机函数rand()产生0,RAND_MAX之间的随机数magic=rand();#includeRAND_MAX在stdlib.h中定义,不大于双字节整数的最大值32767产生0,b-1之间的随机数magic=rand()%b;产生a,a+b-1之间的随机数magic=rand()%b+a;,例4.6,#include#includemain()intmagic;/*计算机想的数*/intguess;/*人猜的数*/magic=rand()%100+1;/*“想”一个1,100之间的数magic*/printf(Pleaseguessamagicnumber:);scanf(%d,例4.9,#include#includemain()intmagic;intguess;intcounter;/*记录人猜次数的计数器变量*/magic=rand()%100+1;counter=0;/*计数器变量count初始化为0*/doprintf(Pleaseguessamagicnumber:);scanf(%d,猜数游戏用到的库函数,每次运行程序时机器所“想”的数都是一样的,这是什么原因呢?函数rand()产生的只是伪随机数随机函数srand为函数rand()设置随机数种子来实现对函数rand所产生的伪随机数的“随机化”通过键入随机数种子,产生0,100之间的随机数scanf(%u,#include#includemain()intmagic;intguess;intcounter;unsignedintseed;printf(Pleaseenterseed:);scanf(%u,例4.9,猜数游戏用到的库函数,使用计算机读取其时钟值并把该值自动设置为随机数种子,产生0,100之间的随机数函数time()返回以秒计算的当前时间值,该值被转换为无符号整数并用作随机数发生器的种子#includesrand(time(NULL);magic=rand()%100+1;,#include#include#includemain()intmagic;intguess;intcounter;srand(time(NULL);magic=rand()%100+1;counter=0;doprintf(Pleaseguessamagicnumber:);scanf(%d,例4.9,guess.c,#include#includemain()intmagic;intguess;intcounter;magic=rand()%100+1;counter=0;doprintf(Pleaseguessamagicnumber:);scanf(%d,错在哪里?,guess.c,#include#includemain()intmagic;intguess;intcounter;magic=rand()%100+1;printf(magic=%dn,magic);counter=0;doprintf(Pleaseguessamagicnumber:);scanf(%d,插入打印语句,#include#include#includemain()intmagic;intguess;intcounter;srand(time(NULL);magic=rand()%100+1;counter=0;doprintf(Pleaseguessamagicnumber:);scanf(%d,实验3,存在一个错误,#include#include#includemain()intmagic;intguess;intcounter;srand(time(NULL);magic=rand()%100+1;counter=0;doprintf(Pleaseguessamagicnumber:);scanf(%d,实验3,实验3,先由计算机“想”一个1到100之间的数请人猜,如果人猜对了,并在屏幕上输出人猜了多少次才猜对此数,以此来反映猜数者“猜”的水平,且结束游戏,否则计算机给出提示,告诉人所猜的数是太大还是太小,最多可以猜10次,如果猜了10次仍未猜中的话,则停止本次猜数,然后继续猜下一个数。每次运行程序可以反复猜多个数,直到操作者想停止时才结束。,例4.11:国王的许诺,相传国际象棋是古印度舍罕王的宰相达依尔发明的。舍罕王十分喜欢象棋,决定让宰相自己选择何种赏赐。这位聪明的宰相指着88共64格的象棋盘说:陛下,请您赏给我一些麦子吧,就在棋盘的第一个格子中放1粒,第2格中放2粒,第3格放4粒,以后每一格都比前一格增加一倍,依此放完棋盘上的64个格子,我就感恩不尽了。舍罕王让人扛来一袋麦子,他要兑现他的许诺。国王能兑现他的许诺吗?试编程计算舍罕王共要多少麦子赏赐他的宰相,这些麦子合多少立方米?(已知1立方米麦子约1.42e8粒)总粒数为:sum=1+2+22+23+263,例4.11方法1,#defineCONST1.42e8#include#includemain()intn;doubleterm,sum=0;/*累加求和变量赋初值*/for(n=1;n=64;n+)term=pow(2,n-1);/*根据累加项的规律计算累加项*/sum=sum+term;/*作累加运算*/printf(sum=%en,sum);/*打印总麦粒数*/printf(volum=%en,sum/CONST);/*折合总麦粒体积数*/,例4.11方法2,#defineCONST1.42e8#includemain()intn;doubleterm=1,sum=1;/*累乘求积累加求和变量赋初值*/for(n=2;n=64;n+)term=term*2;/*根据后项总是前项的2倍计算累加项*/sum=sum+term;/*作累加运算*/printf(sum=%en,sum);/*打印总麦粒数*/printf(volum=%en,sum/CONST);/*折合总麦粒体积数*/,作业,P143152习题4.12,4.16,4.18,嵌套循环,使用嵌套的循环体时,应注意以下问题,在嵌套的各层循环体中,使用复合语句(即用一对大花括号将循环体语句括起来)保证逻辑上的正确性内层和外层循环控制变量不应同名,以免造成混乱嵌套的循环最好采用右缩进格式书写,以保证层次的清晰性自己阅读P278-283,代码风格问题,网站上代码规范的ppt循环嵌套不能交叉,即在一个循环体内必须完整的包含着另一个循环,例4.14:打印乘法九九表,例4.14,#includemain()intm,n;for(m=1;m10;m+)printf(%4d,m);/*打印表头*/printf(n);for(m=1;m10;m+)printf(-);printf(n);for(m=1;m10;m+)for(n=1;n10;n+)printf(%4d,m*n);printf(n);,例4.15:打印下三角乘法九九表,#includemain()intm,n;for(m=1;m10;m+)printf(%4d,m);/*打印表头*/printf(n);for(m=1;m10;m+)printf(-);printf(n);for(m=1;m10;m+)for(n=1;n=m;n+)printf(%4d,m*n);printf(n);,例4.15,例4.16:马克思手稿中的趣味数学题,有30个人,其中有男人、女人和小孩,在一家饭馆里吃饭共花了50先令,每个男人各花3先令,每个女人各花2先令,每个小孩各花1先令,问男人、女人和小孩各有几人?解方程组穷举法,例4.16方法1:采用三重循环穷举x,y,z的全部可能的组合,#includemain()intx,y,z;printf(MantWomentChildernn);for(x=0;x=30;x+)for(y=0;y=30;y+)for(z=0;z=30;z+)if(x+y+z=30,例4.16方法2:改进算法,#includemain()intx,y,z;printf(MantWomentChildernn);for(x=0;x=16;x+)for(y=0;y=25;y+)z=30x-y;if(3*x+2*y+z=50)printf(%3dt%5dt%8dn,x,y,z);,作业,P143152习题4.20,4.21,4.22,4.25,4.27,4.28,流程的转移控制,break语句continue语句goto语句,break和continue,对for、while、do-while循环进行内部手术break,退出一层循环或者switchcontinue,中断此次循环体的执行,开始下一次break和continue少用为妙,break和continue,例4.17:单步运行演示break语句和continue语句的用法区别,#includemain()inti,n;for(i=1;i=5;i+)printf(Pleaseentern:);scanf(%d,Pleaseentern:10n=10Pleaseentern:-10Programisover!,例4.17:单步运行演示break语句和continue语句的用法区别,#includemain()inti,n;for(i=1;i=5;i+)printf(Pleaseentern:);scanf(%d,Pleaseentern:10n=10Pleaseentern:-10Pleaseentern:20n=20Pleaseentern:-20Pleaseentern:30n=30Programisover!,标号举例error:goto举例gotoerror;一般形式goto语句标号;语句标号:或语句标号:goto语句标号;,goto与标号(label),是goto的过错?还是程序员的过错?,破坏了结构化设计风格容易带来错误隐患gotonext;intsum=0;/*被goto跳过*/next:,Evilgotos?MaybeNot凌波微步,未必摔跤,现代观点认为:混乱根源不在goto,而在标号任何程序都可以不用goto就实现其功能但在某些情况下,使用goto可以让程序更清晰两种适合使用goto的情况跳向共同的出口位置,进行退出前的处理工作跳出多重循环的一条捷径gotoerror;,使用goto的原则,主张少用、慎用,而不是禁用保证使用之后,程序仍然是单入口,单出口不要使用一个以上的标号不要用goto往回跳,要向下跳不要让goto制造出永远不会被执行的代码,其他流程转移控制,return语句将在第5章讲解标准库函数exit()作用是终止整个程序的执行,强制返回操作系统调用该函数需要嵌入头文件,例4.19:输入一个整数,判断它是否是素数,goto语句,例4.19:方法1,#includemain()intm,i,k;printf(Pleaseenteranumber:);scanf(%d,Pleaseenteranumber:,6,Programisover!,No!,#includemain()intm,i,k;printf(Pleaseenteranumber:);scanf(%d,Pleaseenteranumber:,5,Programisover!,Yes!

温馨提示

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

最新文档

评论

0/150

提交评论