第四章循环1022_第1页
第四章循环1022_第2页
第四章循环1022_第3页
第四章循环1022_第4页
第四章循环1022_第5页
已阅读5页,还剩99页未读 继续免费阅读

下载本文档

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

文档简介

1、第四章 循环结构循环:对同一个程序段重复执行若干次。计算机最擅长的工作之一就是重复。本章内容for语句语句 1数列求和数列求和2输出阶乘表输出阶乘表3素数判定素数判定4while语句和语句和do语句语句 54 5打印素数表打印素数表54 6求和问题1、求3个数的和。输入3个整数,输出其和。2、求10个数的和。输入10个整数,输出其和。3、求100个数的和。输入100个整数,输出其和。4、求n个数的和。首先输入一个整数n,然后输入n个整数,输出他们的和 /求三个数的和#includeint main() int n1, n2, n3; scanf(%d%d%d, &n1, &n2, &n3);

2、printf(“%dn”, n1 + n2 + n3); return 0;/程序程序4-1:求求10个数的和个数的和#includeint main() int n1, n2, n3, n4, n5, n6, n7, n8, n9, n10; int sum=0; scanf(%d%d%d%d%d, &n1,&n2,&n3,&n4,&n5); scanf(%d%d%d%d%d, &n6,&n7,&n8,&n9,&n10); sum=sum+n1+n2+n3+n4+n5; sum=sum+n6+n7+n8+n9+n10; printf(%dn,sum); return 0;求100个数的和呢?

3、n个数的和呢?n的值在程序运行中才确定求和问题10个数求和可以理解为:以下动作重复执行10次 (1)读入一个数存入number; (2) 将number累加到sum上 C语言提供了循环语句来实现重复。程序程序4-2/*用for语句实现10个数的求和*/#includeint main() int number, i, sum; sum=0; for(i=1; i=10; i=i+1) /重复10次 scanf(%d, &number); sum=sum+number; printf(%dn,sum); return 0;到VC中单步执行一下,监视i、number和sum的变化4.1 求n个数的

4、和解决问题:解决问题:求n个数的和。首先输入一个整数n,然后输入n个整数,求他们的和 .分析:(1) 声明变量i, n, number, sum;(2)sum置为0;(3)读入n(4)以下重复n次 读入一个数存入number,把number累加到sum(5)输出sum ; int i, n, number, sum;sum=0;for(i=1; i=n; i=i+1) scanf(%d,&number); sum=sum+number;scanf(%d,&n);/求n个数的和#includeint main() int number, sum; int i, n; /n为数的个数,i为循环变量

5、 sum=0; /sum存储累加和,要初始化为0 scanf(%d,&n); for(i=1; i=n; i+) /用for语句控制循环n次 scanf(%d,&number); sum=sum+number; printf(%dn,sum); return 0;/循环体,即重复的内容/输出累加和这里,将i=i+1写成了i+。+运算符的作用是让变量的值自增1在此处,以下写法等价:i=i+1;i+=1;i+;稍后讨论源程序4-3具有里程碑意义,要求熟练背默for(i=1; i=n; i+)循环控制语句:i将从1变到n,i每次增1,故循环n次真真for(表达式1;表达式2;表达式3) 循环体语句功

6、能: 实现C语句的重复执行4.1.1 for语句3个表达式、循环体语句个表达式、循环体语句!书写顺序和执行顺序不同书写顺序和执行顺序不同!表达式表达式1只执行一次只执行一次for ( i = 1; i = n; i+) scanf(%d,&number); sum=sum+number;假假假for (i = 1; i = n; i+) scanf(%d,&number); sum=sum+number;表达式1:给循环变量赋初值,指定循环的起点。i = 1;表达式2:给出循环的条件,决定循环的继续或结束。i = n;表达式3:设置循环的步长,改变循环变量的值,从而可改变表达式2的真假性。i+

7、;语句:被反复执行的语句,一条语句。for语句的说明循环(控制)变量:for语句中,通过改变或判断某个变量的值来控制循环的执行 for (i = 1; i = n; i+) scanf(%d,&number); sum=sum+number;for语句中的循环变量赋初值赋初值判断其值判断其值 改变其值改变其值/对上例的对上例的for循环做如下改循环做如下改写,看看运行结果写,看看运行结果for (i = 1; i = n; i+) scanf(%d,&number); sum=sum+number;注意复合语句 和空语句 ;for (i = 1; i = n; i+) ; scanf(%d,&

8、number); sum=sum+number;运行结果运行结果:输入输入n之后,只能读入一之后,只能读入一个数,输出结果等于第一个数。个数,输出结果等于第一个数。sum的值等于输入的最后一个数的值等于输入的最后一个数因为重复执行的语句只有因为重复执行的语句只有scanf语句,语句,sum=sum+number;不再是循环的内容不再是循环的内容因为循环体只有一个空语句,因为循环体只有一个空语句,scanf(“%d”,&number); sum=sum+number; 都不在循环体内。都不在循环体内。注意:注意:循环体多于循环体多于1个语句,要用复合语句个语句,要用复合语句 注意:注意:for语

