第06章 循环结构程序设计_第1页
第06章 循环结构程序设计_第2页
第06章 循环结构程序设计_第3页
第06章 循环结构程序设计_第4页
第06章 循环结构程序设计_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

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

文档简介

第6章循环结构程序设计制作人:王敬华第6章:循环结构程序设计

学习的意义

语言程序设计教程第六章循环结构程序设计C许多实际问题中往往需要有规律地重复某些操作,如菜谱中可以有:“打鸡蛋直到泡沫状”这样的步骤,也就是说,在鸡蛋没有打成泡沫状时要反复地打。相应的操作在计算机程序中就体现为某些语句的重复执行,这就时所谓的循环。

下面来思考一个问题:如何编程来计算1+2+3+…+100?程序如下:ints=0;s=s+1;s=s+2;s=s+3;

……s=s+100;

printf(“s=%d”,s);重复100次,晕!!!有没有更好的方法来计算呢?有!就是用循环来编程。第4章已讨论程序结构顺序结构选择结构循环结构本章讨论第5章已讨论

While、do-while、for语句循环嵌套

Break、continue、goto语句

exit()函数循环结构类型的选择及转换循环结构程序设计举例本章小结学习目标

理解循环结构的含义;掌握C语言三种循环结构的特点;掌握while、do-while、for、goto、break、continue语句的使用方法;掌握不同循环结构的选择及其转换方法;掌握混合控制结构程序设计的方法。

学习内容

语言程序设计教程第六章循环结构程序设计C6.1循环结构的程序设计

1.while语句语言程序设计教程第六章循环结构程序设计C一般形式:while(表达式)

循环体语句;执行流程:F

Texpr循环体while其中:

while后面的括号()不能省。

while后面的表达式可以是任意类型的表达式,但一般是条件表达式或逻辑表达式。表达式的值是是循环的控制条件。语句部分称为循环体,当需要执行多条语句时,应使用复合语句。

特点:先判断表达式,再执行循环体语言程序设计教程第六章循环结构程序设计C【例】用while语句求1~100的累计和。

#include<stdio.h>voidmain(){

inti=1,sum=0;

while(i<=100){sum+=i; i++; }

printf("sum=%d\n",sum);}循环初值循环终值循环条件循环体循环变量增值运行结果:sum=5050【例】显示1~10的平方

#include<stdio.h>

voidmain(){

inti=1;while(i<=10){

printf("%d*%d=%d\n",i,i,i*i);i++;}}运行结果:1*1=12*2=43*3=94*4=165*5=256*6=367*7=498*8=649*9=8110*10=100语言程序设计教程第六章循环结构程序设计C

(1)如果while后的表达式的值一开始就为假,循环体将一次也不执行。

(2)循环体中的语句可为任意类型的C语句。

(3)遇到下列情况,退出while循环:

表达式为假(为0)。循环体内遇到break、return或goto语句(break和goto语句将在随后介绍)。语言程序设计教程第六章循环结构程序设计C

while语句注意事项:inta=0,b=0;while(a>0)//a>0为假,b++不可能执行

b++;intnum=0;//字符计数while(1){if(getche()=='\n')//如果输入的字符是回车符,则返回

return;num++;}

(4)在执行while语句之前,循环控制变量必须初始化,否则执行的结果将是不可预知的。

(5)要在while语句的某处(表达式或循环体内)改变循环控制变量,否则极易构成死循环。

(6)允许while语句的循环体又是while语句,从而形成双重循环。

语言程序设计教程第六章循环结构程序设计C

while语句注意事项:例:计算10!#include<stdio.h>voidmain(){

inti;//i应赋初始值10longs=1;while(i>=1)s*=i--;

printf("10!=%ld\n",s);}i=1;while(i<100)//死循环,因为i的值没变化,永远小于100sum+=i;printf("sum=%d\n",sum);

