950 likes | 1.17k Views
第 6 章 循环结构程序设计. 6.1 循环的概念. 循环结构是结构化程序设计的三种基本结构之一,在数值计算和很多问题的处理中都需要用到循环控制。例如各种数学用表(三角函数表、对数表、平方根表等)的计算,用迭代法求方程的根,计算全班同学的平均分等。几乎所有的应用程序都包含循环,它和顺序结构、选择结构共同作为各种复杂结构程序的基本构造单元。因此熟练地掌握选择结构和循环结构的概念及使用是程序设计最基本的要求。 C语言提供了以下 3 种循环语句来实现: ( 1 ) while( ) ~循环语句;
E N D
6.1 循环的概念 • 循环结构是结构化程序设计的三种基本结构之一,在数值计算和很多问题的处理中都需要用到循环控制。例如各种数学用表(三角函数表、对数表、平方根表等)的计算,用迭代法求方程的根,计算全班同学的平均分等。几乎所有的应用程序都包含循环,它和顺序结构、选择结构共同作为各种复杂结构程序的基本构造单元。因此熟练地掌握选择结构和循环结构的概念及使用是程序设计最基本的要求。 • C语言提供了以下3种循环语句来实现: • (1)while( )~循环语句; • (2)do~while ( )循环语句; • (3)for( )~循环语句。 • 下面我们将分别介绍这三种循环语句。
6.2 while语句 • while用来实现“当型”循环,其一般形式为: • while(循环条件表达式) • 循环体语句 • 在执行while语句时,先对循环条件表达式进行计算,若其值为非0(真),则反复执行循环体语句,直到循环 • 条件表达式的值为0(假)时,循环结束,程序控制转至while • 循环语句的下一条语句。其执行过程如图6.1所示。
6.2 while语句 • 使用while语句时,应注意以下几个问题: • (1)循环体是一个简单语句,或一组语句。当循环体是一组 • 语句时,则必须用{}括起来,组成复合语句。
6.2 while语句 • #include <stdio.h> • void main() • { int i,sum; • sum=0; /* 置累计和sum的初值为0 */ • i=1; /* 置增量i的初值为1 */ • while(i<=100) /* 当i≦10时,循环执行循环体 */ • { sum=sum+i; /* 循环体语句 */ • i=i+1; /* 循环体语句 */ • } • printf("sum=%d\n",sum); • } 程序运行结果: sum=5050
6.2 while语句 • (2)循环体内一定要有使表达式的值变为0(假)的操作,否 • 则循环将永远不会停止,即形成“死循环”。 • (3)while语句中的循环条件表达式一般是关系表达式或逻辑 • 表达式,但也可以是数值表达式或字符表达式,只要其值非0就可 • 以执行循环体语句。 • #include <stdio.h> • void main() • { int i; • printf("input i:"); • scanf("%d",&i); • while(i--) • printf("%5d",i); • } 程序运行结果: 4 3 2 1 0
6.2 while语句 • (4)while语句的特点是“先判断,后执行”,如果循环条件表达 • 式的值一开始就为0,则循环体语句一次也不执行,但要注意的 • 是:循环条件表达式是一定要执行的。 • (5)循环体也可以什么都不做,这时相当于是一个空语句。 • #include <stdio.h> • void main() • { char c; • while((c=getchar())==‘ ’||c==‘\t’||c==‘\n’) /*越过输入中的空白符、 • ;制表符和回车符 */ • putchar(c); • }
6.2 while语句 • 例6.1 利用下面级数求π的值,要求计算到4000项。 • 分析:每项分母为奇数,且相邻项符号取反,要求计算到4000 • 项时,停止求累加和。假设用sum表示累加和,那么π的近似 • 值p可以表示为 pi=4sum。
6.2 while语句 • #include <stdio.h> • void main() • { float sum=0,f=1; • int n=1,k=0; • while(k<4000) /* 当计算到4000项时结束 */ • { sum=sum+f/n; /* 计算通项,并计算累加和 */ • k++; /* 计算累加项数 */ • f=-f; /* 相邻项符号取反 */ • n+=2; /* 加2得到下一个奇数 */ • } • printf(“pi=%8.6f\n”,4*sum); • } 程序运行结果: pi=3.141345
6.2 while语句 • 例 6.2 从键盘上连续输入字符,直到输入“回车”符为止,统计输入的字符中数字字符的个数。
6.2 while语句 • #include <stdio.h> • void main() • { char ch; • int num=0; • printf("Press enter to end input <Enter>\n"); • while((ch=getchar())!='\n') /* 输入回车键时循环结束 */ • { if(ch>='0'&&ch<='9') /* 只对数字字符的个数进行统计 */ • { putchar(ch); /* 输出数字字符 */ • num=num+1; /* 对数字字符的个数进行累加统计 */ • } • } • printf("\nnum=%d\n",num); • } 程序运行结果: 5!a66bc7↙ 5667 num=4
6.3 do~while循环 • do~while用来实现“直到型”循环,其一般形式为: • do • 循环体语句 • while(循环条件表达式); • 执行过程是,先执行循环体语句,然后对循环条件表达式进行计算,若其值为真(非0),则重复上述过程,直到循环条件表达式的值为假(0)时,循环结束,程序控制转至该结构的下一条语句。
6.3 do~while循环 • 图6.4 do~while语句的执行过程
6.3 do~while循环 • 使用do~while语句时,应注意以下几个问题: • (1)循环体是一个简单语句,或一组语句。当循环体是一组 • 语句时,则必须用{}括起来,组成复合语句。 • (2)循环体内一定要有使表达式的值变为0(假)的操作,否 • 则循环将永远不会停止。 • (3)do~while循环是先执行,后判断,因此循环体至少执行 • 一次。 • (4)do和while都是关键字,配合起来使用,while(循环条件表 • 达式)后面的“;”不可缺少。 • (5)C语言中的do~while循环与其它高级语言典型的直到型循 • 环有所不同,典型的直到型循环是条件为假时继续循环,条件 • 为真时结束循环。而C语言的do~while循环是条件为真时继续 • 循环,条件为假时结束循环。
6.3 do~while循环 • 例6.3 用do~while循环编写计算sum=1+2+3+……+100的程序。
6.3 do~while循环 • #include <stdio.h> • void main( ) • { int sum=0,i=1; • do • { sum=sum+i; • i++; • }while(i<=100); • printf("sum=%d\n",sum); • }
6.3 do~while循环 • 例6.4 输入若干个学生的成绩,直到输入负数结束,求平均成绩。 • #include <stdio.h> • void main() • { int num=0; • float score,sum=0,ave; • printf("input score of student:\n"); • scanf("%f",&score); • do • { num++; /* 统计学生数 */ • sum=sum+score; /* 累加学生的成绩之和 */ • scanf("%f",&score); • }while(score>=0); /* 以输入负数结束程序 */ • ave=sum/num; /* 计算平均成绩 */ • printf("average=%6.2f\n",ave); • } 程序运行结果: 65↙ 98↙ 55↙ -1↙ average= 72.67
6.4 for循环 • C语言的for循环使用最为灵活,功能很强。不仅可以用于计数型循环,而且 • 可以用于条件型循环。完全可以代替while和do~while循环。 • for循环语句的一般形式为: • for(表达式1;表达式2;表达式3) • 循环体语句; • 其中,for是C语言的关键字,其后圆括号通常有3个表达式,主要用于for循 • 环控制。表达式之间用分号隔开,表达式是C语言中任何合法的表达式。表达式1 • 给循环变量赋初值;表达式2是循环条件;表达式3修改循环变量值。for后面的语 • 句为循环体。循环体多于一条语句时,要用复合语句表示。 • for循环语句的作用是:首先求解表达式1的值,然后求解表达式2的值,若表 • 达式的值非0(真)时,就执行循环体,执行一次循环体后求解表达式3的值,再 • 求解表达式2的值,若表达式2仍不为0再执行循环体,再求解表达式3的值。如此 • 反复直到表达式2的值为0时,整个循环结束。其执行过程如图6.6所示。
6.4 for循环 • for语句最简单的应用形式,也就是最易理解的形式: • for(循环变量赋初值;循环条件;循环变量增值) • 循环体语句;
6.4 for循环 • 例如:用for循环编写计算sum=1+2+3+……+100的流程图如图所示。
6.4 for循环 • 基于图6.7所描述的算法编写的程序如下: • #include <stdio.h> • void main() • { int sum=0,i; • for(i=1;i<=100;i++) • sum=sum+i; • printf(“sum=%d\n”,sum); • }
6.4 for循环 • 使用for语句时,应注意以下几个问题: • (1)表达式1可以省略。省略后形式如下: • for( ;表达式2;表达式3) • 这时没有了给循环变量赋初值的操作,程序设计者应在for语句之前给 • 循环变量赋初值。 • (2)表达式3可以省略。省略后形式如下: • for(表达式1;表达式2; ) • 这时没有了循环变量增值的操作,程序设计者应在循环体内设置改变循环 • 变量的值,使循环正常结束。 • (3)表达式1和表达式3可以同时省略。省略后形式如下: • for( ;表达式2; ) • 没有了循环变量增值的操作,也没有改变循环变量值的操作,这时的 • for循环完全相当于while循环。程序设计者应在for语句之前给循环变量赋初 • 值,循环体内改变循环变量的值,使循环正常结束。
6.4 for循环 (3)表达式1和表达式3可以同时省略。省略后形式如下: for( ;表达式2;) 没有了循环变量增值的操作,也没有改变循环变量值的操作,这时的for循环完全相当于while循环。程序设计者应在for语句之前给循环变量赋初值,循环体内改变循环变量的值,使循环正常结束。
6.4 for循环 • #include <stdio.h> #include <stdio.h> • void main() void main() • { int sum=0,i=1; { int sum=0,i=1; • for( ;i<=100; ) while(i<=100) • { sum=sum+i; { sum=sum+i; • i++; i++; • } } • printf("sum=%d\n",sum); } • printf("sum=%d\n",sum); • }
6.4 for循环 • (4)表达式2不能省略。 • for(表达式1; ;表达式3) • 这时不判断循环的条件,是一个死循环,因此不能省略 • 表达式。 • (5)不能同时省略三个表达式。 • for( ; ;) • 这时没有表达式2,不判断循环的条件,是一个死循环, • 因此不能同时省略三个表达式。 • (6)for语句括号内的两个分号,在任何情况下都不能省略。 • (7)表达式1、表达式3也可以是与循环变量无关的操作。 • (8)表达式2的值也可以是任何类型的,系统只看它的值,非 • 0就执行循环体语句,为0就退出循环。
例6.5 编写一个程序,输入10个学生的成绩,输出最高成绩和最低成绩。 #include <stdio.h> void main() { int i; float score,max,min; printf("input 10 score:\n"); scanf("%f",&score); max=score; min=score; for(i=2;i<=10;i++) { scanf("%f",&score); if(score>max) max=score; if(score<min) min=score; } printf("\nmax=%6.2f min=%6.2f\n",max,min); } 6.4 for循环
程序运行结果: input 10 score: 89 66 48 98 100 79 85 90 68↙ max=100.00 min=48.00 如果程序中没有给出学生的具体数量,那么我们可以把循环语句改为: for( ;score>=0; ) 以输入负数结束程序。当然,还要把scanf(“%f”,&score); 语句放到循环体语句的最后一行。 6.4 for循环
6.5 break语句和continue语句 • 6.5.1 break语句 • break语句的一般形式为: • break; • break语句的作用是从最内层的switch、for、while或do~while循环语句中跳出,终止这些语句的执行,把控制转到被中断的循环语句或switch语句后去执行。 • 通过使用break语句,可以不必等到循环或switch语句执行结束,而是根据情况,提前结束这些语句的执行。
6.5 break语句和continue语句 • 例6.6 计算sum=1+2+3+…+n,当sum<1000时,n的最大值。
6.5 break语句和continue语句 • #include <stdio.h> • void main() • { int sum=0,i=1; • while(1) • { sum=sum+i; • if(sum>=1000) /*判别条件sum<1000*/ • break; /*条件满足,则提前结束循环*/ • i++; /* i增值1 */ • } • printf("i=%d\n",i-1); • } 这里while(1)是一个无限的循环,当sum的值大于等于1000时,退出循环执行:printf(“n=%d\n”,n-1); 语句。因为执行sum=sum+n后,sum的值大于等于1000,在执行前一次循环时sum的值还小于1000,因此,n-1是sum小于1000的最大值。 注意:break语句对if…else的条件语句不起作用,在多层循环中,一个break语句只向外跳一层。 程序运行结果: i=44
6.5 break语句和continue语句 • 6.5.2 continue语句 • continue语句的一般形式为: • continue; • 其作用是结束本次循环,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判断。
6.5 break语句和continue语句 • 例 6.7 计算 sum=1+2+3+4+6+7+8+9+11+12+13+14+16+…+94+96+97+98+99
6.5 break语句和continue语句 • #include <stdio.h> • void main() • { int sum=0,i; • for(i=1;i<100;i++) • { if(i%5==0) /*判断i是否是被5整除的数*/ • continue; /*i是被5整除的数,则结束本次循环*/ • sum+=i; /*i不是被5整除的数,则进行累加*/ • } • printf("sum=%d\n",sum); • } 程序运行结果: sum=4000 注意:当i%5==0时(即i=5,10,15,…,95)结束本次循环,不执行sum+=i; 而转去执行i++,后判断i是否小于100,若小于100进行下一次循环。这样sum中加上的都是不能被5整除的数。
6.5 break语句和continue语句 • 例6.8 分析下面程序的执行结果。 • #include <stdio.h> • void main() • { int k,b; • for(b=1,k=1;k<100;k++) • { if(b>10) • break; • if(b%2==1) • { b+=3; • continue; • } • b--; • } • printf(“k=%d,b=%d\n”,k,b); • } 分析: 循环变量k的值 循环体执行后b的值 k b 1 4 2 3 3 6 4 5 5 8 6 7 7 10 8 9 9 12 10 因此输出结果为: k=10,b=12
6.5 break语句和continue语句 • 请读者注意continue语句和break语句的区别: • continue语句只结束本次循环,而不是终止整个循环的`执行;break语句则是结束循环,不再进行条件判断。
6.5 break语句和continue语句 • 例6.9 有一张纸厚0.5mm,假设它足够大,不断把它对折,问对折 • 多少次后它的厚度可以达到珠穆朗玛峰的高度(8848m)。 • #include <stdio.h> • void main() • { int n=0; • float h=0.5; • while(1) • { n++; • h=2*h; • if(h>=8848000) • break; • } • printf(“n=%d\n”,n); • } 程序运行结果: n=25
6.5 break语句和continue语句 • 程序也可以写成: • #include <stdio.h> • void main() • { int n=0; • float h=0.5; • while(1) • { n++; • h=2*h; • if(h<8848000) • continue; • printf(“n=%d\n”,n); • break; • } • }
6.5 break语句和continue语句 • 程序最简单的形式可写成: • #include <stdio.h> • void main() • { int n=0; • float h=0.5; • while(h<8848000) • { n++; • h=2*h; • } • printf(“n=%d\n”,n); • }
6.6 多重循环 • 一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。内嵌的循环体内还可以嵌套循环,这就是多重循环。 • 循环嵌套有以下几种形式: • (1) (2) (3) • while() while() for( ; ; ) • { ··· { ··· { ··· • while() do while() • { ··· { ··· { ··· • } }while(); } • } } }
6.6 多重循环 • (4) (5) (6) • do do for( ; ; ) • { ··· { ··· { ··· • for( ; ; ) do for( ; ; ) • { ··· { ··· { ··· • } }while(); } • }while(); }while(); }
6.6 多重循环 • 例6.10 以下面形式输出九九乘法表。 • 1×1=1 • 2×1=2 2×2=4 • 3×1=3 3×2=3 3×3=9 • … • 9×1=9 9×2=18 … 9×9=81
6.6 多重循环 分析:求积可以用两层for循环结构实现: for(i=1;i<=9;i++) /* i表示被乘数 */ for(j=1;j<=i;j++) /* j表示乘数 */ t=i*j; 第一个for语句,称为外循环,i表示被乘数。第二个for语句,称为内循环,j表示乘数。嵌套重复循环结构总是先完整地执行内循环一次,外循环再执行一次。 例如: 在外循环i=1时,内循环执行9次,求出第一行的积: 1×1=1 1×2=2 1×3=3… 1×8=8 1×9=9 执行内循环1次后,i增加1,在外循环i=2时,内循环执行9次,求出第二行的积: 2×1=2 2×2=4 2×3=6… 2×8=16 2×9=18 外循环如此重复9次,就可算出9行数据。