9、句的()后没有分号语句的()后没有分号不要在不要在for语句中随意加分号语句中随意加分号/左侧的程序段等价于左侧的程序段等价于for (i = 1; i = n; i+) scanf(%d,&number); sum=sum+number;/左侧的程序段等价于左侧的程序段等价于for (i = 1; i = n; i+) ; scanf(%d,&number); sum=sum+number;4.1.2 自增自减运算符 自增(+)自减(-)运算符是具有赋值功能的运算符,例如:a+与a=a+1等价;a-与a=a-1等价 运算对象:只能是变量 运算结果:变量的值增加1或减少1 写出如下程序段的结果

10、int number=5;number+;printf(%dn, number);结果为6int number=5;number+1;printf(%dn, number);结果为5for语句中的自增自减运算符以下几种写法等价for (i = 1; i = n; i+ ) for (i = 1; i = n; +i ) for (i = 1; i = n; i=i+1 )for (i = 1; i = n; i+=1 )但以下写法是错误的, 可能造成死循环for (i = 1; i = n; i+1) /i的值没有得到改变自增自减运算符的前置与后置 如果出现在表达式中,+运算的前置和后置有不同

11、意义。 a+: 先使用变量a的值,然后a自增1 +a: 先让a自增1,再使用a的值int number=5;printf(%dn, number+);输出为5输出number的值之后number的值再变为6int number=5;printf(%dn, +number);输出为6先将number的值变为6,然后输出其值等价于:printf(%dn, number);number=number+1;等价于:等价于:number=number+1;printf(%dn, number);int i=3, k;k=( i+)*2;printf(%d %dn, i, k);4 6int i=3, k

12、;k=(+i)*2;printf(%d %dn, i, k);4 8将5读入,存入n4.1.3 求n个数的最大值擂台赛的思想: 第1个人先站在擂台上,后面的n-1个人依次上台与台上的人较量,若胜之,则取代之站在擂台上接受挑战,最后仍站在台上的就是擂主。 用第一个数作为临时最大值max(将第一个数存入max), 依次读入其余n-1个数,若当前数大于max,则其值存入max,循环结束时 max中就是最大值。 max56 4 7 9 3number 6将第一个数读入,直接存入max循环4次,将第二个以后的数,依次存入number, 然后跟max比较,若大于max,则存入max输入: 4 7 7 9

13、9 3最后max中就是最大值解决问题:解决问题:输入n和n个整数,输出其最大值。4.1.3 求n个数的最大值实现过程:(1) 声明变量i, number, n, max;(2) 读入n(3) 读入第一个数,作为临时最大值(4)以下重复n-1次 读入一个数存入number; 如果number大于临时最大值max 则将number的值赋给max(5)输出max ; scanf(%d,&n);scanf(%d,&max);for(i=1; imax) max=number;/求n个数的最大值#includeint main() int a, max; int i, n; /n为数的个数,i为循环变量

14、 scanf(%d, &n); scanf(%d, &number); max=number; /max存储最大值,要用第一个数作为临时最大值 for(i=1; i max) max = number; printf(%dn,max); return 0;/其余n-1个数依次读入,并与max比较,若大于max,则存入max源程序4-4:求最大值模仿练习 输入n和n个学生成绩(实数),输出不及格率,结果保留两位小数。 输入样例:898 45 86 79 56 75 90 70 输出样例:0.25 分析:(1) 声明变量i, n, failNum, score;(2) 读入n;failNum=0;

15、(3)以下重复n次 读入一个数存入score; 如果score60 failNum增1(4)输出1.0*failNum/n ; 模仿练习 输入n和n个整数,输出其中负数、0、和正数的个数。 输入样例:62 3 0 -1 6 -8 输出样例:2 1 3即2个负数、1个0、3个正数 求下列数列的和1、求 1+2+n2、求 的前n项和,保留3位小数3、求 的前n项和。4、求 的前n项和。5、求 的前n项和。6、求 的前n项和。4.2 数列求和.917151311.957453321917151311.514131211求 1+2+n#includeint main() in