i=1;while(i<=9){j=1;

while(j<=9){

printf("%d*%d=%d\n",i,j,i*j);j++;}i++;}【例】求两个正整数的最大公因子。

我们采用Euclid(欧几里德)算法来求最大公因子,其算法是:

(1)输入两个正整数m和n。

(2)用m除以n,余数为r,如果r等于0,则n是最大公因子,算法结束,否则(3)。

(3)把n赋给m,把r赋给n,转(2)。#include<stdio.h>voidmain(){

intm,n,r;

printf("Pleaseinputtwopositiveinteger:");

scanf("%d%d",&m,&n);while(n!=0){r=m%n;//求余数

m=n;n=r;}

printf("Theirgreatestcommondivisoris%d\n",m);}运行结果:Pleaseinputtwopositiveinteger:2456↙Theirgreatestcommondivisoris8语言程序设计教程第六章循环结构程序设计C2.do_while语句语言程序设计教程第六章循环结构程序设计C一般形式:do

循环体语句;while(表达式);执行流程:其中:

while后面的括号()不能省。

while最后面的分号;不能省。

while后面的表达式可以是任意类型的表达式,但一般是条件表达式或逻辑表达式。表达式的值是是循环的控制条件。语句部分称为循环体,当需要执行多条语句时,应使用复合语句。

F

Texpr循环体dowhile特点:先执行循环体,再判断表达式语言程序设计教程第六章循环结构程序设计C【例】用do_while语句求1~100的累计和。

#include<stdio.h>voidmain(){

inti=1,sum=0;

do{sum+=i; i++; }while(i<=100);

printf("sum=%d\n",sum);}运行结果:sum=5050语言程序设计教程第六章循环结构程序设计C

do_while语句注意事项:

inta=0,b=0;dob++;while(a>0);

(1)如果do-while后的表达式的值一开始就为假,循环体还是要执行一次。

(2)在if语句、while语句中,表达式后面都不能加分号,而在do-while语句的表达式后面则必须加分号,否则将产生语法错误。

(3)循环体中的语句可为任意类型的C语句。

(4)和while语句一样,在使用do-while语句时,不要忘记初始化循环控制变量,否则执行的结果将是不可预知的。

(5)要在do-while语句的某处(表达式或循环体内)改变循环控制变量的值,否则极易构成死循环。

(6)do-while语句也可以组成多重循环,而且也可以和while语句相互嵌套。

3.for语句语言程序设计教程第六章循环结构程序设计C一般形式:for(表达式1;表达式2;表达式3)

循环体语句;执行流程:其中:

for后面的括号()不能省。

表达式1:一般为赋值表达式,给控制变量赋初值。

表达式2:关系表达式或逻辑表达式,循环控制条件。

表达式3:一般为赋值表达式,给控制变量增量或减量。表达式之间用分号分隔。语句部分称为循环体,当需要执行多条语句时,应使用复合语句。FTexpr2循环体forexpr1expr3for语句很好地体现了正确表达循环结构应注意的三个问题:控制变量的初始化。循环的条件。循环控制变量的更新。语言程序设计教程第六章循环结构程序设计C【例】用for语句求1~100的累计和。

#include<stdio.h>voidmain(){

inti,sum=0;

for(i=1;i<=100;i++)sum+=i;

printf("sum=%d\n",sum);}运行结果:sum=5050语言程序设计教程第六章循环结构程序设计C

for语句注意事项:例:计算1*2+3*4+5*6+…+99*100。

inti,j;longsum=0;for(i=1,j=2;i<=99;i=i+2,j=j+2)sum+=i*j;printf("sum=%ld\n",sum);

(1)表达式1、表达式2、和表达式3可以是任何类型的表达式。比方说,这三个表达式都可以是逗号表达式,即每个表达式都可由多个表达式组成。

逗号表达式逗号表达式#include<stdio.h>voidmain(){

inti,sum=0;i=1;for(;i<=100;i++)sum+=i;

printf("sum=%d\n",sum);}#include<stdio.h>voidmain(){

