第 5章 循环结构程序设计
5.1 循环语句概述
5.2 for语句和 while语句
5.3 直到型循环 do-while语句
5.4 break语句与 continue语句
5.5 应用举例
良好的源程序书写习惯 ──注释 (续)
[Return]
5.1 循环语句概述
求 1~ 100的累计和。
根据已有的知识,可以用,1+2+……+100” 来求解,但显然很繁琐。
现在换个思路来考虑:
首先设置一个累计器 sum,其初值为 0,利用 sum += n来计算( n依
次取 1,2,……, 100),只要解决以下 3个问题即可:
( 1)将 n的初值置为 1;
( 2)每执行 1次,sum += n”后,n增 1;
( 3)当 n增到 101时,停止计算。此时,sum的值就是 1~ 100的累计
和。
根据已有的知识,单独实现每一步都不难。但是,由于需要经常使
用这种重复计算结构(称为循环结构),C语言提供了 3条循环语句来
实现,以简化、并规范循环结构程序设计。
在C语言中,可用以下语句实现循环:
( 1)用 for语句。
( 2)用 do-while语句。
( 3)用 while语句。
( 4)用 goto语句和 if语句构成循环。使用 goto语句实现求解 1~ 100累计和
的程序可以如下:
main()
{ int n=1,sum=0;
loop,sum += n; n++;
if (n<=100) goto loop;
printf(“sum=%d\n”,sum);
}
其中,loop:”为语句标号(格式:标号, 语句行),其命名遵循标识
符命名规则。 goto语句格式,goto 标号,功能为:使系统转向标号所在
的语句行执行。
注意,结构化程序设计方法,主张限制使用 goto语句。因为滥用
goto语句,将会导致程序结构无规律、可读性差。
另外,从功能上说,for语句可完全代替当型循环语句 while,所以
该语句也不是必需的。
[Return]
5.2 for语句和 while语句
在 3条循环语句中,for语句最为灵活,不仅可用于循
环次数已经确定的情况,也可用于循环次数虽不确定、
但给出了循环继续条件的情况。
[案例 5.1] 求 1~ 100的累计和。
/*案例代码文件名,AL5_1.C*/
/*程序功能:求 1~ 100的累计和 */
main()
{ int i,sum=0; /*将累加器 sum初始化为 0*/
for(i=1; i<=100; i++) sum += i; /*实现累加 */
printf("sum=%d\n",sum);
} [程序演示 ]
程序运行情况如下:
sum=5050
[案例 5.2] 求 n的阶乘 n!( n!=1*2*……*n )。
/*案例代码文件名,AL5_2.C*/
/*程序功能:求 n! */
main()
{ int i,n;
long fact=1; /*将累乘器 fact初始化为 1*/
printf(“Input n:,); scanf(“%d”,&n);
for(i=1; i<=n; i++) fact *= i; /*实现累乘 */
printf("%d ! = %ld\n",n,fact);
} [程序演示 ]
程序运行情况如下:
Input n,5↙
5 ! = 120
1,for语句的一般格式
for([变量赋初值 ]; [循环继续条件 ]; [循环变量增值 ])
{ 循环体语句组; }
2,for语句的执行过程
执行过程如图 5-1所示。
( 1)求解“变量赋初值”表达式。
( 2)求解“循环继续条件”表达式。如果其值非 0,执
行( 3);否则,转至( 4)。
( 3)执行循环体语句组,并求解“循环变量增值”表达
式,然后转向( 2)。
( 4)执行 for语句的下一条语句。
3.说明
( 1)“变量赋初值”、“循环继续条件”和“循环变量
增值”部分均可缺省,甚至全部缺省,但其间的分号不能省
略。
( 2)当循环体语句组仅由一条语句构成时,可以不
使用复合语句形式,如上例所示。
( 3)“循环变量赋初值”表达式,既可以是给循环
变量赋初值的赋值表达式,也可以是与此无关的其它表
达式(如逗号表达式)。
例如,for(sum=0;i<=100;i++) sum += i;
for(sum=0,i=1;i<=100;i++) sum += i;
( 4)“循环继续条件”部分是一个逻辑量,除一般
的关系(或逻辑)表达式外,也允许是数值(或字符)
表达式。
4,while语句
( 1)一般格式
while(循环继续条件 )
{ 循环体语句组; }
( 2)执行过程
执行过程如图 5-2所示。
1)求解“循环继续条件”表达式。如果其值为非 0,
转 2);否则转 3)。
2)执行循环体语句组,然后转 1)。
3)执行 while语句的下一条。
显然,while循环是 for循环的一种简化形式(缺省
“变量赋初值”和“循环变量增值”表达式)。
[案例 5.3] 用 while语句求 1~ 100的累计和。
/*案例代码文件名,AL5_3.C*/
/*程序功能:求 1~ 100的累计和 */
main()
{ int i=1,sum=0; /*初始化循环控制变量 i和累计器 sum*/
while( i<=100 )
{ sum += i; /*实现累加 */
i++; /*循环控制变量 i增 1*/
}
printf(“sum=%d\n”,sum);
} [程序演示 ]
程序运行情况如下:
sum=5050
5.循环嵌套
( 1)循环语句的循环体内,又包含另一个完整的循
环结构,称为循环的嵌套。循环嵌套的概念,对所有高
级语言都是一样的。
( 2) for语句和 while语句允许嵌套,do-while语句也
不例外。
[Return]
5.3 直到型循环 do-while语句
1.一般格式
do
{ 循环体语句组 ; }
while(循环继续条件 ); /*本行的分号不能缺省 */
当循环体语句组仅由一条语句构成时,可以不使用复合语句形式。
2.执行过程
执行过程如图 5-3所示。
( 1)执行循环体语句组。
( 2)计算“循环继续条件”表达式。如果“循环继续条件”表
达式的值为非 0(真),则转向( 1)继续执行;否则,转向( 3)。
( 3)执行 do-while的下一条语句。
do-while循环语句的特点是:先执行循环体语句组,然后再判断
循环条件。
[案例 5.4] 用 do-while语句求解 1~ 100的累计和。
/*案例代码文件名,AL5_4.C*/
/*程序功能:求 1~ 100的累计和 */
main()
{ int i=1,sum=0; /*定义并初始化循环控制变量,以及累计器 */
do
{ sum += i; /*累加 */
i++;
}
while(i<=100); /*循环继续条件,i<=100*/
printf(“sum=%d\n”,sum);
} [程序演示 ]
do-while语句比较适用于处理:不论条件是否成立,
先执行 1次循环体语句组的情况。除此之外,do-while语
句能实现的,for语句也能实现,而且更简洁。
[Return]
复习 几种循环
? for 语句格式,
for(初值表达式 ; 循环继续表达式 ; 循环变化表达式)
一条要反复执行的语句 ;
三个独立的表达式
for (i=1; i<=10; i++)
sum=sum+i;
循环 继续 表达式
for 语句
? for 语句格式,
for(初值表达式 ; 循环继续表达式 ; 循环变化表达式)
一条要反复执行的语句 ;
执行流程:
循环变量 初值 表达式
一条要反复执行的语句
循环变量 变化 表达式 下一条语句
不满足
i<=10
for 语句
执行流程:
i=1
sum=sum+i
i++ printf("%d",sum);
不满足
循环结构后面的语句
for (i=1; i<=10; i++)
sum=sum+i;
for 语句
? 从键盘输入 100个整数, 求其中正数的 平均数 。
#include <stdio.h>
main() {
int i,count=0,x ;
float sum=0;
for (i=0; i<100; i++)
{ scanf(“%d”,&x);
if (x>0) { sum=sum+x; count++; }
}
sum / = count ;
printf("%f",sum);
}
while 语句
? while (条件 )
重复执行的 一条 语句;
不满足
满足
重复执行的语句;
后一语句 ;
条件?
复合语句
while 语句
? while 实现要点
整个循环由 i 控制, i 称 循环变量
i=1; 循环变量必须有初值
while (i<=10) 继续循环的条件
{ sum=sum+i;
i++; 循环变量的改变
}
循环体
while 语句
? for 语句与 while 语句比较
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++; }
}
do-while 语句
? 用 do-while 语句实现
do-while 语句格式:
do 一条要反复执行的语句 ;
while ( 条件表达式 )
? while 是先判别条件, 再决定是否循环;
do-while 是先至少循环一次, 然后再根
据循环的结果决定是否继续循环 。
do-while 语句
? do-while 语句实现流程
要反复执行的语句
循环表达式
非 0=0
下一条语句
先循环
后判断
?重复步骤:
1 输入一个数
2 求和
?重复直到 0
do-while 语句
? do....while 与 while 的用法有所不同
例:输入一串正数求和,
直到数据为 0结束。
main( )
{ int x,sum=0;
do {
scanf(“%d”,&x);
sum+ = x ;
} while (x>0)
printf(“sum=%d”,sum);
}
例:输入一串正数求和,
直到数据为非正数结束。
main( )
{ int x,sum=0;
while (x>0) {
sum+ = x ;
scanf(“%d”,&x);
}
printf(“sum=%d”,sum);
}
s -x);
scanf(“%d”,&x);
? 编写数列求和程序,
1+ 1/2+1/3+1/4+….+1/n
main( )
{ int i,n; float y=0;
scanf(“%d”,&n);
for (i=1; i<=n; i++)
y+=1.0/ i ;
printf("n=%dy=%f\n",n,y);
}
1/1+1/2+1/3+1/4+….+1/n当精度达到, 第 n项 <=0.003 即可
main( )
{ int i=1 ;
float eps,y=0,t;
scanf("%f",&eps);
do {t=1.0/i;
y+=t ;
i++;
} while (t>=eps)
printf("n=%d y=%f\n",i-1,y);
}
ain( )
{ int i=1 ;
float eps,y=0,t=1;
scanf("%f",&eps);
while (t>=eps) {t=1.0/i;
y+=t ;
i++;
}
printf("n=%d y=%f\n",i-1,y);
}
循环结构的实现
循环实现要点,(1) 找出什么要反复执行
(2) 重复到何时结束
假定输入 x=12345,逆序输出 。 从低位开始分割
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 结束
12345 %10 = 5
如何 12345 ---> 4?
(1) 12345%100/10
(2) 12345/10%10
(1)反复执行 x%10
x=x/10
(2)何时结束 x= =0
scanf(,%d”,&x) ;
while ( x>0 )
{ printf(,%d,,x%10) ;
x=x/10 ;
}
循环结构的实现
循环实现要点,(1) 找出什么要反复执行
(2) 重复到何时结束
假定输入 x=12345 顺序输出, 从高位开始分割
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/i>0 ; i=i*10)
d++ ;
(2) 每次循环缩小 10倍
(3) 缩小到 0 结束
§ 6.2 break 和 continue 语句
例:读入一行字符 ( 不超过 10个 ), 给予输出
#include "stdio.h"
main()
{ char c;
int i=0;
for (i=0;i<10;i++) /* i>=10 是结束条件 */
{ c=getchar();
putchar(c);
}
}
if (c=='\n') break;
/* c==回车 也是结束条件 */
有两个条件决定循环的结束
main()
{ char c;
int i=0;
for (i=0; i<10 && c! ='\n'; i++)
{ putchar(c); 两个结束条件合并
c=getchar();
}
}
c=getchar();
真 ( 非 0)
break 流程
for的下一条语句
假 ( 0)
表达式 1
表达式 2
语 句 1
表达式 3
否 break
语 句 2