16、t sum=0, n; scanf(%dn, &n); sum=1+2+3+.+n; printf(%dn,sum);编译器不认识不要告诉我用高斯公式,我们在讨论for循环!抽取具有共性的算式:sum=sum+i;循环n次,i从1变到n,循环内容为: sum=sum+i;当i从1变到n,正好将1、2n都累加到sum中源程序4-5#includeint main() int i, n, sum; scanf(%dn, &n); sum=0; for(i=1; i=n; i+) sum = sum + i; printf(%dn, sum); 到VC中单步执行一下,监视i和sum的变化 初始化:指

17、定循环起点 给循环变量赋初值,如i = 1; 进入循环前,设置相关变量的初值,如sum = 0。 条件控制: 只要i 100,循环结束。for循环的四个部分求 /求求 1+2+n#includeint main() int i, sum, n; scanf(%d, &n); sum=0; for(i=1; i=n; i+) sum = sum + i; printf(%dn, sum);改写如下1+2+.+n的程序,求 的前n项和,结果保留3位小数。/程序程序4-6:求求 1+1/2+1/n#includeint main() int i, n; double sum; scanf(%d, &

18、n); sum=0; for(i=1; i=n; i+) sum = sum + 1.0/i; printf(%.3fn, sum);.51413121111111.2345结果sum定义为double注意写成1.0/i,因为整数相除结果是整数改写如下程序,求以上序列的前n项和,结果保留3位小数。求 /求求 1+1/2+1/n#includeint main() int i, n; double sum; scanf(%dn, n); sum=0; for(i=1; i=n; i+) sum = sum + 1.0/i; printf(%.3fn, sum);11111.3579方法1:第i项

19、的分母是2*i-1第n项的分母是2*n-1故分母的变化是:1、3、5、2*n-1, 每次增2for(i=1; i=2*n-1; i=i+2) sum = sum + 1.0/i;i=2*n-1; i=i+2)/程序程序4-7a求求 1+1/3+1/5+前前n项和项和求 /源程序源程序4-7b:求求 1+1/3+1/5+1/7+#includeint main() int i, n; double sum; scanf(%dn, &n); sum=0; for(i=1; i=n; i+) sum = sum + 1.0/(2*i-1); printf(%.3fn, sum);方法2:循环变量i只

20、控制项数,每次增1: for(i=1; i=n; i+)观察分母与循环变量i的关系:第i项的分母为2*i-111111.3579求 /源程序源程序4-7c:求求 1+1/3+1/5+1/7+int main() int i, n, deno; double sum; scanf(%dn, &n); sum=0; deno=1; for(i=1; i=n; i+) sum = sum + 1.0/deno; deno=deno+2; /为下次循环做准备 printf(%.3fn, sum);方法3:循环变量i只控制项数,每次增1: for(i=1; i=n; i+)观察分母的变化规律:每次增加2

21、增加一个变量deno,初始化为1,每次使用完,增加2, 为下一项做准备。11111.3579求 前n项和 11111.3579flag是在+1.0和-1.0之间变换,为避免整数除法运算,把flag定义为实数。/源程序源程序4-8:求求 1+1/3+1/5+1/7+int main() int i, n, deno; double sum, flag; scanf(%dn, &n); sum=0; deno=1; flag=1.0; for(i=1; i=n; i+) sum = sum + flag/deno; deno=deno+2; /为下次循环做准备 flag=-flag; printf

22、(%.3fn, sum);思路分析:有了刚才递推的思想,符号的变化可以用一个变量flag来控制,使其在+1和-1之间变换,每次循环使flag符号取反切记循环开始之前,相关变量的初始化,如sum清0,分母为1,符号为正模仿练习.16113110171411求如下数列的前n项和,结果保留3位小数。1、2、.116957453321符号每次取反;分母每次增加3符号每次取反;分母每次增加2;分子就用循环变量i;切记相关变量的初始化上机练习 1336累加和累加和 1337n个数求和个数求和 1338数列求和数列求和 1339数列求和数列求和 1340数列求和数列求和 1341最大值最大值 1342对数表

23、对数表 1346数值统计数值统计 1347平方和与立方和平方和与立方和 1348奇数的乘积奇数的乘积 1359数列求和数列求和4.3 阶乘表阶乘的结果要存储为什么类型?n是一个不大于20的整数,估算一下20!是一个多少位的十进制整数?32位整型显然表达不了要用double类型或64位整型解决问题: 输入一个整数n(n=20),输出1-n的阶乘表:1 12 23 64 24.实现思路fact=1;for (i = 1; i = n ; i+) 计算i的阶乘;(前一项结果*i) 输出结果 fact = fact * i; printf(“%d %dn”, i, fact);要充分利用中间结果,递推