inti,sum=0;i=1;for(;i<=100;)sum+=i++;

printf("sum=%d\n",sum);}语言程序设计教程第六章循环结构程序设计C

for语句注意事项:省掉表达式1,3省掉表达式1

(2)表达式1、表达式2、和表达式3都是任选项,可以省掉其中的一个、两个或全部,但其用于间隔的分号是一个也不能省的。#include<stdio.h>voidmain(){

inti,sum=0;i=1;for(;;){if(i>100)break;sum+=i++;}

printf("sum=%d\n",sum);}省掉表达式1,2,3语言程序设计教程第六章循环结构程序设计C

for语句注意事项:for(a=1;;a++)

printf("&d\n",a);

(3)表达式2如果为空则相当于表达式2的值是真。死循环!

(4)循环体中的语句可为任意类型的C语句。

(5)for语句也可以组成多重循环,而且也可以和while语句和do-while语句相互嵌套。

(6)循环体可以是空语句。例:计算用户输入的字符数(当输入是回车符时统计结束)。

#include<stdio.h>voidmain(){

intn=0;

printf("inputastring:\n");for(;getchar()!='\n';n++);

printf("%d",n);}表示循环体为空语句,并非表示for语句结束三种循环可互相嵌套,层数不限外层循环可包含两个以上内循环,但不能相互交叉嵌套循环的执行流程(1)while(){……while(){……}…...}(2)do{……do{……}while();…...}while();(3)while(){……do{……}while();…….}嵌套循环的跳转禁止:从外层跳入内层跳入同层的另一循环向上跳转语言程序设计教程第六章循环结构程序设计C4.循环嵌套

(4)for(;;){……do{……}while();……while(){……}…...}外循环内循环内循环【例】循环嵌套,输出九九表1234567891234567892468101214161836912151821242791827364554637281……………..ij语言程序设计教程第六章循环结构程序设计C#include<stdio.h>voidmain(){

inti,j;for(i=1;i<10;i++)

printf("%4d",i);

printf("\n---------------------------------------\n");for(i=1;i<10;i++)for(j=1;j<10;j++)

printf((j==9)?"%4d\n":"%4d",i*j);}i<10printf假(0)真(非0)i=1j++j=1j<10真(非0)假(0)i++外循环内循环语言程序设计教程第六章循环结构程序设计Cfor(i=1;i<10;i++)

for(j=1;j<10;j++)

printf((j==9)?"%4d\n":"%4d",i*j);语言程序设计教程第六章循环结构程序设计C5.break与continue语句

break语句功能:在循环语句和switch语句中,终止并跳出循环体或开关体说明:(1)break不能用于循环语句和switch语句之外的任何其它语句之中。(2)break只能终止并跳出最近一层的结构。while(表达式1){

……if(表达式2)break;……}语句……do{

……if(表达式2)break;……}while(表达式1);语句……for(;表达式1;){……if(表达式2)break;……}语句……语言程序设计教程第六章循环结构程序设计C【例】将用户输入的小写字母转换成大写字母,直到输入非小写字母字符。

#include<stdio.h>voidmain(){charc;while(1){c=getchar();//读取一个字符

if(c>='a'&&c<='z')//是小写字母

putchar(c-'a'+'A');//输出其大写字母

else//不是小写字母

break;

//循环退出

}}运行结果:howareyou↙HOWAREYOU

语言程序设计教程第六章循环结构程序设计C

方法:通过设置一标志变量tag,然后在每层循环后加上一条语句:if(tag)break;

其值为1表示跳出循环体,为0则不跳出。for(…){while(…){……if(…)break;…}while循环后的第一条语句}inttag=0;for(…){while(…){……if(…){tag=1;break;}……}if(tag)break;……}for循环后的第一条语句