程序:
for (表 1;表 2;表 3)
{ 语句 1 ;
if (,.,) break ;
语句 2 ;
}
for后的下一条语句;

真 ( 非 0)
continue 流程
for的下一条语句
假 ( 0)
表达式 1
表达式 2
语 句 1
表达式 3
否continue
语 句 2



程序:
for (表 1;表 2;表 3)
{ 语句 1 ;
if (,.,) continue;
语句 2 ;
}
for后的下一条语句;
continue 语句例子
#include "stdio.h"
main()
{ char c;
int i;
for (i=0;i<10;i++) /* i>=10 是结束条件 */
{ c=getchar();
if (c=='\n') continue;
putchar(c); /* c=回车 也是结束条件 */
}
} 问,若把 break 改成 continue,
结果会怎样?
输入,abc ↙
efgh ↙
123 ↙
输出,abcefgh1
§ 6.3 for 语句的变化形式
原形,int i,sum=0;
for (i=1; i<=10; i++) sum=sum+i;
i<=10
sum=0;
i=1;
sum=sum+i
i++
下一条语句
变形 1 int i=1,sum=0;
for ( ;i<=10; i++) sum= sum+i;
变形 2 int i=1,sum=0;
for ( ; i<=10 ; )
{ sum = sum+i; i++; }
相当于,while
§ 6.3 for 语句的变化形式
原形,int i,sum=0;
for (i=1; i<=10; i++) sum=sum+i;
i<=10
sum=0;
i=1;
sum=sum+i
i++
下一条语句
变形 3 int i=1,sum=0;
for( ; ; ){
无限循环 sum=sum+i ; i++ }
变形 4 int i,sum;
for(i=1,sum=0;i<=10;sum+=i,i++);
无循环体语句
if (i>10) break;
§ 6.3 for 语句的变化形式
原形,int i,sum=0;
for (i=1; i<=10; i++) sum=sum+i;
变形1 int i=1,sum=0;
for ( ; i<=10; i++) sum=sum+i ;
变形2 int i=1,sum=0;
for ( ; i<=10 ; ) { sum=sum+i; i++; }
变形3 int i=1,sum=0;
for ( ; ; ) { if (i>10) break;
无限循环 sum=sum+i ; i++ }
变形4 int i,sum;
for (i=1,sum=0 ; i<=10; sum+=i,i++) ;
不管那一种变形,循环变量的初值、判断和变化
表达式仍都存在,只是改变了所处的位置。
不管那一种变形,三个表达式的 功能 缺一不
可,且执行流程不得改变。
原形,int i,sum=0;
for (i=1; i<=10; i++) sum=sum+i;
i<=10
i=1;
sum=0;
sum=sum+i
i++
下一条语句
变形 3 int i=1,sum=0;
for( ; ; ){ if (i>10) break;
sum=sum+i ; i++ }
变形 4 int i,sum;
for(i=1,sum=0;i<=10;sum+=i,i++);
无循环体语句
§ 6.4循环嵌套
循环体中又包含了循环语句称循环嵌套。
例:求 S = 1! +2! +3! + …… + n!
分析,首先要循环 n次来累加 i!
for (i=1; i<=n; i++)
s = s + i! ;
如果存在求阶乘的运算 !,计算完成。
嵌套
for (i=1; i<=n; i++)
{ t = i! ;
s = s + t ;
}
for (t=1,j=1 ; j<=i; j++)
t = t * j ;t = t * i ;
§ 6.4循环嵌套
例:已知小鸡 0.5文钱/只,公鸡2文钱/只,
母鸡3文钱/只,现要求 100文钱正好买 100只鸡,
请给出所有的组合。
组合问题用计算机解,通常采取“凑”的办法
母鸡可能的只数,0——100
公鸡可能的只数,0——100
小鸡可能的只数,0——100
然后对三种鸡所 有的 组合方式,排除不等于
100元和 100只的那些组合。
hen
cock
chick
§ 6.4循环嵌套
main()
{
int chick,cock,hen;
for (cock=0; cock<=100; cock++)
for (hen=0; hen<=100; hen++)
for (chick=0; chick<=100; chick++)
if (cock+hen+chick= =100 &&
cock*2+hen*3+chick*0.5 = = 100)
printf("cock=%d hen=%d
chick=%d\n",cock,hen,chick);
}
cock=0
hen=0
chick=0
?100
? 1100
? 1100
§ 6.4循环嵌套
运行结果:
cock=0 hen=20 chick=80
cock=5 hen=17 chick=78
cock=10 hen=14 chick=76
cock=15 hen=11 chick=74
cock=20 hen=8 chick=72
cock=25 hen=5 chick=70
cock=30 hen=2 chick=68
§ 6.4循环嵌套
运行过程:
cock=0
hen=0 chick=0~100 共 101次
hen=1 chick=0~100 共 101次……
hen=100 chick=0~100 共 101次
cock=1
hen=0 chick=0~100 共 101次
……hen=100 chick=0~100 共 101次
……cock=100
hen=0 chick=0~100 共 101次……
hen=100 chick=0~100 共 101次
101

101

101

100



§ 6.4循环嵌套
main()
{
int chick,cock,hen;
for (cock=0; cock<=50; cock++)
for (hen=0; hen<=33; hen++)
{ chick = 100 - cock - hen ;
if (cock*2+hen*3+chick*0.5 = = 100)
printf("cock=%d hen=%d
chick=%d\n",cock,hen,chick);
}
}
§ 6.4循环嵌套
循环嵌套均是大循环包小循环
绝对不允许循环体交叉 !
for ( )
{,........
do {
..........
}
} while(....)
for ( )
{,.......,
do {
.........,
} while(....)
}
§ 6.4循环嵌套
main()
{
int chick,cock,hen ;
for (cock=0; cock<=50; cock++)
{ for (hen=0; hen<=33; hen++)
{ chick = 100 - cock - hen ;
if (cock*2+hen*3+chick*0.5 = = 100)
break;
}
printf(.........) ;
}
}
§ 6.4循环嵌套
main()
{
int chick,cock,hen,flag=0 ;
for (cock=0; cock<=50; cock++)
{ for (hen=0; hen<=33; hen++)
{ chick = 100 - cock - hen ;
if (cock*2+hen*3+chick*0.5 = = 100)
{ flag =1; break; }
}
if (flag) break ;
printf(.........) ;
}
}
“接力赛”第一棒
“接力赛”第二棒
结论,break只能终止内层循环
习题 5.1
? 方法一
? main()
? {
? int sum,i;
? sum=0;
? for (i=1;i<=100;i++)
? if(i%2==0) sum=sum+i;
? printf("1~100之间偶数之和为,%d\n",sum);
? }
?
? 方法二,
?,.....
? for (i=2;i<=100;i+=2) sum+=i;
?,.....
习题 5.2
? 方法一
? main()
? {
? long multi;
? int i;
? multi=1;
? for (i=1;i<=20;i++)
? if (i%3==0) multi=multi*i;
? printf("1~20之间所有 3的倍数之积为,%ld\n",milti);
? }
? 方法二:
?,.....
? for(i=3;i<=20;i+=3) milti*=i;
?,....,
? 习题 5.3(方法一 )
? main()
? {
? long s=0,t=1;
? int n ;
? for (n=1;n<=10;n++)
? {
? t=t*n;
? s=s+t;}
? printf("ok=%ld\n",s);
? }
? 习题 5.3(方法二 )
? main()
? {
? long s=0;
? int t,n,i;
? for (i=1;i<=10;i++)
? {t=1;
? for (n=1;n<=i;n++) t=t*n;
? s=s+t;
? }
? printf("ok=%d\n",s);
? }
习题 5.4
main()
{
int a,n,i=1;
long sn=0,tn=0;
printf("请输入一个数字和此数字的个数,");
scanf("%d,%d",&a,&n);
for(;i<=n;i++)
{
tn=tn*10+a;
sn+=tn;
}
printf("d+dd+ddd+....+dd...d=%ld\n",sn);
}
例题
求算式
直到第 40项的和
main()
{ int i,s=1;
float y=0;
for (i=1; i<=40; i++)
{ y=y+s/((float)i*( i+1)) ;
s=-s ;
}
printf(,%f”,y);
}
??????? 421301201121611
第 i 项, 1/(i*(i+1))
符号,s = 1
s = -1
例题
求算式
直到第 40项的和
main()
{ int i,s=-1;
float y=1;
for (i=2; i<=40; i++)
{ y=y+s/((float)i*( i+1)) ;
s=-s ;
}
printf(,%f”,y);
}
??????? 421301201121611
第 i 项, 1/(i*(i+1))
符号,s = 1
s = -1
例题
编程, 输出下列形式的九九乘法表 。
(1) (2) (3) (4) (5) (6) (7) (8) (9)
(1) 1 2 3 4 5 6 7 8 9
(2) 2 4 6 8 10 12 14 16 18
(3) 3 6 9 12 15 18 21 24 27
(4) 4 8 12 16 20 24 28 32 36
(5) 5 10 15 20 25 30 35 40 45
(6) 6 12 18 24 30 36 42 48 54
(7) 7 14 21 28 35 42 49 56 63
(8) 8 16 24 32 40 48 56 64 72
(9) 9 18 27 36 45 54 63 72 81
#include <stdio.h>
main()
{ int i,j;
printf(" "); 第 1行先输出 5个空格
for(i=1;i<10;i++) printf("(%d) ",i);
putchar('\n');
for(i=1;i<10;i++) { i代表行
printf("(%d) ",i);
for(j=1;j<10;j++) j代表列
printf(" %2d",i*j);
putchar('\n');
}
}
例题
下列程序求 Sn=a+aa+aaa+……+aa…aa(n个 a)的值,
sn=2+22+222+2222+22222,其值应为 24690。
#include <stdio.h>
main()
{
int a,n,count=1,sn=0,tn=0;
scanf(“%d%d”,&a,&n);
for (count=1; count <=n ;count++){
tn=tn*10+a;
sn=sn+tn;
}
printf(“the sn is,%d \n”,sn);
}
tn=0*10+2 =2
tn=2*10+2=22
tn=22*10+2=222
程序举例
? 例 1,输入一行字符,统计其中的单词数,单词之间
用空格分隔开。
? 例如:输入 you are a student,则有 4个单词。
解题思路:
( 1)用空格区分每一个单词;
( 2)遇到空格,则表示前一个单词结束; (word=0)
( 3) 遇到一个非空格:若前面一个字符是空格 (即
word=0), 则开始一个新单词 (word=1,计数加 1);
若前面一个字符是非空格 (即 word=1),则仍然是同
一个单词 。
#include <stdio.h>
main()
{
char string[81];
int i,num=0,word=0;
gets(string);
for (i = 0; string[i]!=?\0?;i++)
if (string[i]==? ?) word = 0;
else if (word == 0) {
word++; num++;
}
printf(“There are %d words in the line.\n”,num);
}
程序举例
? 例 2.打印以下图案,
? **********
? **********
? **********
? **********
? **********
程序举例
? 例 3.打印以下图案,
? $
? $ $ $
? $ $ $ $ $
? $ $ $ $ $ $ $
? $ $ $ $ $
? $ $ $
? $
分析:分上下两部分考虑
? 对上半部每一行,$数 +空格数 =列数 (n)
行数 $数 空格数 (单边 )
? $ 1 1 (n-1)/2
? $ $ $ 2 2*2-1=3 (n-3)/2
? $ $ $ $ $ 3 2*3-1=5 (n-5)/2
? $ $ $ $ $ $ $ 4 2*4-1=7 (n-7)/2
? 一般地, i 2*i-1 (n-(2*i-1))/2
?
?
分析:
? 对下半部每一行,$数 +空格数 =列数 (n)
行数 空格数 (单边 ) $数
? $ 1 1 n-1*2
? $ $ $ 2 2 n-2*2
? $ $ $ $ $ 3 3 n-3*2
? $ $ $ $ $ $ $ i i n-i*2
? $ $ $ $ $
? $ $ $
? $
?
? #include <stdio.h>
? main()
? {
int n_blank,n_dollar,i,j,n,m;
scanf(“%d”,&n);
m=(n+1)/2;
for (i = 1; i <= m; i++) {
n_dollar = 2 * i – 1;
n_blank = (n – n_dollar)/2;
for (j = 0; j < n_blank; j++)
putchar(? ?);
for (j = 0; j < n_dollar; j++)
putchar(?$?);
putchar(?\n?);
}
? for (i = 1; i < m; i++) {
n_blank = i;
n_dollar = n – 2 * n_blank;
for (j = 0; j < n_blank; j++)
putchar(? ?);
for (j = 0; j < n_dollar; j++)
putchar(?$?);
putchar(?\n?);
}
return 0;
}
5.5 应用举例
[例 4] 求 Fibonacci数列的前 40个数。该数列的生成方法为,F1=1,
F2=1,Fn=Fn-1+Fn-2( n>=3),即从第 3个数开始,每个数等于前 2个数之
和。
算法设计,请参见第 2章第 1节( 2.1)。参考源程序如下:
/*案例代码文件名,AL5_5.C*/
main()
{ long int f1=1,f2=1; /*定义并初始化数列的头 2个数 */
int i=1; /*定义并初始化循环控制变量 i*/
for( ; i<=20; i++ ) /*1组 2个,20组 40个数 */
{ printf(“%15ld%15ld”,f1,f2); /*输出当前的 2个数 */
if(i%2==0) printf(“\n”); /*输出 2次( 4个数),换行 */
f1 += f2; f2 += f1; /*计算下 2个数 */
}
} [程序演示 ]
[例 5 输出 10~ 100之间的全部素数。所谓素数 n是指,
除 1和 n之外,不能被 2~( n-1)之间的任何整数整除。
算法设计要点:
( 1)显然,只要设计出判断某数 n是否是素数的算
法,外面再套一个 for循环即可。
( 2)判断某数 n是否是素数的算法:根据素数的定
义,用 2~( n-1)之间的每一个数去整除 n,如果都不能
被整除,则表示该数是一个素数。
判断一个数是否能被另一个数整除,可通过判断它
们整除的余数是否为 0来实现。
参考源程序如下:
main()
{ int i=11,j,counter=0;
for( ; i<=100; i+=2) /*外循环:为内循环提供一个整数 i*/
{ for(j=2; j<=i-1; j++) /*内循环:判断整数 i是否是素数 */
if(i%j= =0) /*i不是素数 */
break; /*强行结束内循环,执行下面的 if语句 */
if(counter%10= =0) /*每输出 10个数换一行 */
printf(“\n”);
if( j >= i ) /*整数 i是素数:输出,计数器加 1*/
{ printf(“%6d”,i);
counter++;
}
}
} [程序演示 ]
思考题,外循环控制变量 i的初值从 11开始、增量为 2
的作法有什么好处?为提高运行速度,如何优化内循环?
(提示:从减少计算次数角度来考虑)
[Return]
良好的源程序书写习惯 ──注释(续)
( 3)循环结构
在 C语言中,循环结构由循环语句 for,while和
do...while来实现。
作为注释,应在它们的前面说明其功能,在循环条
件判断语句行的后面,说明循环继续条件的含义,如下
所示。
1) for语句
/*功能 */
for(变量初始化 ;循环条件 ;变量增值 ) /*循环继续条件
的含义 */
{ …… }
2) while语句
/*功能说明 */
while(循环条件 ) /*循环继续条件的含义 */
{ …… }
3) do...while语句
/*功能说明 */
do { …… }
while(循环条件 ); /*循环继续条件的含义 */
如果循环嵌套,还应说明每层循环各控制什么。
[Return]
? 习题 5.5
? main()
? {
? int i,j,k,n;
? printf("水仙花数有,");
? for(n=100;n<1000;n++)
? {
? i=n/100;
? j=n/10-i*10;
? k=n%10;
? if(n==i*i*i+j*j*j+k*k*) printf("%5d",n);
? }
? printf("\n");
? }
? 5.6方法一
?main()
{
int i,t,n=10;
float a=2,b=1,s=0;
for(i=1;i<=n;i++)
{
s=s+a/b;
t=a;
a=a+b;
b=t;
}
printf("数列的前 10项之和为,%9.6f\n",s);
}
? 5.6方法二
? main()
? {
? int i,n=5;
? float a=2,b=1,s=0;
? for(i=1;i<=n;i++)
? {
? s=s+a/b;
? b=a+b;
? s=s+b/a;
? a=b+a;
? }
? printf("数列的前 10项之和为,%9.6f\n",s);
? }
? 5.7
? main()
? {
? int num,count=-1,sum=0,max=0,min=0;
? float aver;
? printf("请输入任意多个正整数,一数值 0作为结束标志,\n");
? do
? {
? scanf("%d",&num);
? count++;
? sum+=num;
? max=(max>num)?max:num;
? min=(min<num)?min:num;
? }
? while(num!=0);
? aver(float)sum/count;
? printf("共输入了 %d个数据 \n",count);
? printf("累计和为,%d,平均值为,%.4f\n",sum.aver);
? printf("最大值为,%d,最小值为,%d\n",max,min);
? }
? 5.8题
? main()
? {
? int i=1,j=1;
? float pai=0;
? while(pai<3.135||3.145<=pai)
? {
? pai=pai+j*4.0/i;
? j=j*(-1);
? i+=2;
? }
? printf("要计算 %d项才能得到 3.14\n",i/2);
? }