24、求解,切记不要把本题写成双重循环#include int main() int i, n; double fact; scanf (%d, &n) ; for (fact=1, i = 1; i = n; i+ ) fact = fact * i ; /递推计算i的阶乘 printf ( %d %.0f n, i, fact ); return 0;源程序4-9:输出阶乘表4.3.1逗号运算符及其表达式逗号运算符,又称为顺序求值运算符;用逗号运算符连接起来的式子,称为逗号表达式1、一般形式 表达式1,表达式2,.,表达式n 例如:3+5, 6*9 x=2, y=x+4, z=x*y2、求解过程

25、:从左至右,依次计算,最后一个表达式的值就是整个表达式的值。 逗号表达式3+5, 4*9的值为36 a= (3+5, 4*9); /则a的值为36逗号表达式的求解逗号运算符的优先级低于赋值运算符。a= (3+5, 4*9); /则a的值为36;a= 3+5, 4*9 ; /则a的值为8,虽然整个逗号表达式的值是36b = (a= 3+5, 4*9) ; /则b的值为36,a的值为8x=2, y=x+4, z= x*y; / 则z的值为12, 逗号表达式的值是12z = ( x=2, y=x+4, x*y); / 则z的值为12计算过程如下: (1)执行赋值表达式x=2, 把2赋给x; (2)

26、执行赋值表达式y=x+4, 把6赋给y; (3) 计算x*y的值12, 并将12作为整个逗号表达式的值 (4)把12赋给z;逗号表达式的应用(1)1、顺序求值,如x=2, y=x+4, z=x*y;2、有时可用逗号表达式代替大括号的作用大括号的作用是把多个语句当做一个复合语句,有时候用逗号也可以起到同样的效果,并使语句更简化紧凑,特别是多个具有承接而又相对独立的语句。 举例:三个整数排序/三个数的排序#includeint main() int a,b,t; scanf(%d%d%d, &a,&b,&c); if(ab) /用复合语句 t=a; a=b; b=t; if(ac) /用复合语句

27、t=a; a=c; c=t; if(bc) /用复合语句 t=b; b=c; c=t; printf(%d %d, a,b); return 0;/三个数的排序#includeint main() int a,b,t; scanf(%d%d%d, &a,&b,&c); if(ab) / 用逗号表达式t=a, a=b, b=t; if(ac) / 用逗号表达式t=a, a=c, c=t; if(bc) / 用逗号表达式t=b, b=c, c=t; printf(%d %d, a,b); return 0;逗号表达式的应用(2)3、在只能用一个表达式的语法限制下,进行多项操作,可用逗号表达式。如:

28、for (fact=1, i=1; i0) 先读入n,然后判断n0是否成立,将该结果作为逗号表达式的结果模仿练习1、求1! + 2! + . + n!,其中n不大于20.思路分析:(1)定义变量i, n, fact, sum,fact存阶乘值,sum存累加和;fact和sum要声明为什么类型?(2) fact初始化为1,sum初始化为0;(3) for(i=1; i=n; i+) 计算i的阶乘fact; 将fact累加到sum中; (4) 输出sum;课堂练习计算 的前20项和。357sin( ).3!5!7!xxxxx先找规律:后一项与前一项相比:符号如何变?分子如何变?分母如何变?解题思路

29、(1)定义相关变量i, num(分子)、demo(分母),flag(符号),sum(累加和)(2)读入x(3)初始化: flag=1; num=x; demo=1; sum=0;(4)计算前20项for(i=1;i=20;i+) sum=sum+flag*num/demo; /计算当前项并累加 /为下一项做准备 flag=-flag; /符号取反 num=num*x*x; /计算下一项的分子 demo=demo*(2*i)*(2*i+1) ; /计算下一项分母(5)输出结果4.3.2 计算a+aa+aaa+解决问题:输入n和a,求a+aa+aaa+aaa(n个a),0=a,n=9,如当n=3,

30、 a=2时,2+22+222的结果为246思路分析:(1)定义变量i, n, a, item,sum,item存当前项,sum存累加和;(2) item初始化为0,sum初始化为0;(3) for(i=1; i=n; i+) 计算当前项item(i个a); 将item累加到sum中; (4) 输出sum;如何递推计算当前项有同学这样递推第i项:item = a * pow(10, i) + item;从理论上是对的,但程序的运行结果不一定正确。原因是pow函数的返回值是实数,比如pow(10, 2)可能存储为99.999999,转换为整数时截断取整是99,而不是100,造成结果错误。为避免截断