多重循环中,break的使用问:在嵌套循环的情况下,如何让break语句跳出最外层的的循环体?语言程序设计教程第六章循环结构程序设计Ccontinue语句功能:结束本次循环,跳过循环体中尚未执行的语句,进行下一次是否执行循环体的判断。说明:(1)仅用于循环语句中。(2)在嵌套循环的情况下,continue语句只对包含它的最内层的循环体语句起作用。for(…){while(…){……if(…)continue;……}while循环后的第一条语句}语言程序设计教程第六章循环结构程序设计C【例】求输入的十个整数中正数的个数及其平均值。#include<stdio.h>voidmain(){

inti,a,num=0;floatsum=0;for(i=0;i<10;i++){

scanf("%d",&a);//输入一整数

if(a<=0)continue;

//如果为负,则输入下一个整数

num++;//正数个数增1sum+=a;//正数和累加

}

printf("%dplusinteger'ssum:%.0f\n",num,sum);

printf("averagevalue:%.2f\n",sum/num);}运行结果:8plusinteger'ssum:45averagevalue:5.63假设输入的10个整数为:123–45–678910

语言程序设计教程第六章循环结构程序设计C5.goto语句

一般形式:

goto

语句标号;……语句标号:……语句标号:…………

goto

语句标号;或说明:

语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto

语句配合使用。

作用:

goto语句的作用是在不需要任何条件的情况下直接使程序跳转到该语句标号所标识的语句去执行。

语言程序设计教程第六章循环结构程序设计C

goto语句的应用:例:求1~100的累计和

#include<stdio.h>voidmain(){

inti=1,sum=0;

loop:sum+=i++;if(i<=100)//如果i小于或等于100

gotoloop;

//转到标号为loop的语句去执行

printf("sum=%d\n",sum);}

(1)goto语句可与条件语句配合使用来实现条件转移,构成循环。

(2)在嵌套循环的情况下,利用goto语句可以直接从最内层的循环体跳出最外层的循环体。

inttag=0;for(…){while(…){……if(…)gotostop;……}……}stop:for循环后的第一条语句

注意:在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。语言程序设计教程第六章循环结构程序设计C6.exit()函数

功能:说明:参数status为int型,status的值传给调用进程(一般为操作系统)。按照惯例,当status的值为0或为宏常量EXIT_SUCCESS时,表示程序正常退出;当status的值为非0或为宏常量EXIT_FAILURE时,表示程序出现某种错误后退出。

终止整个程序的执行,强制返回操作系统。

调用形式:voidexit(intstatus);头文件

<stdlib.h>程序设计分析:由数学知识可知,求三角形面积的公式是:其中,a、b、c是三角形的三个边长,s=(a+b+c)/2。因此,程序中应该有三个float型变量用来存放a、b、c的值,为了方便起见,还应有一个变量存放s,最后有必要设置一个变量来存放三角形的面积值。公式中存在求平方根的操作,这要用到C语言数学库函数sqrt。sqrt函数带有一个参数,它的功能是返回参数的平方根。程序在开始接受用户输入的三角形的三个边长后,首先要对这三边作合法性检查,如三边中有某一边长度小于或等于0,则终止程序的执行,同样如果s*(s-a)*(s-b)*(s-c)为负,也要终止程序的执行。语言程序设计教程第六章循环结构程序设计C【例】

输入三角形的边长,求三角形面积。

#include<stdio.h>#include<stdlib.h>#include<math.h>voidmain(){floata,b,c;floats,area;

printf("inputthelengthofthreeedgesoftriangle:");

scanf("%f%f%f",&a,&b,&c);if(a<=0||b<=0||c<=0){

printf("thelengthofthreeedgesoftriangleiserror!\n");

exit(-1);}

s=(a+b+c)/2;s=s*(s-a)*(s-b)*(s-c);if(s<0){

printf("thelengthofthreeedgesoftriangleiserror!\n");

exit(-1);}area=(float)sqrt(s);

