1.07k likes | 1.31k Views
第 4 章 循环结构程序设计. printf( “ **********<br> ” );. printf( “ **********<br> ” );. 问题的提出. 输出一行 10 个星号“ * ” 语句是?. printf( “ **********<br> ” );. 输出两行 10 个星号“ * ” 语句是?. 输出 100 行 10 个星号“ * ” 语句是?. 用循环结构解决. 问题 1 :. 4.1 循环的概念. 什么是循环? 为什么要使用循环?. 问题 2: 求学生平均成绩 分数相加后除以课数.
E N D
printf(“**********\n”); printf(“**********\n”); 问题的提出 输出一行10个星号“*” 语句是? printf(“**********\n”); 输出两行10个星号“*” 语句是?
输出100行10个星号“*” 语句是? 用循环结构解决
问题1: 4.1 循环的概念 什么是循环? 为什么要使用循环? 问题2:求学生平均成绩分数相加后除以课数 • 在许多问题中需要用到循环控制。循环结构是结构化程序设计的基本结构之一,它和顺序结构、选择结构共同作为各种复杂程序的基本构造单元。 • 循环分为两种:无休止循环和有终止循环 • 构成有效循环的条件:循环体和循环结束条件
本章将介绍的内容 4.1 for 语句 4.2while 语句 4.3 do - while 语句 4.4break语句和continue语句 4.5循环语句的嵌套
4.1 for语句 C语言中的for语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替while语句。 【例4.1】for 语句的引例。 求1+2+3+…+100的值,并将其结果放在变量sum中。 P88
for(i=1;i<=100;i++) sum=sum+i; sum sum=0; 6 5050 sum=sum+1; 3 1 0 不确定 表示为: 规律是: sum=sum+2; for(i=1;i<=100;i++) sum=sum+3; sum=sum+i; …… sum=sum+100; 是for语句!
for 关键字 #include <stdio.h> main( ) { int i=0, sum=0; for ( i=1; i<=100; i++ ) sum=sum+i; printf("1+2+3+......+100=%d\n",sum); } 循环体 运行结果:1+2+3+......+100=5050
for语句的一般形式 for( 表达式1; 表达式2; 表达式3 ) 循环体 注意此处不是“,”!
执行过程 处理表达式1 处理表达式3 表达式2 执行循环体 非0 for语句的执行过程: (1) 先求解表达式1。 (2) 求解表达式2,若其值为真(值为非0),则执行for语句中指定的内嵌语句,然后执行下面第(3)步。若为假(值为0),则结束循环,转到第(5)步。 (3) 求解表达式3。 (4) 转回上面第(2)步骤继续执行。 (5) 循环结束,执行for语句下面的一个语句 0
输出100行10个星号“*” 语句是? for ( i = 1; i <= 100; i = i + 1 ) printf ( “**********\n” ); i++
讨论题4.1 若要计算2+4+6+…+100的值如何书写for语句? for ( i = 2; i <= 100; i = i + 2 )
复合语句 讨论题4.2 如何通过for循环计算 的值? float t=1,sum=0; int i; for ( i = 1; i <= 100; i = i + 1 ) {t=1/i; sum=sum+t ; }
编程点拨:确定两件事情 scanf("%d",&score); printf("%d ",score); sum=sum+score; 【例4.2】键盘输入10个学生的成绩,输出各成绩和平均成绩。 哪些语句重复执行 执行多少次循环体 输入10个,重复10次
main( ) { int i=0,score=0, sum=0; float ave=0; printf("Input score:\n"); printf("\n"); ave=(float)sum/10; printf("ave=%f\n",ave); } for( i=1; i<=10; i++) { scanf("%d",&score); printf("%d ",score); sum=sum+score; } 用复合语句 循环体是3条语句 不必放在循环体内
运行结果如下: Input score: 95 100 65 45 60 89 78 80 83 70 95 100 65 45 60 89 78 80 83 70 ave=76.500000
编程点拨 【例4.3】在3~100之间所有3的倍数中,找出个位数为2的数。 3~100内3的倍数有3 6 9 … 99 for ( i=3; i<=100; i=i+3 ) 用 i%10 表示个位数 if( i%10==2 ) …
将最小的3的倍数3赋给i 当i的值小于等于100时 i个位数是2? 假 真 输出i的值 i的值增3 流程图
72 _ 用三种基本结构能写出所有复杂程序 #include <stdio.h> main( ) { int i=0; for ( i=3; i<=100; i=i+3 ) if( i%10==2 ) printf("%4d",i); printf("\n"); } 循环结构 按4个字符位 输出整数 顺序结构 分支结构 输出: 12 42
讨论题4.3 #include <stdio.h> main( ) { int i=0,j=0; for ( i=102; i<=999; i=i+3 ) { j=i%100; if((j/10==2) ||(j%10==2) ) /* 判断10位数是否是2 */ printf("%4d",i); printf("\n"); } 若将例4.3的功能改为:找出十位或个位是2的所有三位数,程序应如何改写? for ( i=100; i<=999; i=i++ ) { if(i%3==0) /*若是3的倍数 */
编程点拨 算法和求1+2+…+100的算法类似 但在本程序中fac的初值为1,不是0。 【例4.4】输出1!、2!、3!、……、n! 其中n!= 1×2×3×……×n n的值从键盘输入
若为int型,求8!时开始出现溢出现象 不能为0.0 只输出整数部分 #include <stdio.h> main ( ) { int i=0,n=0; float fac=1.0; printf("Input n:"); scanf ( "%d", &n ); for ( i=1; i<=n; i++ ) { fac=fac*i; printf( "%d!=%.0f\n",i,fac); } }
运行结果如下: Input n:20 1!=1 2!=2 …… 19!=121645096004222976 20!=2432902023163674620 (注意,只保证前6~7位是准确的)
若为int型,求2i时开始出现溢出现象 不能为0.0 只输出整数部分 讨论题4.4 #include <stdio.h> main () { int i=0,n=0; double fac=1.0; printf("Input n:"); scanf ( "%d", &n ); for ( i=1; i<=n; i++ ) { fac=fac*2; printf("2^%d=%.0f\n",i,fac); } } 如果要计算21、22、23、…、2n的值,应如何修改本程序?
1) #include <stdio.h> main() { int i=0,n=0; double fac=1.0,sum=0.0; printf(“Input n:”); scanf(“%d”,&n); for(i=1;i<=n;i++) { fac=fac*i; sum=sum+fac } printf(“1+2!+…+%d!=%.lf\n”,n,sum); } 课堂练习 3) #include <stdio.h> main() { int i=0,n=0; double fac=1.0,sum=0.0; printf("Input n: "); scanf("%d ",&n); for(i=1;i<=n;i++) { fac=fac*2; sum=sum+fac; } printf("2^1+2^2+…+2^%d!=%.lf\n",n,sum); } • 修改例4.4中的程序,计算1!+2!+3!+…+n!的值。 • 修改例4.4中的程序,计算21、22、23、…、2n的值。 • 修改例4.4中的程序,计算21+22+23+…+2n的值。
教学总结 本次课的讲授内容是: 1.用循环解决问题的场合。 2.for 语句。 3.累加算法。 4.求平均值算法。 5.连乘算法。
作业 • 完成未做完的课堂练习 • 理解并运行例4.5~4.8 预习 例4.9~例4.15
【例4.5】在两行上分别按顺序和逆序输出 26个英文大写字母。【例4.5】在两行上分别按顺序和逆序输出 26个英文大写字母。 编程点拨 在ASCII码表中,字母按A到Z的顺序排列 使用循环通过A计算 (即’A’+i,i=0,1,2,…,25)
printf("\n"); printf("\n"); #include <stdio.h> main ( ) { int i=0; } for ( i=0; i<=25; i++ ) printf("%c ", 'A'+i); 顺序输出 注意位置 for ( i=25; i>=0; i-- ) printf("%c ", 'A'+i); 逆序输出 不是i++
【例4.6】 从键盘输入10个数,求其中最大值。 编程点拨: 用例3.6中介绍的算法 数据较多,用循环结构
运行时试最大值在 最前最后中间某一位置的情况 思考:100个数中求最大,如何修改? #include <stdio.h> main( ) { int a=0,max=0,i=0; printf("\nmax=%d\n",max); } printf("Input data:"); 输入第一个数并输出 scanf("%d",&a); printf("%d ",a); 第一个数存入max max=a; for ( i=1; i<=9; i++ ) { scanf("%d",&a); printf("%d ",a); 输入后九个数并输出 if ( max<a ) max=a; }
方法2: #include <stdio.h> main( ) { int a=0,max=0,i=0; max=-32768; printf("Input data:"); for(i=1; i<=10; i++) { scanf("%d",&a); printf("%d ",a); if(max<a) max=a; } printf("\n"); printf("max=%d\n",max); }
【例4.7】求 先思考:如何求 for(i=1; i<=100; i++) sum=sum+(float)1/i;
再思考:如何解决正负相间的问题 i=1 sign=1 for ( i=1; i<=100; i++ ) sum=sum+(float) 1 / i; sum=sum+1/1 i=2 sign=-1 sum=sum-1/2 i=3 sign=1 sign=1; sum=sum+1/3 …… { } sign sign=-sign; 符号翻转
运行结果 sum=0.688172 #include <stdio.h> main( ) { int i=0,sign=1; float sum=0.0; 完整程序 for ( i=1; i<=100; i++ ) { sum=sum+(float) sign/ i; sign=-sign; } printf("sum=%f\n",sum); }
运行结果 sum=0.688172 讨论题4.7 #include <stdio.h> main( ) { int i=0,sign=1; float sum=0.0; 如何计算 的值? for ( i=2; i<=100; i=i+2 ) { sum=sum+(float) sign/ i; sign=-sign; } printf("sum=%f\n",sum); }
【例4.8】输出斐波纳契(Fibonacci)级 数1、1、2、3、5、8、13、… 的前30项。 规律:前两项的值各为1,从第3项起,每一项都是前两项的和。 要求:一行输出6项
规律: 1 1 + a b next=a+b; a=b; b=next; 2 next 第3项 • 求解过程 3 a + b next 第4项 2 1 5 a + b next 第5项 2 3 8 a + b next 第6项 3 5 ……
a=b=1; printf("%10ld%10ld",a,b); n=2; 处理前两项 main( ) { int i=0,n=0; long a=0,b=0,next=0; } 处理后28项 for ( i=3; i<=30; i++ ) { next=a+b; a=b; b=next; } printf("%10ld",next); n++; if ( n%6==0 ) printf("\n"); 输出并控制换行
运行结果如下: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040
说明: • 同一个问题,可能有多种算法 • 在学习过程中,勤于思考,善于发现问题,编写出更优化的程序。 • 以上循环共同点:容易确定循环次数 • for语句一般用于循环次数已知的情况。 • 如果次数事先不知,则常用while 语句或do-while语句。
4.2 while语句 P97 【例4.9】从键盘输入若干个非0数据,求它们的和。用0结束循环的执行。 • 编程点拨: • 本题需要用循环结构 • 用for语句不方便 • 下面用while 语句
#include <stdio.h> main( ) { int a=0,sum=0; printf("Input data:\n"); scanf("%d",&a); while ( a!=0 ) { printf("%4d",a); sum=sum+a; scanf("%d",&a); } printf("\nsum=%d\n",sum); } while 当a为非0时,执行循环体 关键字 进入循环前 先输入一个数
Input data: 11 22 33 44 55 66 77 88 99 0 1 2 第1次运行: 11 22 33 44 55 66 77 88 99 sum=495 Ctrl+Break强行结束执行 第2次运行: Input data: 0 (空一行) sum的初值 sum=0
while语句的一般形式: while ( 表达式) 循环体
执行过程 表达式 循环体 非0 0
【例4.10】用while循环求 1+2+3+…+100 #include <stdio.h> main( ) { int ,sum=0; printf("sum=%d\n",sum); } i=1 不同循环语句之间可以相互转换 while ( i<=100 ) sum=sum+i; { } i++;
【例4.11】用公式 求π的近似值,直到最后一项的绝对值小于10-4为止。
编程点拨: • 先计算 的近似值,再求π的近似值 • 不易确定从第几项起,绝对值小于10-4 • 本例用while语句
#include <math.h> 加入一行 next=1,sum=0; sign=1 i=1 while ( ) { } fabs(next) >= 1e-4 main ( ) { int , ; float pi=0, pi=sum*4 ; printf("pi=%f\n",pi); } sum=sum+next; fabs是库函数 求绝对值 sign=-sign; i=i+2; next=(float)sign/i;