You are on page 1of 18

第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 ~ 1
00 的累计和。
根据已有的知识,单独实现每一步都不难。但是,由于需要经
常使用这种重复计算结构(称为循环结构), 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 语句。因为滥用 go


to 语句,将会导致程序结构无规律、可读性差。
另外,从功能上说, 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]
5.4 break 语句与 continue 语句
为了使循环控制更加灵活,C语言提供了 break 语句和 continue 语句。
1 .一般格式: break ;
continue ;
2 .功能
( 1 ) break :强行结束循环,转向执行循环语句的下一条语句。
( 2 ) continue :对于 for 循环,跳过循环体其余语句,转向循环变
量增量表达式的计算;对于 while 和 do-while 循环,跳过循环体其余语
句,但转向循环继续条件的判定。
3 . break 和 continue 语句对循环控制的影响如图 5-4 所示。
4 .说明
( 1 ) break 能用于循环语句和 switch 语句中, continue 只能用于循
环语句中。
( 2 )循环嵌套时, break 和 continue 只影响包含它们的最内层循环,
与外层循环无关。
[Return]
5.5 应用举例
[ 例 5.5] 求 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.6] 输出 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 和 d
o...while 来实现。
作为注释,应在它们的前面说明其功能,在循环条
件判断语句行的后面,说明循环继续条件的含义,如下
所示。
1 ) for 语句
/* 功能 */
for( 变量初始化 ; 循环条件 ; 变量增值 ) /* 循环继续
条件的含义 */
{ …… }
2 ) while 语句
/* 功能说明 */
while( 循环条件 ) /* 循环继续条件的含义 */
{ …… }
3 ) do...while 语句
/* 功能说明 */
do { …… }
while( 循环条件 ) ; /* 循环继续条件的含义 */
如果循环嵌套,还应说明每层循环各控制什么。

[Return]

You might also like