31、取整带来的错误,可以加上一个很小的数,如做如下处理,则可得到正确结果item = a * (pow(10,i) + 0.00001) + item;如何由第i-1得到第i项?找规律:后一项与前一项相比:第i-1项乘以10,加上aitem = item * 10 + a;建议:整数运算要避免实型函数源程序4-10/求a+aa+aaa+.#includeint main() int i, n, a, item, sum; scanf(%d%d, &n, &a); item = 0; /item初始化为0 sum = 0; for(i=1; i=n; i+) /先计算第i项,再累加 item = i

32、tem * 10 + a; sum = sum + item; printf(%dn, sum); return 0;/求a+aa+aaa+.#includeint main() int i, n, a, item, sum; scanf(%d%d, &n, &a); item = a; /item初始化为a sum = 0; for(i=1; i=n; i+) /先累加,再为下一项做准备 sum = sum + item; item = item * 10 + a; printf(%dn, sum); return 0;有同学将sum初始化为a,然后循环n-1次,这样做的问题是:当n为0时,

33、结果是错误的。解决问题:解决问题:若m是素数,则输出“yes”,否则输出“no”。素数的定义:除了1和m,不能被其它数整除。注意,1不是素数。4.4 素数判定定义:除了1和m,不能被其它数整除。数学理论:若m是合数,必有一个因数属于区间2, ,即若m不能被 2, 的任何整数整除,m必为素数。mm4.4 素数判定以判断13769是否是素数为例,讨论如何判断。尝试用2、3、4、5、117去除m有两种可能情况:(1)尝试完所有数,均不能整除m,则m是素数(2)尝试到某一个数i,能整除m,可得出结论m不是素数,提前结束尝试实现思路(1)flag=0; /m被整除的标志,0表示没有整除,1表示整除 k=

34、sqrt(m); (2)尝试i=2.k if(m是i的倍数) 则m不是素数,flag=1; break; 否则,做下一次循环,尝试下一个整数 (3)若flag=0,则m是素数,否则,m不是素数只要有一个i能整除m,就可以得到m不是素数的结论,提前结束循环最后判断一下flag,若为1就说明m能被某个i整除,m不是素数。反之,flag是0说明在循环过程中flag没有被赋值赋到1,也就是m没有被整除!flag是m能否被整除的标志,故称为标志变量主要代码k=sqrt(m);flag=0; /0代表m没有被整除,1代表m被某个数整除for(i = 2; i = k; i+) if(m % i = 0)

35、flag=1; break; if(flag=0) printf(yesn)else printf(non”);break语句用于提前结束循环本程序的bug上述程序没有考虑m为1的情况。在问题描述中,输入的m是一个“正整数”,那么对于所有合法输入,上述程序都应该能得到正确结果,可是当输入为1时,上述程序的输出是错误的,因为1不是素数。k=sqrt(m);flag=0; /0代表m没有被整除,1代表m被某个数整除for(i = 2; i = k; i+) if(m % i = 0) flag=1; break; if(m=1) flag=1;if(flag=0) printf(yesn)else

