c语言控制结构(修改版).ppt_第1页
c语言控制结构(修改版).ppt_第2页
c语言控制结构(修改版).ppt_第3页
c语言控制结构(修改版).ppt_第4页
c语言控制结构(修改版).ppt_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

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

文档简介

1,第三章 程序结构的控制语句,2,3.1.1 C语言中的语句 C语言中的语句有5类:,3.1 顺序程序结构,表达式语句 一般形式: 合法的表达式; 例如: x=3;,结构化程序设计涉及3种基本结构:顺序、分支和循环。,2. 分支、循环和跳转语句程序结构的控制语句 例如:if语句、switch语句;while语句、do-while语句、for语句;goto语句、break语句等。,3,3. 函数调用语句 一般形式: 函数名(实际参数表); 分为: 用户函数调用和标准函数 调用。 例如:见右。,例如:输出两个数中较大数的C 语言源程序 main() int a,b,c; scan(“%d,%d”, ,4. 空语句 形式: 只有分号的语句 例如:while(getchar()!=n) ; ,4,5. 复合语句:,概念:一对 所包含的内容称为一个复合语句。其中可以包 含2 多条C语言语句。如:,#include void main (void) int a,b; scanf(“%d,%d”, ,复合语句,复合语句也可以嵌套,复合语句的作用: 作为标识符的作用域。 作为分支和循环的块。,若其中只有一条语句,复合语句的大括号可要可不要 ,但函数体例外 !,另例. 求数列 1+2+i 的值sum,当i 10000时结束。 #include void main(void) long i=1L,SUM=0L; while(i10000L) sum=sum+i; i=i+1; printf(“%ld”,sum); ,5,3.1.2 顺序程序设计举例 特征:简单程序(程序结构中没有分支、循环和跳转)。, 已知:有一圆柱体,底半径为r,圆柱高为h。 求: 底周长、底面积、表面积,体积。,定义变量: 输出:fLen, fAread、 fAreas, fV ; 输入:r 、h。,r,h,先建立数学模型: fLen=2r fAread=r2, fAreas=2r2+2rh=2 fAread+fLenh fV=fAreadh,6,源程序(数学公式变为C表达式)如下:,#include void main(void) float fLen, fAread,fAreas, fV,r,h; scanf(“%f,%f”, ,7, 求一元二次方程ax2+bx+c=0的两个不等的实根,#include #include void main(void) float a,b,c,x1,x2; scanf(“%f,%f,%f”, ,b*b-4.*a*c0,写成C语言的表达式后,该加括号的地方一定要加 !,写成 2*A*B/(A+B)*(A+B) 作为C表达式 可以吗?,不可以,分子、分母缺括号!,跳,8,3.2.1 关系运算符和关系表达式,关系运算是比较两个表达式值的的运算。,关系运算规则:参加运算的表达式,按关系运算符提供的关系 进行比较,满足关系得到整型值1 , 不满足关系 得到整型值0。,3.2 关系运算和逻辑运算,分支结构和循环结构都需要判断条件,而且与关系运算和逻辑运算密切相关。,9,3.2.2 逻辑运算符和逻辑表达式,逻辑运算的结果也是整型值:运算结果为真时,得到整型值1,运算结果为假时,得到整型值0。,例如:int a=1,b=3,c=1,d; c=a=b=a=a)c), 则c为0*/ d=a+2=b+3; /*d的值为1*/,优先级和结合性: ( 、=、=)(=、!=);左结合性。,算术运算,关系运算,逻辑运算,赋值运算,单目运算,在其他运算符中的优先级:,10,逻辑运算符的优先级和结合性: !、 &和 |。,优先级,1,4,3,结合性,例如: 设 x、y、z 均为 int,执行语句 “x=y=3; t=+x|+Y;” 后,t、x、y的值依次是:,说明: !是单目运算符,&、|是双目运算符。 “与”运算的左侧若为0,则右侧运算不进行; “或”运算的左侧若非0,则右侧运算不进行。 逻辑运算的结果值只能是0 或 1。,在其他运算符中的优先级:单目运算优先双目运算。,算术运算,关系运算,逻辑运算,赋值运算,单目运算,11,3.2.3 所有运算符的优先级与结合性汇总,C 语言允许允许所有类型的运算符出现在一个表达式中。 因此,表达式值的类型如何确定,运算的先后顺序如何确定, 必须通过一套规则解决。,为了便于调整优先级,可设置“()”为最高优先级。相同优先级连续出现按结合顺序,结合顺序有从右向左或从左向右。,运算符优先级和结合性总表 :,表达式人工求解举例:,+a-bc+d&a=b*34,注意:在无法确定优先级 时,可加()区分,但降低 编译效率:,c=b*=a+2,c=(b*=(a+2),12,单 算 关 逻 三 赋 逗,单 三 赋 号 都 取 右,总表(附录2),13,3.2.4 根据问题构造合法合意的C语言表达式4例,例1:写出x大于等于-3并且小于5的表达式。,x=-3&x5 写成 -3=x5 错误,例2:写出x落在1、3象限的表达式,但不包括x轴、y轴和原点。,写法:x0&y0|x0,例3:写出字符变量ch是小写字母的表达式。,ch=a&ch=z,注意:关系表达式“abc”与逻辑表达式“ab&bc”是不等价的;当a、b、c分别为3、2、1时,前者的结果为0,而后者的结果为1。,例4:构成三角形的条件是:任意两边之和大于第三边,任意两 边之差的绝对值小于第三边。,a+bc&a+cb&c+ba| fabs(a-b)c& fabs(a-c)b&fabs(c-b)a,14,3.3 分支结构,概念: 结构化程序设计是软件设计的第三次革命。结构化程序设计的基础是采用三种程序的控制结构。,1966年BOHM &Jacopini 证明:只要三种控制结构,就能表达用一个入口和一个出口框图所能表达的任何程序逻辑。,三种控制结构如下:, 顺序结构Sequence,算法描述: f; g;,框图:,f;,g;,入口,出口, 选择结构Selection,算法描述: if(e) f; else g;,框图:,e?,yes,f;,no,g;,入口,出口,15, 循环结构Repetition,当型循环,C ?,f(体),YES,NO,直到循环,f(体),C ?,YES,NO,三种控制结构有如下共同的特点:,一个入口和一个出口; 无死语句(任何情况都不执行的语句); 无死循环。,入口,出口,入口,出口,16,3.3.1 if 结构,C语言的基本分支语句有单分支if 、二分支if else;由它们又可以演化成多分支结构。, 简单if,格式: if(expression) statement;,if 结构,可以是各种表达式;表达式非0为yes,0为no。加括号!,语句可以是一条或多条或 无语句但有分号。,流程图:,e?,statement;,yes,no,举例:,#include void main(void) char ch; ch=getchar(); if(ch=a ,程序的功能是什么 ?,17, if else 结构(二选一),格式: if(expression) stat1; else stat2;,无语句、一条或复合语句,流程图:,e?,yes,stat1;,stat2;,no,入口,出口,举例:输出| x |的 结果。,#include main ( ) int x ; scanf ( “%d” , ,18, if else if 结构(多分支),格式: if(e1) stat1; else if(e2) stat2; else if(e3) stat3; else if(en-1) statn-1; else statn;,框图:,e1?,y,stat1;,n,e2?,y,stat2;,出口,n,en-1?,y,statn-1;,n,statn;,特点: n-1个条件,满足某个条件,执行对应的语句,然后到出口,即实现“多选一”。,19,if else if 结构 举两例:,例1: 征税问题:1000以下税率为3% 10002000税率为4% 20003000税率为5% 3000以上税率6% 输入收入,求应缴税款。,#include /*方法*/ void main(void) float x ,rate; scanf(“%f ”, ,能用3/100 吗 ?,能否与下面的一个分支互换 ? 都改为逻辑表达式后可互换吗? 请看下面两个改写后的程序:,不,可,20,下列程序可行吗?输入1500元试试看。 #include / 错方法 void main(void) float x ,rate; scanf(“%f ”, ,下列程序可行吗?输入1500元试试看。 #include /方法 void main(void) float x ,rate; scanf(“%f ”, ,21,下列程序可行吗?输入1500元试试看。 #include/方法 void main(void) float x ,rate; scanf(“%f ”, ,下列程序可行吗?输入1500元试试看;试分析和比较下列结构。 #include /方法 void main(void) float x ,rate; scanf(“%f ”, ,22,下列程序可行吗?输入1500元试试看; 试分析和比较下列结构。 #include /方法 void main(void) float x ,rate; scanf(“%f ”, ,通过以上6种方法的分析,你对用if构造多分支有何高见 ?,在多分支中,使用关系表达式应注意值的顺序,而使用逻辑表达式一般不需要考虑表达式值的顺序(因为值的区间被限定)。 “if else if ”与“if嵌套”结构实际上是相互变异,即“if else if ”结构实际上是在else一侧又复合 (嵌套)了“ if else ”结构。,23,下列程序可行吗?输入1500元试试看。 #include /方法 main() int x,c; float rate,y; scanf(“%d”, ,通过对同一个问题的多种编程方法的分析,你对if和switch语句的理解是否又提高了一步 ?,注意:用if 完全可替代switch,而switch不能完全替代if ! 原因:表达式不同。,24,例2:输入一个分数,将百分制转化为五分制。 90分以上 打印 A 80-90 打印 B 70-80 打印 C 60-70 打印 D 60 以下 打印 E,#include void main(void) int a; scanf (“%d”, ,也要注意分数的排列顺序 ! 因为也未用逻辑表达式。,25, if语句的嵌套(也可实现“多选一”),对于如下的结构: if(e1) stat1; else stat2;,若在 stat1、stat2中(实际是前面“ifelse if”的变异)又含有if结构: if(e2) stat3; else stat4; 称为if结构的嵌套。,如求符号函数: -1 (x0),#include void main ( void) int x,y ; scanf (“%d” , ,外层,内层,在外层else语句中,含有一个完整的if 结构。,说明:,书写采取缩进形式, 便于区分,增强可读性。,内层缩进。,else与上面的最近的 if 相匹配;各种if 结构都可 以相互嵌套。例如:,x=-1; if (x!=0) if (x0) y=1; else y=0;,Y的结果?,26,if语句的嵌套实例:求一元二次方程ax2+bx+c=0的所有根。,#include #include void main(void) float a,b,c,d,e,x1,x2; scanf(“%f,%f,%f”, ,外层,内 层,求相等实根。,求不等实根。,求共扼复根。,比较两个实数是否相等, 如何构造表达式 ?,应将a=b改为fabs(ab)1.0e-6,外层:分出等于0和不等于0的两种情况。 内层:分出大于0和小于0的两种情况。,因为程序中使用了数学函数 !,27,3.3.2 switch语句(结构更清晰的“多分支”),格式: switch (expression) case 常量表达式1: statement组1;break; case 常量表达式2: statement组2; break; case 常量表达式n-1: statement组n-1; break; default : statement组n; ,只能是整型或字符型表达式。,整型、字符型常量表达式。 各表达式的值最好不能相等。,执行过程:,先求expression的值(构造此表达式是个难点)。,再依次比较expression和各常量表达式(起语句标号作用)的值:若相等,则执行第i 条语句组,若有break ,则退出(即多选一);若无break则继续且不再比较(即case重叠)。,如果都不相等,则执行 default 后的语句组;此分支可缺。,28,switch语句实例:输出五分制对应的百分制范围。,#include void main(void) char chGrad; chGrad=getchar(); switch(chGrad) case a: case A: printf(“90100n”); break; case b: case B: printf(“8089n”); break; case c: case C: printf(“7079n”); break; case d: case D: printf(“6069n”); break; case e: case E: printf(“60n”); break; default : printf(“Data Error!n”); ,多个不同的标号可以共用相同的语句,但前一个不能有“ break; ”。,default语句可以省略。,若去掉任意一个 “break;”,情况如何 ?,注意:用if 完全可替代switch,而switch不能完全替代if !,29,/switch语句的 改错 #include main() int x=1; switch(1.6+1); default:printf(“errorn“);break; case 3:printf(“3n“); case 2:printf(“2n“);break; case x:printf(“1n“),break; case 3:printf(“3n“);break; ,/两个错: 1.6和;,/可在任何位置,/3在2前可以,/两个错: x和,/错:3重复,30,3.4 循环结构,程序经常会需要重复执行某些相同的操作,如: 求:s=1+2+3+4+100,算法描述(自然语言的方法): s=0;i=1; s+=i; i+; 判断i是否小于等于100 如果i小于等于100,重复; 否则,结束。,根据某个条件重复执行相同算法的结构,称为循环。,初始化部分。,循环体。含有条件趋假(i+;)的语句。,循环的条件。循环应在有限次内完成。,C 语言提供了三类实现循环的语句: while, do while,for 下面分别介绍:,31,3.4.1 while 语句,格式: while(expression) statement;,任何表达式:值非0,表示满足条件;值为0代表不满足条件。,语句(或复合语句),重复执行部分(循环体)。,流程:,e ?,Yes(e非零),statement;,no,含有使条件趋假的语句。,举例:,求 s= 1+2+3+4+100,#include void main(void ) int s=0, i=1; while (i=100) s=s+i; /*或 s+=i; */ i+; printf (“s = %d n”, s) ; ,初始化部分,循环体,条件测试,使条件趋假语句,32,3.4.2 do while语句,格式: do statement; while (expression );,流程:,statement;,e?,yes (e非零),no,含有使条件趋假的语句。,while循环与do-while循环的区别: while循环先判条件,后执行循环体; do while循环先执行循环体,后判条件。,举例:,求:30!,#include void main(void) float s=1.0; int i=1; do s*=i; i+; while(i=30); printf(“30!=%f”,s); ,初始化。,循环体。,测试条件。,使条件趋假的语句,思考题: 用do-while实现s=1+2+100。用while实现30!。,33,3.4.3 for语句,格式: for(e1; e2; e3 ) statement;,流程:,e1,e2?,yes (e非零),statement;,e3,no,举例:,求:s=1+2+3+100,#include void main (void ) int s,i ; for(s=0,i=1;i=100;i+ ) s =s + i; printf (“s= %d” , s) ; ,使e2趋假。,在for循环中,e1、e2、e3都可以省略!,e1省略,s=0;i=1;,e3省略,i+;,初值表达式(可以是逗号表达式) 。,测试条件表达式(关系或逻辑 表达式)。,增或减值表达式(可以是逗号 表达式),使e2趋假。,for(i=100;i=1;i-) ?,e2省略如何处理 ? 见下一个问题。,34,3.4.4 循环中途转移语句(break和continue), 提前结束所在循环语句 break,概念:循环体中可以加分支,判断是否提前结束(break) 循环。,举例: 求:r =110的圆的面积,但若圆面积大于100 则结束。,for (r=1; r100 ) break; printf ( “ n% f “ , area); ,若满足,则提前结束所在循环。,中途继续循环语句continue,循环体中可以加分支,判断是否跳过本次循环剩余内容(但for中的表达式3仍执行,否则为死循环!),而执行下次循环。见例和。,举例:求1100内的偶数和。 s=0; for ( n=1; n=100; n+) if (n%2!=0) continue; s+=n; ,若满足条件,跳过循环体中continue下面(但n+照做)的语句,继续循环。,35,3.4.5 循环的嵌套,概念:在一个循环的循环体内又包含一个完整的(完全包住) 循环称为循环的嵌套。,实例:打印99乘法表。,#include void main (void ) int i,j ; for (i=1 ; i=9 ; i+) for (j=1; j=9 ; j+) printf ( “ %4d” , i * j ); printf (“ n ”); ,外层循环,说明:,内外层循环采用缩进形式 书写,增强可读性。,while和do_while和for可以 相互嵌套。,执行次数为内层次数和外存 次数的乘积。 外层一步,内层一遍 !,内层循环,左一半或右一半可修改内循环的终值或初值;上一半或下一半可修改外循环的终值或初值; 它们也可在“体”用if()条件跳出。,如何打印乘法表的左一半?,输出4个角一半 又如何做 ?,“j=10-i” 输出何角 ?,36,补充:特殊循环及应用, 无限循环(死循环)及应用,、while(1) 、do while(1); 、for( ; ;),它们只有靠在循环体中加条件控制和break语句退出循环。,例:程序等待,直到输入字母A,或输入正确。 for ( ; ;) ch= getchar ( ); if ( ch=A) break; , 循环体为空语句的循环(空循环)及应用,for (i=1 ;i=MAX ; i+) ;,空语句(只有分号),作用:程序延时(如交通信号灯)。,应用: 限制输入次数的密码输入问题 !,37, goto语句,格式: goto Label /* Label是同一函数内某语句前的标号*/,作用:转移到标号对应的语句上继续执行(间接实现循环); 也可用于条件退出一层或多层循环(二维数组)。例如:,loop: if (i=100 ) sum=sum+i; i+; goto loop; /*此处不可用ifcontinue*/ ,不可,可以,如二维数组中找首个负数;而Break做不到。,不可,可以,用goto实现跳转应注意的问题:,不可滥用goto语句,破坏模块化 !,38,3.4.6 程序设计举例 分支、循环综合应用,可以分为3类问题: 只有分支的问题(前面的征税);(略) 只有循环的问题(一般循环(略)和迭代循环); 分支、循环综合应用问题(枚举)。,39,例1_1、 找出100999之间的所有水仙花数(三位数的个、 十、百位的立方和等于该数。153=13 +53 +33 )。,n为枚举(一一列举)变量:枚举初值100,枚举终值999。,构造条件:取出(待判的)一个数n的个、十、百位数。,测试是否满足条件:若满足条件则输出n。,#include void main(void) int n, a, b, c; for(n=100 ; n=999 ; n+) a=n/100; b=n%100/10; c=n%10; if(a*a*a+b*b*b+c*c*c=n) printf(“n%d”,n); ,枚举所有三位数,构造条件,测试条件,取n的百位a、十位b、个位c,如何找100999之间的完数(因子之和等于该数,如6=1+2+3) ?如何找同构数(位于它的平方的右边) ?,40,例1_2、求100到200之间的所有素数(只能被1和自身 整除的数)。,对于自然数n,判断其是否为素数有以下三种方法:,判断n是否能被从2到n-1范围内的数整除;,判断n是否能被从2到(int)(n/2)范围的数整除;,判断n是否能被从2到k=(int)sqrt(n)范围的数整除。,程序设计中标志技术的使用:,在程序设计中,经常要记录一些状态,作为判断的条件。 因此需要在程序中设置一些标志,通常标志是整型变量。,如:设置整型变量iFlag用于记录是否是素数, if(iFlag=1)是素数; if(iFlag=0)不是素数。,标志的设置算法如下:,41,标志位设置框图,int iFlag=0(或1);,是素数?,iFlag=1(或0);,yes,No(标志不变),找素数的程序清单如下:,说明: 有时,使用标志位技术可以很方便地解决问题且模块化,如采用顺序查找的方法,在某一批数中查找某一个数,若找到了输出yes,否则输出no这样的问题;当然也可用其他方法。,42,程序如下:,#include #include void main(void) int m, k, i, iFlag; for(m=101;m200;m+=2) k=sqrt(m); iFlag=1; for(i=2; i=k; i+) if(m%i=0) iFlag=0;break; if(iFlag) printf(“n%d”,m); ,其值若为0,则不是素数;非0是素数。,枚举所有奇数,假定m是素数。,如果m能被2到k 的任意一个数整除,则置标志为零且退出内循环。,如果m是素数(即iFlag=1),输出m。 此题若不用标志位技术,应如何做 ? 见08版教材p68(09版教材p77): “if(ik)printf(“n%d”,m); ”。,再枚举2k,43,例1_3、已知一只公鸡5元,一只母鸡3元,3只小鸡1元。现有100元钱,要买100只鸡,求公鸡、母鸡和小鸡各买多少只。 解析:先建立数学模型:x+y+z=100,5x+3y+z/3=100。 枚举列出x(范围:020)和y (范围:033)的所有情况,然后解出z,同时用5x+3y+z/3=100和z能被3整除作为判断条件。 #include main( ) /类似还有:男、女和小孩搬砖问题 ! int x,y,z; for(x=0;x20;+x) / 若全买公鸡cock ,最多买20只 for(y=0;y33;y+) / 若全买母鸡hen ,最多买33只 z=100-x-y; / 对公、母鸡的每一种取值,求小鸡数量 if(z%3=0) / 输出求得一组解 ,44,例1_4、输入10个数,找出并统计其中偶数的个数及偶数值和。,算法框图:,start,定义变量,初始化,循环?,yes,输入,偶数?,yes,统计、累加,no,no,输出结果,end,#include void main(void) int i, ix,iCount=0,iSum=0; for(i=1;i=10;i+) scanf(“%d”, ,循环枚举,分支判断,如何限制输入负数和零?,do if(ix=0) printf(“date error”); while(ix= 0);,算法的健壮性(容错),注意:结构应完整的包含和被包含。,10个数如何提供 ?,空格或回车分隔!,45,例1_5. 输入n个学生某门课程的成绩,统计各分数段的人数。,程序段(枚举输入并判断)如下:, for(i=1 ;i100) continue; /*输入数据不合要求*/ switch(s/10-5) case1:s60+;break; /*6069分*/ case2:s70+;break; case3:s80+;break; case4:s90+;break; case5:s100+;break; default:s50+; /*60分*/ ,很健壮吗?,不 ,影响n !如何改进 ?,循环枚举每个学生,46,例2_1. 求ex=1+x /1! +x2/2!+ x3/3!+ +xn/n! 前n+1项之和。,迭代(循环根据旧值求新值)次数i : 0 1 2 n,迭代公式 :t=t*x/i和exp=exp+t ,即后项的值与前项的关系。,迭代初值: exp=1, t=1,(i=1n),#include void main(void) float exp , x , t; int i, n; scanf(“%f,%d”, printf(“n%f15.6”,exp) ,迭代初值;exp若为0,循环体中语句顺序要变。,循环迭代得新的t 和新的exp。,循环迭代,if(fabs(t)1e-5)break;,可以附加(充要条件,可省)条件:当| t |10-5, 结束运算。,47,例2_2. 用公式 试求sin(x)的 近似值,要求误差小于给定的eps。 #include #include void main(void) float t,x,eps,fsin=0.0; int i=1; scanf(“%f,%f“, ,48,例2_3. 用梯形法求定积分,( 0,0 ),y,x,f(x),a,b,面积,h,x,将 a,b分为n等份,h=(b-a)/n;,求n个小梯形面积之和,实际上是下面4个赋值语句的循环; 而第i 个小梯形面积为: (f0+f1)*h/2 x+h x(循环迭代得新的x) f(x) f1(循环迭代得新的下底f1) s+ (f0+f1)*h/2 s (循环迭代得新的s) f1 f0 (循环迭代得新上底f0),x 初值为a s初值为0 f0 的初值为f(a) 分为n等份(循环次数为n),迭代求积分的方法:,49,程序清单如下:,#include void main(void) float a,b,f0,f1,h,x,s=0.0; int n,i; scanf(“%f,%f,%d”, ,迭代初值。,循环迭代,根据被积函数,体内无条件判断,50,例2_4. 求s=a+aa+aaa+aaaa。 0a10 共n项,最后一项有n个a。 如求s=2+22+222+222222 ; n、a从键盘输入。,迭代次数:i=1n,迭代初值:

温馨提示

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

评论

0/150

提交评论