printf("area=%.2f\n",area);}运行结果:inputthelengthofthreeedgesoftriangle:345↙area=6.00inputthelengthofthreeedgesoftriangle:3-45↙thelengthofthreeedgesoftriangleiserror!6.2循环结构类型的选择及转换

语言程序设计教程第六章循环结构程序设计C1.循环结构类型的选择原则如果循环次数在执行循环体之前就已确定,一般用for循环;如果循环次数是由循环体的执行情况确定的,一般用while循环或者do-while循环。当循环体至少执行一次时,用do-while循环,反之,如果循环体可能一次也不执行,选用while循环。2.循环结构类型之间的相互转换尽管上面对于循环结构的选择给出了原则性指导意见,但是我们应注意到其实这三种循环结构彼此之间可以相互转换,象前面我们分别用while循环、do-while循环、for循环来求1~100的累计和的例子就说明了这一点。语言程序设计教程第六章循环结构程序设计C【例】求1~100之间的所有素数

问题分析:

素数是指除了能被1和它本身整除外,不能被其它任何整数整除的数。例如,17就是一个素数,除了1和17之外,它不能被2~16之间的任何整数整除。根据素数的这个定义,可得到判断素数的方法:把m作为被除数,把i=2~(m-1)依次作为除数,判断被除数m与除数i相除的结果,若都除不尽,即余数都不为0,则说明m是素数,反之,只要有一次能除尽(余数为0),则说明m存在一个1和它本身以外的另一个因子,它不是素数。事实上,根本用不着除那么多次,用数学的方法可以证明:只需用2~之间(取整数)数去除m,即可得到正确的判定结果。

这一思路的算法如下:从键盘输入一正整数m。计算k=i从2变化到k,依次检查m%i是否为0。若m%i为0,则判定m不是素数,并终止对其余i值的检验;否则,令i=i+1;并继续对其余i值进行检验,直到全部检验完毕为止,这时判定m是素数。#include<stdio.h>#include<math.h>voidmain(){

intm,i,k;

printf("inputanumber:“);

scanf("%d",&m);

k=sqrt(m);i=2;

while(i<=k)

{if(m%i==0)break;i++;}if(i>k)

printf("yes\n");else

printf("no\n");}while循环语言程序设计教程第六章循环结构程序设计C#include<stdio.h>#include<math.h>voidmain(){

intm,i,k;

printf("inputanumber:“);

scanf("%d",&m);k=sqrt(m);

for(i=2;i<=k;i++)if(m%i==0)break;if(i>k)

printf("yes\n");else

printf("no\n");}for循环#include<stdio.h>#include<math.h>voidmain(){

intm,i,k;

printf("inputanumber:“);

scanf("%d",&m);

k=sqrt(m);i=2;

do

{if(m%i==0)break;i++;}while(i<=k);

if(i>k)

printf("yes\n");else

printf("no\n");}do_while循环6.3循环结构程序设计举例

语言程序设计教程第六章循环结构程序设计C

【例1】验证哥德巴赫猜想:任一充分大的偶数,可以用两个素数之和表示。例如:4=2+2,6=3+3,98=19+79这一思路的算法如下:读入大于3的偶数n。

p=1do{p=p+1;q=n-p;p是素数吗?

q是素数吗?

}whilep、q有一个不是素数。输出n=p+q。问题分析:读入一个偶数n,将它分成p和q,使n=p+q。怎样分呢?可以令p从2开始,每次加1,而令q=n-p,如果p、q均为素数,则正为所求,否则令p=p+1再试。flagp=1;for(j=2;j<=(int)sqrt(p);j++)if(p除以j的余数=0){flagp=0;break;}

flagq=1;for(j=2;j<=(int)sqrt(q);j++)if(q除以j的余数=0){flagq=0;break;}

设置两个标志量flagp和flagq,0—是素数,1—不是素数

}while(flagp*flagq==0);

语言程序设计教程第六章循环结构程序设计C#include<stdio.h>#include<stdlib.h>#include<math.h>voidmain(){

