工学]04第四章循环结构.ppt_第1页
工学]04第四章循环结构.ppt_第2页
工学]04第四章循环结构.ppt_第3页
工学]04第四章循环结构.ppt_第4页
工学]04第四章循环结构.ppt_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

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

文档简介

第四章 循环结构,用于解决语句的重复执行,以克服一条语句只能执行一次的限制。 while语句 do-while语句 break 和 continue 语句 循环嵌套 循环结构程序设计,本章要点,什么是循环? 为什么要使用循环? 如何实现循环? 实现循环时,如何确定循环条件和循环体? 怎样使用while 和do-while语句实现次数不确定的循环? while 和do-while语句有什么不同? 如何使用break语句处理多循环条件? 如何实现多重循环?,4.1 用格里高利公式求的近似值,使用下列格里高利公式求的近似值,要求精确到最后一项的绝对值小于105。,和以前不同之处在于循环条件,即没有显式地给出循环次数,而是提出了精度要求(|item| 105)。 当 |item| 105时,要循环累加item的值,直到 |item| 105为止。,分析:sum = sum + 第i项,#include #include /* 使用绝对值函数 fabs */ void main( ) int flag, t; double item, pi; /* pi 用于存放累加和 */ flag = 1; /* 变量 flag 表示第 i 项的符号,初始为正 */ t = 1 ; /* 变量 t 表示第 i 项的分母*/ item = 1.0; /* 初始的item 中存放第1项的值*/ pi = 0; /* 置累加和 pi 的初值为0 */ while(fabs (item) = 0.00001) pi = pi + item; /* 累加第 i 项的值 */ flag = -flag; /* 改变符号,为下一项计算做准备 */ t = t +2; /* 分母递增2 ,为下一项计算做准备 */ item = flag * 1.0 / t; /* 计算下一 项的值 */ pi = pi * 4; /* 循环计算结果是 pi/4 */ printf ( “pi = %fn”, pi); ,while 循环, 先判断,后执行,1. while 语句格式,while (条件) 循环体语句;,for(表达式1; 表达式2; 表达式3) 循环体语句,2. while语句与for语句的关系,从while 语句和for语句的执行流程可以看出,它们的执行机制实质上是一样的,都是在循环前先判断条件,只有条件为“真”才进入循环。,可以把for语句改写成while语句: 表达式1; while (表达式2) for的循环体语句; 表达式3; ,例:,main() int i,sum=0; i=1; for (i=1; i=10; i+) while (i=10) sum=sum+i; sum=sum+i; printf(“%d“,sum); i+; ,如:for (i=1; i=10; i+) sum=sum+i; 可以写成 i=1; 循环变量必须有初值 while (i=10) 继续循环的条件 sum=sum+i; i+; 循环变量的改变 ,循环体,3. while 实现要点,例:从键盘输入一批学生的成绩,统计平均分。,分析:这是一个求累加和的问题,将输入的成绩先累加,最后再除以学生的数量,算出平均分。,本题的难点在于确定循环条件,不知道输入数据的个数,所以无法事先确定循环次数。 需要自己设计循环条件,可以用1个特殊的数据作为正常输入数据的结束标志,比如选用一个负数作为结束标志。,#include void main( ) int num; double mark, average; num = 0; average = 0; printf(“Input marks: n“); scanf (“%lf“, ,问题:如果第一个数据就输入 -1,运行结果是什么?,4.2 统计一个整数的位数,例:从键盘读入一个整数,统计该数的位数。如,输入1234,输出4;输入0,输出1。,分析:一个整数由多位数字组成,统计过程需要一位位地数,因此这是个循环过程,循环次数由整数本身的位数决定。由于需要处理的数据有待输入,故无法事先确定循环次数。,程序中引入循环语句 do - while 。,#include void main( ) int count, number; count = 0; printf(“Input a number: “); scanf (“%d“, ,源程序:,如果将do-while语句改为while语句,效果相同吗?,先循环,后判断,1. do-while 语句,do 循环体语句; while (表达式),while 是先判别条件,再决定是否循环; do-while 是先至少循环一次,然后再根据循环的结果决定是否继续循环。,2. while 和 do-while 的比较,3. 循环语句的选择,当循环次数已知时使用for语句 当循环次数未知时 如果循环条件在进入循环时已明确使用while语句 否则使用do-while语句,但是循环条件需要在循环体中明确,(1) 由 while 、do-while 、for 语句构成的循环结构都可以处理同一问题,一般情况下可以互换 (2) while 和 do-while 循环,在while后面只指定循环的条件,而使循环趋于结束的语句包含在循环体中 for 循环可以在“表达式3“中包含使循环趋于结束的操作 (3) 用while 和 do-while循环时,循环变量初始化应在 while 和 do-while之前 for 循环可以在“表达式1“中实现循环变量的初始化 (4) while循环先判断后执行 do-while循环先执行后判断 for循环先判断后执行 (5) 对 while循环、do-while循环、for循环,可以用 break 语句跳出循环,可以用 continue 语句结束本次循环,4. 几种循环的比较,main() int i,sum=0; i=1; while (i=100) sum=sum+i; i+; printf(“%d“,sum); ,main() int i,sum=0; i=1; do sum=sum+i; i+; while(i=100); printf(“%d“,sum); ,while语句 构成的循环,do-while语句 构成的循环,main() int i,sum=0; for (i=1;i=100;i+) sum=sum+i; printf(“%d“,sum); ,for 语句 构成的循环,求 1+2+3+.+100,4.3 判断素数,例:输入一个正整数m,判断它是否为素数。,分析:判断一个数 m 是否为素数,需要检查该数是否能被除 1 和自身以外的其他数整除,即判断 m 能否能被2 m-1之间的数整除。,设 i 取值 2, m-1 ,如果m不能被该区间上的任何一个数整除,即对每个 i ,m%i 都不为0,则m是素数; 只要找到一个 i ,使 m%i 为0,则m肯定不是素数。 m不可能被大于 m/2 的数整除 i 取值可以是 2, m-1 或 2, m/2 或 2, ,#include void main( ) int i, m; printf(“Input a number: “); scanf (“%d“, ,源程序:,#include void main( ) int i, m; printf(“Input a number: “); scanf (“%d“, ,如果改成如下的该程序,还能正确判断素数吗?,1. break语句,当循环结构中出现多个循环条件时,可以由循环语句中的表达式和break语句共同控制。 break语句强制循环结束,使循环提前结束,不再执行循环体中位于其后面的其他语句。 break语句应该和if语句配合使用,即条件满足时,才执行break跳出循环。,必定是经条件判断后执行的,程序: for (表1;表2;表3) 语句1 ; if ( exp ) break ; 语句2 ; for后的下一条语句;,2. break 流程,3. continue语句,continue语句的作用是跳过循环体中continue后面的语句,继续下一次循环。 continue语句一般也需要与 if 语句配合使用。 continue语句和break语句的区别在于,break结束循环,而continue只是跳过后面语句,继续循环。 break除了可以终止循环外,还用于switch语句; 而continue语句只能用于循环。,程序: for (表1;表2;表3) 语句1 ; if ( exp ) continue; 语句2 ; for后的下一条语句;,4. continue 流程,abc efgh 123 ,abc,abcefgh1,5. break 和 continue 应用,#include “stdio.h“ void main( ) char c; int i; for (i = 0; i 10; i+) c = getchar( ); if (c = n) break; putchar(c); ,continue;,下列程序段的输出结果是_。 int k, s; s=0; for(k=0; kk) break; else s = s+k; printf(“k=%d s=%d“, k, s);,输出 k=4 s=6,k s 0 0 1 1 2 3 3 6 4,int k; for ( k= -90 ; k ; k-) printf ( “ % d ”, k ) ; 在编译运行时会遇到 : A) 编译通不过 B) 能运行, 但会死机 C)能运行, 但不会死机 D) 以上说法都不对,在下列选项中,没有构成死循环的程序段是 A) int i=100; while ( 1 ) i=i%100+1; if ( i100 ) break; B) for ( ; ; ) ; C) int k=1000; do +k; while ( k=10000); D) int s=36; while ( s ) ; -s;,下列 for 循环, 将执行 s=0 ; for ( i = 10; ; i - ) if ( i = 0 ) break ; else s = s + i; A) 10 次 B) 11 次 C) 1 次 D) 以上均不是,下列程序段的输出是_。 main() int k; for (k=1; k5; k+) if (k % 2) printf(“*“); else continue; printf(“#“); ,输出: * # * #,4.4 求1! + 2! + . + 100!,例:计算1! + 2! + 3! + + 100!。要求定义和调用函数fact(n)计算n的阶乘。,分析:这是一个求累加和的问题,共循环100次,第 i 项就是 i 的阶乘: sum = sum + 第 i 项 在第2章中介绍了求阶乘的程序,还定义了求阶乘的函数fact,求 i 的阶乘可以直接调用fact(i)。 sum = sum + fact(i),#include double fact (int n); /* 函数声明 */ void main( ) int i; double sum; sum = 0; for(i = 1; i = 100; i+ ) sum = sum + fact (i) ; /* 调用fact(i)求i!,共100次 */ printf(“1! + 2! + 3! + + 100! = %en“, sum); double fact (int n) /* 定义求 n! 的函数 */ int i; double result; result = 1; for (i = 1; i = n; i+) result = result * i ; return result ; ,源程序:,for (i = 1; i = 100; i+) item = i 的阶阵; sum = sum + item; ,for(i = 1; i = 100; i+) item = 1; for (j = 1; j = i; j+) item = item * j; sum = sum + item; ,嵌套循环:,不使用函数也能实现求 i 的阶阵 sum = sum + 第 i 项 求累加和的for语句为: for (i = 1; i = 100; i+) sum = sum + i 的阶阵;,#include void main( ) int i, j; double item, sum; sum = 0; for(i = 1; i = 100; i+) /* 外层循环重复100次,求累加和 * / item = 1; /* 置初值为1,以保证每次求阶乘都从1开始连乘 */ for (j = 1; j = i; j+) /* 内层循环重复i次,算出item = i! */ item = item * j; sum = sum + item; printf(“1! + 2! + 3! + + 100! = %en“, sum); ,for(i = 1; i = 100; i+) item = 1; for (j = 1; j = i; j+) item = item * j; sum = sum + item; ,item = 1; for(i = 1; i = 100; i+) for (j = 1; j = i; j+) item = item * j; sum = sum + item; ,改成这样会有问题吗?,关于嵌套循环的说明:,分析程序中二重循环的执行过程 首先外层循环变量 i 固定在一个值上 然后执行内层循环,内层循环变量 j 变化一个轮次; 外层循环变量 i 再加1,重新执行内层循环,j 再变化一个轮次。 内外层循环变量不能相同,如:分别用 i 和 j。,for(i = 1; i = 100; i+) item = 1; for (j = 1; j = i; j+) item = item * j; sum = sum + item; ,例:输出数据 for (i = 1; i = 100; i+) for (j = 1; j = i; j+) printf (“%d %dn“, i, j );,4.5 循环程序设计,循环程序的实现要点: 归纳出哪些操作需要反复执行? 循环体 这些操作在什么情况下重复执行? 循环控制条件,一旦确定了循环体和循环条件,循环结构也就基本确定了,再选用C语言提供的3种循环语句(for,while和do-while)实现循环。,循环的具体实现又分两种情况: 如果事先给定了循环次数,一般首选for语句; 如果循环次数不明确,需要通过其他条件控制循环,则考虑while语句或do-while语句。,例:从键盘输入一批学生的成绩,找出最高分。,分析:先假设输入的第1个成绩为最高分,然后在循环中读入下一个成绩,并与最高分比较,如果大于最高分,就设它为新的最高分,继续循环,直到所有的成绩都处理完毕。 循环体中进行的操作就是输入和比较,难点在于如何确定循环条件,由于题目没有指定输入数据的个数,需要自己增加循环条件: 先输入一个正整数n,然后再输入n个数据。即循环重复n次,属于指定了循环次数,用for语句实现。 设定一个特殊数据(伪数据)作为循环的结束标志,由于成绩都是正数,选用一个负数作为输入的结束标志。考虑使用 while语句或do-while语句。,#include void main( ) int i, mark, max, n; printf(“input n: “); scanf (“%d“, ,用for语句来实现:,先输入数据个数,用while语句来实现:,#include void main( ) int mark, max; printf(“Input marks: n“); scanf (“%d“, ,用负数表示输入结束,当输入的成绩 mark 大于等于0时,执行循环。,有问题码?,用do-while语句来实现:,#include void main( ) int mark, max; max = -1; printf(“Input marks: n“); do scanf (“%d“, ,用负数表示输入结束,只要读入的数据大于 等于0,就继续循环 。,12345 %10 = 5 12345 /10 =1234 1234 %10 = 4 1234/10 =123 123%10 = 3 123/10 =12 12%10 = 2 12/10 =1 1%10=1 1/10=0 结束,(1)反复执行 x%10 x=x/10 (2)何时结束 x= =0 scanf( “%d”, ,从低位开始分割,例:输入一个正整数,将其逆序输出。例如,输入12345,输出54321。,分析:需要把该数按逆序逐位拆开,用求余运算%分离数字。,#include void main() int x,digit; printf(“input a number: “); scanf(“%d“, ,%10,/10,12345 /10000 = 1 12345 %10000 =2345 2345 /1000 = 2 2345%1000 =345 345 /100 = 3 345%100 =45 45 /10 = 4 45%10 =5 5/1= 5 5%1=5,(1)开始如何得到10000 找输入数据的位数 d=1; for ( i=10; x/i0 ; i=i*10) d+ ; (2) 每次循环缩小10倍 (3) 缩小到 0 结束,例:输入一个正整数,将其顺序输出。例如,输入12345,输出1 2 3 4 5。,从高位开始分割,#include void main( ) int x,d,n,i,j; scanf(“%d“,for (i=1; i=d; i+) n=x/j; printf(“%d, “,n); x=x%j; j=j/10; printf(“n“); ,例:求500以内的全部素数,每行输出10个。,分析:在499次循环中,对2到500之间的每个数进行判断,若是素数,则输出该数。 for (m = 2; m = 500; m+) if (m是素数) printf( “%d“, m); /* 输出素数*/,判断素数的方法:判断数m能否被2 m-1之间的数整除。,实现:使用嵌套循环(二重循环) 外层循环针对2到500之间的所有数, 而内层循环对其中的每一个数判断其是否为素数。,#include #include void main( ) int count, i, m, n; count = 0; for(m = 2; m =m) /* 如果m是素数 */ printf(“%6d“, m); count+; if (count %10 = 0) printf(“n”); ,for (m = 2; m n) printf(“%d“, m); ,源程序:,#include #include int prime(int x); void main( ) int m, n; for(m = 2; m = 500; m+) if(prime(m) printf(“%6d“, m); ,用函数实现判断素数,prime(m)函数判断素数 if m是素数,返回1 否则,返回0,int prime(int m) int i, n, res=1; n = sqrt(m); for( i = 2; i = n; i+) if (m % i = 0) res = 0; break; return res; ,int prime(int m) int i, n; n = sqrt(m); for( i = 2; i n) return 1; else return 0; ,用这个prime(m)函数能正确判断m=1时的情况吗?,例:求菲波那契(Fibonacci)序列:1,1,2,3,5,8,。请输出前10项。,分析:菲波那契(Fibonacci)序列的头两项均为1,后面任一项都是其前两项之和。程序在计算中需

温馨提示

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

评论

0/150

提交评论