36、 printf(non”);处理m为1的情况4.4.2 循环中的break利用break语句能够强制结束循环,转到后续语句执行。for(i = 2; i k时结束,一个是当m是某个i的倍数,if (m % i = 0)条件成立时,通过break结束其实,即使没有flag变量,循环结束后,通过判断循环使因为哪种原因结束的,也可以知道m是否是素数。如果循环是因为m是某个i的倍数,if条件成立,由break结束循环,则i的值必不大于kif(i=k),则m不是素数否则,m是素数4.4.3 循环中的continue#includeint main() int i; for(i=1; i=100; i+)

37、 if(i%7=0)continue; printf(%d ,i); 输出结果: 1 2 3 4 5 6 8 9 10 11 12 13 15 16 17 18 .利用continue语句能中断循环体的本次执行(即跳过循环体中尚未执行的语句),立即开始执行下一次循环。例子:输出1-100,遇到7的倍数则跳过遇到7的倍数,立即执行下一次循环break与continue/分析如下程序的输出结果#includeint main() int i; for(i=1;i=100;i+) if(i%7=0) break; printf(%d ,i); 输出结果:1 2 3 4 5 6 遇到第一个7,就中断了

38、循环continue语句中断循环的本次执行,立即开始执行下一次循环;break是立即结束循环把上例中的continue改为break,看看结果如何明7暗7过(敲7) #includeint main() int i; for(i=1;i=100;i+) if(i%7!=0 & i%10!=7 & i/10!=7) printf(%d ,i); printf(n);#includeint main() int i; for(i=1;i=100;i+) if(i%7=0)continue; if(i%10=7)continue; if(i/10=7)continue; printf(%d ,i);

39、 printf(n);如果i不是7的倍数,且不含有数字7,则输出如果i是7的倍数则跳过如果i个位是7则跳过如果i十位是7则跳过规则: 按顺序从1开始数数,逢7的倍数或是带有7的数字,必须以敲桌子代替。请用明7暗7过的规则,输出100以内的整数。4.4.4 缺省表达式的for语句for(表达式表达式1; 表达式表达式2; 表达式表达式3) 循环体语句循环体语句中的三个表达式都可缺省,但两个分号不能缺省。以下4个程序段等价for (i = 1; i = n; i+) sum = sum + i; i = 1;for ( ; i = n; i+) sum = sum + i; i = 1;for (

40、 ; i n)break; 把初始化放在循环之前循环变量增值放在循环体中缺省表达式2可理解为表达式2为永真,循环的结束的控制由break实现上机作业 1345前n项和 1349阶乘的累加和 1350素数判定 1364 四则运算(多次计算) 1368 求解不等式4.5 求若干学生的总成绩从键盘输入一批学生的成绩,计算总成绩。输入负数表示输入结束。问题分析:问题分析:求累加和确定循环条件:不知道输入数据的个数,无法事先确定循环次数用一个特殊的数据(比如一个负数)作为正常输入数据的结束标志。思路分析: (1)定义变量score, sum; (2)读入一个成绩score; (3)while(score

41、=0),做 把成绩累加到sum上; 读下一个学生成绩score; (4)输出总成绩sum为什么要先读入一个成绩?因为进入while循环首先先进行score=0的判断读入下一个成绩,为下一次循环做准备源程序4-14#include int main(void) double score, sum; sum=0; scanf(%lf, &score); while (score = 0) sum = sum + score; scanf (“%lf”, &score);printf(“%.2fn, sum);return 0;/计算总成绩,逗号表达式计算总成绩,逗号表达式#include int

42、main(void) double score, sum; sum=0; while ( scanf(“%lf”, &score), score = 0) sum = sum + score; printf(“%.2fn, sum);return 0;while中的表达式是一个逗号表达式,先执行scanf,读入一个实数存入score,然后判断score=0,并将其值作为逗号表达式的值4.5.1 while语句while (表达式) 循环体语句;功能:表达式为真时,重复执行循环体语句 真真假假while下一条语句下一条语句表达式表达式循环体语句循环体语句while( n != 0 ) /当n非0

43、 n = n/10; /扔掉n的个位数字 digits+; /位数加1n != 0n = n/10;digits+;课堂练习:以下程序段的运行结果?(1)i=0;while(i5) printf(i=%dn,i);i+;i=0i=1i=2i=3i=4请用请用for循环改写这个程序段循环改写这个程序段:for( i=0; i5; i+) printf(i=%dn,i);(2)i=k=1;while(i5)k+=i;printf(i=%d,k=%dn,i,k);i=1,k=2i=1,k=3i=1,k=4i=1,k=5i=1,k=6死循环!死循环!i5永真永真课堂练习:以下程序段的运行结果?(3)i

44、=0;while(i=4) printf(*n); i+=2;*死循环!死循环!无论无论i值在循环体中如何变化,赋值表达式值在循环体中如何变化,赋值表达式i=4 为永真,是死循环。为永真,是死循环。课堂练习:以下程序段的运行结果?(4)i=0;while(i=4) printf(i=%dni); i+=2;无输出无输出进入循环时首先测试进入循环时首先测试 i=4 的值为假,结束循环。的值为假,结束循环。循环体一次也不执行,无输出。循环体一次也不执行,无输出。课堂练习:以下程序段的运行结果?while 语句和for语句表达式表达式1;while (表达式表达式2) for的循环体语句的循环体语句

45、; 表达式表达式3;把把for语句改写成语句改写成while语句语句for(表达式表达式1; 表达式表达式2; 表达式表达式3) 循环体语句循环体语句for (i = 1; i = 10; i+) sum = sum + i; i = 1; /循环变量赋初值循环变量赋初值while (i = a & ch = A & ch = 0 & ch = 9) digit +; else other +; printf(letter=%d, digit=%d, other=%dn, letter, digit, other); return 0; 源程序4-15while中的表达式是一个逗号表达式,先读

46、入字符存入ch,然后判断ch!=n,并将其值作为逗号表达式的值4.5.3 整数的位数 解决问题:输入一个整数n(int范围内),输出n的位数。方法1:n 最多是一个10位数,用10个分支的else if语句不推荐!没有循环和结构化变量的程序不值得编写思路分析:思路分析:反复除以10取整,看看多少次之后n变成0,n就有多少位。digits=0; /位数初始化为0当n非0,重复如下操作 n = n/10; /扔掉n的个位数字 digits+; /位数加1源程序4-16#includeint main() int n, digits; scanf(%d,&n); digits = 0; /位数初始化

47、为0 while( n != 0 ) /当n非0,重复如下操作 n = n/10; /扔掉n的个位数字 digits+; /位数加1 printf(%dn,digits); return 0; while循环:当n!=0为真时,重复执行循环体本程序有bug。考虑:如果输入0,输出什么?if(n = 0 )digits = 1;模仿练习输入一个正整数n,逆序输出n的各位数字,用空格隔开。4.5.4 do语句do 循环体语句 while (表达式)先执行一次循环先执行一次循环后判断后判断真真假假表达式表达式循环体语句循环体语句do-while的下一条语句的下一条语句 while 是先判别条件,再决

48、定是否循环; do-while 是先至少循环一次,然后再根据循环的结果决定是否继续循环。while语句和do语句的比较真真假假表达式表达式循环体语句循环体语句do-while的下一条语句的下一条语句真真假假while的下一条语句的下一条语句表达式表达式循环体语句循环体语句用while语句实现求位数/ 求n的位数int main() int n, digits; scanf(%d,&n); if(n = 0 )digits = 1; digits = 0; /位数初始化为0 while( n != 0 ) /当n非0,重复如下操作 n = n/10; /扔掉n的个位数字 digits+; /位数

49、加1 printf(%dn,digits); return 0; 当n为0时,while循环一次也不执行,所以digits为0;故必须加上语句 if(n = 0 )digits = 1;用do语句实现求位数#includeint main() int n, digits; scanf(%d,&n); digits = 0; /位数初始化为0 do n = n/10; /扔掉n的个位数字 digits+; /位数加1 while( n != 0 ) printf(%dn, digits); return 0; 即使n为0,也执行了一次循环,所以digits增为1,不必再对n为0的情况做特殊处理。

50、课堂练习从键盘输入一批学生的成绩,输出最高分。从键盘输入一批学生的成绩,输出最高分。输入负数表示输入结束。输入负数表示输入结束。注意变量的初始化注意变量的初始化4.6 打印素数表解决问题:输出100以内的所有素数。思路分析:对n=2、3、.100,做 判断n是否是素数,若是素数则输出n的值 判断n是否是素数,也需要用循环实现: k=sqrt(n); flag=0; for(i=2; i=k; i+) if(n%i=0) flag=1; break; if(falg = 0)输出n主要代码段分析for(n=2; n=100; n+) k=sqrt(n); flag=0; for(i=2; i=k

51、; i+) if(n%i=0) flag=1; break; if(flag=0) printf(%d , n);判断n是否是素数,若是则输出n4.6.1 多重循环 如果循环语句的循环体内又包含了另一条循环语句,则称为多重循环,或循环的嵌套。for(i=0; i=m; i+) . for(j=0; j=n; j+) . .由i控制的外部循环,每执行一次循环体,都执行由j控制的内部循环(j由0变到n)。左侧的二重循环最内层的循环体会执行m*n次其实循环可以嵌套任意多层。变量初始化的位置 初学多重循环,最容易犯的错误时变量初始化的位置不对。flag=0;for(n=2; n=100; n+) k=

52、sqrt(n); for(i=2; i=k; i+) if(n%i=0) flag=1; break; if(flag=0) printf(%d , n);将左侧打印素数表的程序段改写成程序后,运行结果是:2 3分析原因到VC中单步执行,发现当n为4时,flag被置为1之后,其值始终是1,所以4以后的数都没有被输出。flag=1;变量初始化位置不对应该放在每次内循环开始前flag=0;4.6.2 n元钱买n只鸡解决问题:n元钱买n只鸡。经典的百钱买百鸡问题是:公鸡五文钱一只,母鸡三文钱一只,鸡仔一文钱三只,用100文钱买100只鸡,公鸡、母鸡、鸡仔各买多少只? 本程序要求解的问题是:给定一个正

53、整数n,用n文钱买n只鸡,问公鸡、母鸡、鸡仔各买多少只? 如果问题有解,输出所有解,每个解占一行,每个整数用空格隔开;如果问题无解,则输出” No answer”。问题分析:三个变量,两个约束条件,如何求解?计算机解决这类问题用的方法是枚举。枚举是常用计算思维方法之一。思路分析(1)用flag作为有无解的状态标志(2)枚举公鸡的个数,i从0到n/5逐个尝试 枚举母鸡的个数,j从1到n/3逐个尝试 鸡仔个数为n-i-j; 若i个公鸡,j个母鸡和,k个鸡仔价格为n 则输出一个解, 并置标志flag为1; 若flag=0,输出“No answer”。#includeint main() int i,

54、 j, k, n, flag; scanf(%d,&n); flag=0; /flag为有无解标志,有解为1,无解为0 for(i=0; i=n/5; i+) /穷举公鸡的可能个数 for(j=0; j=n/3; j+) /穷举母鸡的可能个数 k=n-i-j; /其余是鸡仔 if( i*15+j*9+k = n*3) /若i, j和k满足要求 printf(“%d %d %dn”, i, j, k); /输出一个解 flag=1; /有解标志置为1 if (flag=0) /若无解 printf(No answern); return 0;源程序4-18为什么写为i*15+j*9+k = n*

55、3,而不是是i*5+j*3+k/3=n到VC中试试,分析为何要避免整数除法或小数运算4.6.3 goto 语句继续考虑4.14的n元钱买n只鸡的问题,若问题的输出要求变为:若有解,只输出一个解,即公鸡数量最少的那个解;若无解,输出” No answer”。问题分析:找到第一个解后如何让求解过程结束?方法一:使用break语句,可以实现,不过要注意break语句只能停止本层循环,不能停止外层循环,结束多层循环需要较为复杂的逻辑。方法二:使用goto语句。方法一:用break语句结束多层循环flag=0; for(i=0; i=n/5; i+) for(j=0; j=n/3; j+) k=n-i-

56、j; if( i*15+j*9+k = n*3) /若找到一个解 printf(“%d %d %dn”, i, j, k); /输出一个解 flag=1; /有解标志置为1 break; /结束循环内循环(由j控制的循环) if(flag=1) break; /若已找到解,结束外循环(由i控制的循环) if (flag=0) /若无解 printf(No answern);若找到解,用break结束内层循环,在外层循环中也要加上:若flag为1, 结束外层循环方法二:使用goto语句跳出多重循环flag=0; for(i=0; i=n/5; i+) for(j=0; j=n/3; j+) k=

57、n-i-j; if( i*15+j*9+k = n*3) /若找到一个解 printf(“%d %d %dn”, i, j, k); /输出一个解 flag=1; /有解标志置为1 goto PRN; /使用goto语句直接跳转到循环结构之后的语句 PRN: if (flag=0) /若无解 printf(No answern); PRN为语句标号,标示程序的特定位置Goto PRN; 直接跳转到语句标号为PRN的位置goto语句的使用 goto语句格式: goto 语句标号;语句标号:语句标号是一个标示符加一个冒号组成,它标示程序地一个特定位置,一般放在一段可执行语句的左边。功能:将程序转到

58、指定的位置继续执行goto语句是一个古老的语句,是循环语句的前身(在计算机发展的早期,程序就是由几个语句+语句标号+跳转语句组成的) goto语句如何实现循环?#includeint main() int sum,i; sum=0; i=1;loop: sum=sum+i; i+; if(i=100) goto loop; printf(%dn,sum); return 0;如果i=100,跳转到loop处,从而实现循环goto语句通常不用,主要因为它将使程序层次不清,且不易读,且带来隐患。但在多层嵌套退出时, 用goto语句则比较合理 2022-5-2684 题目的输入数据和输出数据有多组(不定),对每一组输入都应有相应的输出。也就是运行一次程序进行多次计算。通过循环来实现通过循环来实现4.7 多实例测试多实例测试先从先从a+b开始:开始:2022-5-2685初学者很常见的一种写法:初学者很常见的一种写法: #include int main() int a,b; scanf(“%d %d”,&a,&b); printf(“%d”,a+b); 2022-5-26864.7.1 多实例第一类多实例第一类 例4.19: a+b(一)一) 求a+b,输入包含N组数据,下面接着N组数据,每组数据包含两个整数a和b,对每组

温馨提示

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

评论

0/150

提交评论