760 likes | 834 Views
第六章 循环结构的 C 程序设计. 第一节 循环的基本概念 第二节 while 语句 第三节 do-while 语句 第四节 for 语句 第五节 break 、 continue 、 goto 语句 第六节 几种循环语句比较 第七节 循环的嵌套 第八节 程序举例. 循环的必要性. §6.1 概述. int result1,result2,result3; int result4,result5; result1 = 1 * 10; printf("1 × 10 = %d <br>",result1); result2 = 2 * 10;
E N D
第一节循环的基本概念 第二节while语句 第三节do-while语句 第四节for语句 第五节break、continue、goto语句 第六节几种循环语句比较 第七节循环的嵌套 第八节程序举例
循环的必要性 §6.1 概述 int result1,result2,result3; int result4,result5; result1 = 1 * 10; printf("1 × 10 =%d \n",result1); result2 = 2 * 10; printf("2 × 10 =%d \n",result2); result3 = 3 * 10; printf("3 × 10 =%d \n",result3); result4 = 4 * 10; printf("4 × 10 =%d \n",result4); result5 = 5 * 10; printf("5 × 10 =%d \n",result5); 1 × 10 =10 2 × 10 =20 3 × 10 =30 4 × 10 =40 5 × 10 =50 输出结果 重复语句
循环的必要性 1 × 10 = 10 2 × 10 = 20 3 × 10 = 30 4 × 10 = 40 5 × 10 = 50 0 + 1 1 + 1 2 + 1 上个数字 + 1 ... 重复 (上个数字 +1) × 10
C 语言中的各种循环 do- while while for 需要多次重复执行一个或多个任务的问题考虑使用 循环来解决
C语言可实现循环的语句: 用goto 和 if 构成循环 while 语句 do ~ while 语句 for 语句 循环型程序设计
开始 假(0) 表达式 真(非0) 循环体 §6.2 while语句 • 一般形式: while(表达式) 循环体语句; 说明:语句部分可以是简单语句也可以是复合语句。 • 执行流程: 工作原理 计算表达式的值,当值为真(非0)时,执行循环体语句,一旦条件为假,就停止执行循环体。如果条件在开始时就为假,那么不执行循环体语句直接退出循环。
不成立 表达式? 成立 执行语句 执行while循环之后的语句 循环体
i1; sum0 例 用while循环求 i<=100 sumsum+1 i++ 循环条件 循环初值 输出sum 循环变量增值 循环终值 循环体 #include <stdio.h> main() { int i,sum=0; i=1; while(i<=100) { sum=sum+i; i++; } printf("%d",sum); }
说明: • 循环体有可能一次也不执行 • 循环体可为任意类型语句,一个以上的语句用{}括起来 • 下列情况,退出while循环 • 条件表达式不成立(为零) • 循环体内遇break,goto • 无限循环: while(1) 循环体;
{ } • 例:分析程序的运行结果 #include <stdio.h> main ( ) { int i=1,sum=0; while ( i<=100 ) printf(“i=%d,sum=%d”,i,sum += i); i++; printf(”Sum=%d\n”,sum); } 结果:程序将不停的打印“i=1,sum=...”。 • 无法正常终止的程序,称为“死循环”。 结论:在while语句循环体中,一定要有能够对循环控制条件产生影响的语句。避免出现“死循环”现象。
例 显示1~10的平方 #include <stdio.h> main() { int i=1; while(i<=10) { printf("%d*%d=%d\n",i,i,i*i); i++; } } 运行结果: 1*1=1 2*2=4 3*3=9 4*4=16 5*5=25 6*6=36 7*7=49 8*8=64 9*9=81 10*10=100
循环体 真(非0) expr 假(0) §6.3 do~while语句 • 一般形式: do 循环体语句; while(表达式); • 执行流程: 工作原理 它先执行循环体中的语句,然后再判断条件是否为真,如果为真则继续循环;如果为假,则终止循环。
分别用do-while和while求 • 特点:先执行循环体,后判断表达式 • 说明: • 至少执行一次循环体 • do~while可转化成while结构 main() { int i,sum=0; i=1; while(i<=10) { sum=sum+i; i++; } printf("%d",sum); } main() { int i,sum=0; i=1; do { sum+=i; i++; }while(i<=10); printf("%d",sum); } while do-while
do-while 循环示例 main() { int number=5,guess; printf ("猜一个介于 1 与 10 之间的数\n"); do { printf("请输入您猜测的数:"); scanf("%d",&guess); if (guess > number) printf("太大\n"); else if (guess < number) printf("太小\n"); } while (guess != number); printf("您猜中了! 答案为 %d\n",number); } 猜一个介于 1 与 10 之间的数 请输入您猜测的数:3 太小 请输入您猜测的数:5 您猜中了! 答案为 5 问题描述: 猜数游戏。要求猜一个介于1~10之间的数字,根据用户猜测的数与标准值进行对比,并给出提示,以便下次猜测能接近标准值,直到猜中为止。 输入数字 5 后,do…while 循环中的条件为假,输出结果消息后,程序终止。
比较 while 和 do-while循环 • 比较 while 和 do-while 循环的工作原理 do { 循环体; }while( 循环条件); while(循环条件) { 循环体; } while循环是先判断后执行,所以,如果条件为假,则循环体一次也不会被执行。 do-while 循环是先执行后判断,所以,即使开始条件为假,循环体也至少会被执行一次。 编程:辗转相除法求任意两个整数间的最大公约数
<例3>:输入一个正整数,要求以相反的顺序输出该数。例如:输入12345,则输出为54321。<例3>:输入一个正整数,要求以相反的顺序输出该数。例如:输入12345,则输出为54321。 基本思路:可以从个位开始,按位输出整数的每一位 Input an integer to number Output number%10 number = number /10 Until number = 0
main( ) { unsigned int number; printf ("Input the number:"); scanf ("%d", &number); do { printf("%d", number%10); number/=10; /* number缩小10倍 */ } while (number!=0); } 5 1234 思考:使用while或for语句,如何实现? 两个程序有何区别? 前面的程序可以处理数字0,后面的程序不能处理
for expr1 假(0) expr2 真(非0) 循环体 expr3 §6.4 for语句 • 一般形式: for(expr1 ; expr2 ; expr3) 循环体语句; • 执行流程:
for 循环 for 循环的一般语法: for( 表达式1 ; 表达式2 ; 表达式3 ) { 语句; } 1 2 4 3 counter = 0; num = 1; cnt = 100; 工作原理 counter == 10; num < 25; cnt >0 counter ++; num = num + 1; cnt-- 1、计算表达式1的值,通常为循环变量赋初值; 2、计算表达式2的值,即判断循环条件是否为真,若值为真则执行循环体一次, 否则跳出循环; 3、计算表达式3的值,这里通常写更新循环变量的赋值表达式,然后转回第2步重复执行; 分号用于分隔 for 循环的 三个表达式
表达式1 N 表达式2 表达式3 语句 for循环 表达式1 表达式1 表达式2 表达式2 表达式2 N 语句 Y 表达式3 Y 表达式3
例 用for循环求 #include <stdio.h> main() { int i,sum=0; for(i=1;i<=100;i++) sum+=i; printf("%d",sum); }
内存 number fac i for 循环示例 #include <stdio.h> void main() { int number,i,fac=1; printf("\n 请输入任意一个正整数:"); scanf("%d",&number); for(i = 1; i<=number; i++) fac=fac*i; printf("\n %d的阶乘= %d\n",number,fac); } 2 6 5 1 120 1 循环执行五次 请输入任意一个正整数:5 5的阶乘 = 120
for 循环的表达式 • for 循环中有三个表达式 • for 语句中的各个表达式都可以省略 • 分号分隔符不能省略 可省略 for(<初始化循环变量> ;<循环条件> ; <修改循环变量的值>) { <循环体语句>; } 不能省略
省略表达式1 • 相当于省去了为循环变量赋初值,此时应在for语句之前给循环变量赋初值 int num=0; for(;num <= 10 ;num ++) { printf("%d\n",num*2); } int a=0,n; printf("\n 输入n的值: "); scanf("%d",&n); for(;n>0;a++,n--) printf("%d ",a*2);
省略表达式2 • 即不判断循环条件,也就是认为表达式2始终为真, 这时应在循环体内设法结束循环,否则将成为死循环 for(num=1;;num++) { ... }
省略表达式3 • 即省去修改循环变量的值,但此时应在循环体内设法结束循环 for(i=1;i<=100;) { sum=sum+1; i++; }
省略三个表达式 • 即不为循环变量赋初值,不设置循环条件(认为表达式2为真值),不修改循环变量的值,无终止地执行循环体。此时应在循环体内设法结束循环,否则会成为死循环 for( ; ; ) { printf("这将一直进行下去"); i = getchar(); if(i == 'X' || i == 'x') break; }
说明: • expr1也可以是给其它变量赋初值;expr1和expr3也可以是逗号表达式 例:for(sum=0,i=1;i<=100;i++,i++) • for(sum=0,i=1;i<=100;i=i+2) • for语句可以转换成while结构 expr1; while(expr2) { 循环体语句; expr3; }
例:#include<stdio.h> main( ) { int i=0; for(;i<10;i++) putchar(‘a’+i); } 例:#include<stdio.h> main( ) { int i=0; for(i=0;i<10;i++) putchar(‘a’+i); } 例:#include<stdio.h> main( ) { int i=0; for( ;i<10; putchar(‘a’+i),i++) ; } 运行结果:abcdefghij 例:#include<stdio.h> main( ) { int i=0; for(;i<10;) putchar(‘a’+(i++)); }
main() { int i,j,k; for(i=0,j=100;i<=j;i++,j--) { k=i+j; printf("%d+%d=%d\n",i,j,k); } } 0+100=100 1+99=100 2+98=100 … … … 50+50=100 #include<stdio.h> main() { char c; for(;(c=getchar())!='\n';) printf("%c ",c); }
<例>:数列1、1、2、3、5、8、13、21、…是著名的菲波那奇数列,其递推通项公式为:<例>:数列1、1、2、3、5、8、13、21、…是著名的菲波那奇数列,其递推通项公式为: F1= F2=1 Fn= Fn-1+ Fn-2 (n>=3) 为求出第N项的值,请编写程序。 根据递推通项公式,可用递推法编写程序,计算第N项的值。 • 递推法:由初始的已知条件开始,先计算出第(N-1)步的结果,再利用前面已知的(N-1)项结果,按照递推公式(或遵照递推规则),推出第N步结果。 递推法是程序设计中最常用的方法之一,使用递推法必须有明确的递推初始值和递推规则(递推公式)。
§6.5break、continue、goto语句 break语句 功能:在循环语句和switch语句中,终止并跳出循环体或switch 说明: break只能终止并跳出最近一层的结构 break不能用于循环语句和switch语句之外的任何其它语句之中 • continue语句 • 功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断 • 仅用于循环语句中
break 语句 跳出for 循环 for( ; ; ) { printf("这将一直进行下去"); i = getchar(); if(i == 'X' || i == 'x') break; } 跳出while 循环 while(1) { if(x == 10) break; } 跳出do-while 循环 do { if (x == 10) break; }while (x< 15);
continue 语句 • 功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断 • 仅用于循环语句中 • continue 语句的作用是跳过循环体中剩余的语句而执行下一次循环 • 对于while和do-while循环,continue 语句执行之后的动作是条件判断;对于for循环,随后的动作是变量更新
continue 语句 while(…) { …… …… break; …… …… } while(…) { …… …… continue; …… …… } 继续下一次循环 跳出整个循环
例6.5 把100~200之间的不能被3整除的数输出 main() { int n; for(n=100;n<=200;n++) { if(n%3= =0) continue; printf("%d ",n); } } main() { int n; for(n=100;n<=200;n++) { if(n%3= =0) break; printf("%d ",n); } } 100 101 103 104 106 107 …… 200 100 101
<例>:求555555的约数中最大的三位数是多少? main( ) { int j; long n=555555; /*所求的约数的可能取值是从999到100,j从大到小*/ for (j=999; j>=100; j--) if ( n%j==0 ) /* 若能够整除j,则j是约数 */ { printf(”3 digits in %ld=%d\n”, n, j ); break; /* 控制退出循环 */ } }
<例>:输入10个整数,求其中正数的个数及平均值,精确到小数点后两位。<例>:输入10个整数,求其中正数的个数及平均值,精确到小数点后两位。 main ( ) { int i, count=0, j, sum=0; for ( i=1; i<=10; i++) { printf ("Input integer:"); scanf ("%d", &j); if (j<=0) /* 若为负数 */ continue; /*则结束本次循环,不进行后续操作*/ count ++; /* 计数器 */ sum += j; /* 求累加和 */ } if ( count ) printf("Plus numer:%d,average value:%.2f", count, 1.0*sum/count); else printf("Plus numer: 0, average value: 0"); }
goto语句及用goto构成循环 • goto 语句标号; • ….….. • 标号:语句; • goto语句一般格式: • 功能:使系统转向标号所在的语句行执行 • 说明:语句标号用标识符表示,要符合标识符命名规则 goto loop; goto 255;
循环条件 循环初值 循环变量增值 循环终值 循环体 • 用if 和goto语句构成循环 C不主张使用goto循环 #include <stdio.h> main() { int i,sum=0; i=1; loop: if(i<=100) { sum+=i; i++; goto loop; } printf("%d",sum); } sum=0+1 sum=1+2=3 sum=3+3=6 sum=6+4 …… sum=4950+100=5050
<例> 从键盘输入一组数据,以0结束输入,求数据和 #include <stdio.h> main() { int number,sum=0; read_loop: scanf("%d",&number); if(!number) goto print_sum; sum+=number; goto read_loop; print_sum: printf("The total sum is %d\n",sum); }
§6-6 几种循环语句的比较 • C语言三种循环语句的特点如下: • for和while先判断循环条件后执行循环体, do-while语句先执行循环体后判断循环条件。 • while和do-while语句的条件表达式只有一个, for语句有三个。 • while、do-while、for可以相互替换使用。 • while语句多用于不需要赋初值的或循环次数不定的情况。 for语句多用于要赋初值或循环次数固定的情况。 do-while语句多用于至少要运行一次的循环控制。 • 循环语句可以嵌套,循环可以并列,但不能交叉。
为了保证循环体正常运行,应该特别注意: • 循环控制条件 • 控制条件的初始状态(初始值) • 循环体内部对控制条件的影响 以上三个方面相互配合,相互影响,共同完成循环控制
外循环 内循环 内循环 §6.7 循环的嵌套 • 定义:一个循环体内又包含了另一个完整的循环结构 • 三种循环可互相嵌套,层数不限 (4) for( ; ;) { …… do { …… }while(); …… while() { …… } …... } (1) while() { …… while() { …… } …... } (2) do { …… do { …… }while( ); …... }while( ); (3) while() { …… do { …… }while( ); ……. }
程序举例 main() { int i,j; for(i=1;i<=2;i++) { printf(“\ni=%d\n”,i); for(j=1;j<=3;j++) printf(“j=%d,”,j); } }
程序举例 内层循环终止 main() { int i,j; for(i=1;i<=2;i++) { printf(“\ni=%d\n”,i); for(j=1;j<=3;j++) printf(“j=%d,”,j); } } j=2 j=4 j=3
程序举例 循环全部终止 main() { int i,j; for(i=1;i<=2;i++) { printf(“\ni=%d\n”,i); for(j=1;j<=3;j++) printf(“j=%d,”,j); } } i=2 i=3 运行结果:
三种循环可互相嵌套,层数不限 • 外层循环可包含两个以上内循环,但不能相互交叉 • 嵌套循环的执行流程 • 嵌套循环的跳转 禁止: • 从外层跳入内层 • 跳入同层的另一循环 • 向上跳转
<例>:输出下三角形乘法九九表。 1 2 3 4 5 6 7 8 9 --------------------------------------- 1 2 4 3 6 9 4 8 12 16 5 10 15 20 25 6 12 18 24 30 36 7 14 21 28 35 42 49 8 16 24 32 40 48 56 64 9 18 27 36 45 54 63 72 81 假设:行号为i ,列号为j 输出项aij和行(i)、列(j)的关系 i=6 j=5 i*j (1<=j<=i) (1<=i<=9) 则:第 i行中要输出j个乘积