270 likes | 432 Views
第六章 循环控制. 本章重点、难点: 1、 while 语句及使用该语句进行程序设计 2. for 语句及使用该语句进行程序设计 3. 初步学会利用 C 语言来解决一些实际的问题. 6.1 概述. 程序经常会重复执行某些相同的操作,如: 求: s=1+2+3+4+…+100. 算法描述: ① s=0;i=1; ② s+=i; i++; ③ 判断 i 是否小于等于100 如果 i 小于等于100,重复 ② ; 否则,结束。. 初始化部分。. 循环体。.
E N D
第六章 循环控制 本章重点、难点: 1、while语句及使用该语句进行程序设计 2. for语句及使用该语句进行程序设计 3. 初步学会利用C语言来解决一些实际的问题
6.1 概述 程序经常会重复执行某些相同的操作,如: 求:s=1+2+3+4+…+100 算法描述: ①s=0;i=1; ②s+=i; i++; ③判断i是否小于等于100 如果i小于等于100,重复②; 否则,结束。 初始化部分。 循环体。 此类根据某个条件重复执行相同算法的结构,称为循环。 C 语言提供了三类实现循环的语句: while, do while,for
6.2 goto语句 goto语句 格式: goto Label /* Label: 同一函数内语句前的标号。*/ 作用:转移到标号对应的语句上继续执行。无条件转向语句. loop: if (i<=100 ) { sum=sum+i; i++; goto loop; } 语句标号的命名规则:与变量名相同。不能用整数来作标号。例如: goto labeL1; goto 23; 这样写对吗?
6.2 goto语句 • 注意: • 结构化程序设计方法主张限制使用goto语句,因为滥用goto语句将使程序流程无规律、可读性差。但也不是绝对禁止使用goto语句。一般来说,可以有两种用途: • 与if语句一起构成循环结构; • if (……) goto kk; • 从循环体中跳转到循环体外,但在C语言中可以用break语句和continue语句跳出本层循环和结束本次循环。goto语句的使用机会已大大减少,只是需要从多层循环的内层循环跳到外层循环外时才用到goto语句。但是这种用法不符合结构化原则,一般不宜采用,只有在不得已时才使用。
6.3 while语句 ⒈while 循环(当型循环) 表达式:值非0,表示满足条件;值为0代表不满足条件。 格式: while(expression) statement; 语句(复合语句),重复执行部分(循环体)。 流程: no e? yes statement;
6.3 while语句 举例:求1+2+3+…+100 #include <stdio.h> /*test2.c */ void main(void ) { int s=0, i=1; while (i<=100) { s=s+i; /* s+=i; */ i++; } printf (“s = %d \ n”, s) ; } S=0;i=1 初始化部分 i<=100 0 条件测试 非0 s=s+i i=i+1 循环体 实例运行 注意:1、 循环体如果包含一个以上的语句,应该用花括弧括起来,以复合语句形式出现。如果不加花括弧,则while语句的范围只到while后面第一个分号处。 2、在循环体中应有使循环趋向结束的语句 .
6.4 do-while语句 格式: do { statement;} while (expression ); 流程: statement; 含有使条件趋假的语句。 yes while循环与do-while循环的区别: • while循环先判条件,后执行循环体; • do –while循环先执行循环体,后判条件。 e? no
6.4 do-while语句 举例: 求:30! #include <stdio.h> void main(void) { float s=1.0; int i=1; do{ s*=i; i++; }while(i<=30); printf(“30!=%f”,s); } 初始化。 循环体。 测试条件。 使条件趋假。 ? 思考题: 1. 用do-while实现s=1+2+…+100 2. 用while实现30!。
6.4 do-while语句 举例: while和do一while循环的比较 1)main() /*test3.c*/ 2) main()/*test4.c*/ {int sum=0,i; { int sum=0,i; scanf(”%d”,&i); scanf(”%d”,&i); while(i<=10) do { sum=sum十i; { sum=sum十i; i++; i++; } } while(i<=10); printf(“%d”,sum); } printf(“%d”,sum);} 实例运行2 实例运行1
6.5 for 语句 ⒊ for循环 初值表达式。 测试表达式。 格式: for (e1; e2; e3 ) statement; 增值表达式。 流程: (1)先求解表达式1; (2)求解表达式2,若其值为真(非0),然后执行下面第(3)步,若为假(0),则结束循环,转到第(5)步。 (3)若表达式为真,在执行指定的语句后,求解表达式3。 (4)转回上面第(2)步骤继续执行。 (5)执行FOR语句下面的一个语句。 e1 no e2? yes statement; 使e2趋假。 e3
6.5 for 语句 for语句的形式如下: for(循环变量赋初值;循环条件;循环变量增值) #include <stdio.h> void main() {int n,sum=0,i; pinrtf (“please input n: ”); scanf(“%d”,&n); for(i=1;i<=100;i++) sum=sum+i; pirntf (“sum=%d”,sum); } 例:求s=1+2+3+……n
6.5 for 语句 for (e1; e2; e3 ) 在for循环中,e1、e2、e3都可以省略! 1. for语句中表达式1可以省略,其后的分号不能省略。执行时,跳过“求解表达式1”这一步,其它不变。 2.如果表达式2省略,即不判断循环条件,循环无终止地进行下去。也就是认为表达式2始终为真。 for (i=l;;i++) sum=sum+I 它相当于: i=1; while(1) {sum=sum+i;i++;} 求解表达式1 语句 3.表达式3也可以省略,但此时程序设计者应另外设法保证循环能正常结束。如: for(sum=0,i=1;i<=100;) {sum=sum十1; i++;} 求解表达式3
6.5 for 语句 4.可以省略表达式1和表达式3,只有表达式2,即只给循环条件。如: for(;i<=100;){sum=sum+i;i++;} 相当于: while (i<=100) { sum=sum+i;i++;} 5.三个表达式都可省略,如: for (;;)语句 相当于: while (1)语句 即不设初值,不判断条件(认为表达式2为真),循环变量不增值。
6.5 for 语句 6.表达式1可以是设置循环变量初值的赋值表达式,也可以是与循环变量无关的其它表达式。如: for (sum=0; i<=100;i++) sum=sum+i; 表达式3也类似,如: for(sum=0;i<=100;k++) 表达式1和表达式3可以是一个简单的表达式,也可以是多个表达式,中间用逗号间隔。如: for(sum=0,i=1;i<=100;i++) sum=sum+i; 或 for(i=0,j=100;i<=j;i++,j--) k=i+j ; 7.表达式2一般是关系表达式或逻辑表达式 , 但也可以是数值表达式或字符表达式,只要其值为非零就执行循环体。
6.6 循环的嵌套 概念:在一个循环的循环体内又包含一个完整的循环称为循环 的嵌套。 说明: ⒈内外层循环采用缩进形式。 例:打印99乘法表。 #include <stdio.h> 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可以 相互嵌套。 ⒊执行次数为内层次数和外存 次数的乘积。 外层循环 内层循环 如何打印乘法表的一半? 实例运行 乘法表的一半
6.7 循环的中断(break)和继续(continue) 假 表达式1 真 真 表达式2 break 假 循环的 下一语句 ①循环的中断:break语句 概念:循环体中可以加分支,判断是否继续执行循环,break语句可以提前结束循环。 如有以下循环结构: While (表达式1) {…… if (表达式2)break; …… } 其流程图为:
6.7 循环的中断(break)和继续(continue) 举例:求:s=1+2+3+…+100 void main (void ) { int s=0,i=1; for (; ; ) { s =s + i; i++; if ( i > ?? ) break; } printf (“s= %d” , s) ; } void main (void ) { int s,i ; for (s=0,i=1; ;i++ ) { s =s + i; if ( i > ?? ) break; } printf (“s= %d” , s) ; } 100 99 实例运行 实例运行
6.7 循环的中断(break)和继续(continue) 举例:求:r =1—10的圆的面积,如圆面积大于100则中断。 float pi=3.14159; for (r=1; r<=10; r++) { area =pi * r * r; if ( area >100 ) break; printf ( “ \n% f “ , area); }
6.7 循环的中断(break)和继续(continue) 假 表达式1 真 真 表达式2 continue 假 循环的 下一语句 ②继续循环:continue语句 continue语句的作用:跳过本次循环剩余的循环体内容,执行下次循环。 如有以下循环结构: While (表达式1) {…… if (表达式2)continue; …… } 其流程图为:
6.7 循环的中断(break)和继续(continue) 举例:求1—100内的偶数和。 s=0; for ( n=1; n<=100; n++) { if (n%2!=0) continue; s+=n; } 如果不使用continue语句,如何来实现?
6.8 循环和分支相互嵌套 输入10个自然数统计其中偶数的个数及偶数值和。 算法框图: #include <stdio.h> void main(void) { int i, ix,iCount=0,iSum=0; for(i=1;i<=10;i++) { scanf(“%d\n”, &ix); if( ix%2==0 ) { iSum+=ix; iCount++; } } printf(“Num=%d\nSum=%d”,iCount,iSum); } start 算法的健壮性 定义变量 输入负数? do { if(ix<=0) printf(“date error”); } while(ix<=0); 初始化 no 循环? 循环结构 yes 分支结构 输入 输出结果 no 偶数? yes 统计累加 end
6.9 程序举例 ⒈求100到200之间的所有素数(只能被1和自身整除的数)。 对于自然数n,判断其是否为素数的方法: 判断n是否能被从2到(int)sqrt(n)范围的数整除; 在程序设计中,经常要记录一些状态,作为判断的条件。因此需要在程序中设置一些标志,通常标志是整型变量。 程序设计中标志技术的使用: 如:设置变量iFlag用于记录是否是素数, iFlag==1是素数; iFlag==0不是素数。
s=sqrt(n); 判断某自然数n是否是素数的算法 iFlag=1; N i<=s Y Y n%i==0 N iFlag=0; break; i=i+1; iFlag==0? 输出n是素数 输出n不是素数
程序如下: #include <stdio.h> #include <math.h> void main(void) { int n, j, s, iFlag; for(n=101;n<200;n+=2) { s=sqrt(n); iFlag=1; for(j=2; j<=s; j++) { if(n%j==0){ iFlag=0;break;} } if(iFlag==1)printf(“\n%d”,n); } } 0不是素数;1是素数。 假定n是素数。 枚举所有数 如果n能被2到s的任意数整除,设标志退出循环。 如果n是素数,输出n。 实例运行
⒉求水仙花数(条件:三位数的个、十、百位的立方和等于该数。153==13 +53 +33 )。 #include <stdio.h> 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。 构造条件 测试条件 实例运行
思考题: 36人一次搬36块砖,男搬4,女搬2,两个小孩抬一块。要一 次搬完。问:男、女、小孩要多少?(要求输出所有的方案) #include <stdio.h> main() { int m,w,c,k=0; for (m=0;m<=9;m++) for (w=0;w<=18;w++) for(c=0;c<=72;c+=2) if(m*4+w*2+c/2==36 && m+w+c==36) {printf("m=%d,w=%d,c=%d\n",m,w,c); k=k+1;} printf ("total=%d",k); }
课堂作业: 1.输出10-1000之间所有被3余2、被5除余3的数,并统计其个数。 2.输入n的值,计算并输出S的值。 s=1+(1*2)+(1*2*3)+……+(1*2*3*4*…n)