inti,n,p,q,flagp,flagq;

printf("pleaseinputn:");

scanf("%d",&n);//输入一偶数

if(n<4||n%2!=0)//如果该数不是偶数

{

printf("inputdataerror!\n");exit(-1);//程序结束

}

p=1;

do{p++;q=n-p;

flagp=1;for(i=2;i<=(int)sqrt(p);i++){if(p%i==0){flagp=0;break;}}

flagq=1;for(i=2;i<=(int)sqrt(q);i++){if(q%i==0){flagq=0;break;}}}while(flagp*flagq==0);

printf("%d=%d+%d\n",n,p,q);}判断p是否为素数

判断q是否为素数

运行结果:pleaseinputn:98↙98=19+79pleaseinputn:9↙inputdataerror!语言程序设计教程第六章循环结构程序设计C

【例】利用下面的公式求π的近似值,要求累加到最后一项小于10-6为止。问题分析:这是一个累加求和的问题,但这里的循环次数是预先未知的,而且累加项以正负交替的规律出现,如何解决这类问题呢?在本例中,累加项的构成规律可用寻找累加项通式的方法得到,具体表示为t=s/n;即累加项由分子和分母两部分组成,分子s按+1,-1,+1,-1,…交替变化,可用赋值语句s=-s;实现,s的初始值取为1,分母n按1,3,5,7,…变化,用n=n+2;语句实现即可,n的初始值取为1.0。#include<stdio.h>#include<math.h>voidmain(){

ints=1;floatn=1.0,t=1,pi=0;while(fabs(t)>=1e-6){pi+=t;n+=2;s=-s;t=s/n;}pi*=4;

printf("pi=%.6f\n",pi);}运行结果:pi=3.141594语言程序设计教程第六章循环结构程序设计C

【例】打印大小可变的菱形图案(下面菱形的大小是7)。

﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡﹡问题分析:菱形的大小size其实就是中间行中*号的个数,也是整个菱形的行数,其值必须是奇数。

问题的关键之一是如何确定每行中*号的个数。经过分析得知:当行数i(假设最上面的一行为第1行)≦(size+1)/2时,该行上的*号个数为n=2*i-1,否则n=2*(size-i+1)-1。

问题的关键之二是如何确定每行显示的第一个*号的位置,也就是显示第一个*号之前应显示多少个空格。经过分析得知:每行应显示的空格数为m=(size-n)/2个。

#include<stdio.h>#include<stdlib.h>voidmain(){

inti,j,k,m,n,size;

printf("inputsize:");//输入大小提示

scanf(“%d”,&size);//输入大小

//如果为小于或等于0的数或为偶数

if(size<=0||size%2==0){

printf("thesizeiserror!\n");exit(-1);//程序结束

}

for(i=1;i<=size;i++)//控制行数

{n=(i<=(size+1)/2)?i:size-i+1;//每行中"*"号的个数

n=2*n-1;m=(size-n)/2+15;//每行打印"*"之前应打印的空格数

for(k=1;k<=m;k++)//打印每行前面的空格

printf("");for(j=1;j<=n;j++)//打印每行的"*"

printf("*");

printf("\n");//打印一行后,回车换行

}}语言程序设计教程第六章循环结构程序设计C

【例】计算用户输入的两正整数之间的所有整数中0,1,2,…,9数码的个数。例如,101~104之间总共包含四个整数101,102,103,104,其中0的个数为4,1的个数为5,2、3、4的个数都为1,其余数码没出现都为0。问题分析:问题的关键是要计算某整数中包含的各个数码的个数,必须对该整数进行分解,求得所包含的各个数码,其方法可以通过每次除以10取余数得到,然后再对商进行同样的处理,直到商为0时为止。对所得到的数码进行计数,可采用switch语句来实现。#include<stdio.h>#include<stdlib.h>voidmain(){

intnum1,num2;

intn,s,r;

温馨提示

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

评论

0/150

提交评论