分享
 
 
 

实例讲解 C 语言的循环结构

王朝c/c++·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

这一讲开始之前,我们需要准备一个函数。这个函数的作用就是把一个百分制成绩转换成等级制。转换的过程我已经在讲解分支结构的时候详细阐述了,现在仅提供函数如下:

/* 准备 grade.h */

char grade(int score) {

switch (score / 10) {

case 10: case 9:

return 'A';

case 8:

return 'B';

case 7:

return 'C';

case 6:

return 'D';

case 5: case 4: case 3:

case 2: case 1: case 0:

return 'E';

default:

return 0;

}

}

在讲解分支结构时提出的实例都只能解决一个成绩的情况。假如需要将 5 个人的成绩进行转换,最简单的办法如下:

/* 例1 */

#include "grade.h"

#include

void main() {

int n;

printf("请输入成绩: ");

scanf("%d", &n);

printf("等级为: %c", grade(n));

printf("请输入成绩: ");

scanf("%d", &n);

printf("等级为: %c", grade(n));

printf("请输入成绩: ");

scanf("%d", &n);

printf("等级为: %c", grade(n));

printf("请输入成绩: ");

scanf("%d", &n);

printf("等级为: %c", grade(n));

printf("请输入成绩: ");

scanf("%d", &n);

printf("等级为: %c", grade(n));

}

例1 的结构非常简单易懂,但是书写起来只有一个感觉--烦!同样的三句话,居然重复了 5 次。如果这个班的人数不止 5 人,而是数十人的话,……天啊!简直想都不敢想!

C 语言当然不会笨得来一点方便都不给,这个"方便",就是循环结构。循环结构的目的就是减少重复代码,减轻程序员的负担。而其形式,在 C 语言中有三种:for 循环、while 循环和 do-while 循环。正面分别介绍如下:

for 循环的基本格式是 for (语句1; 逻辑表达式1; 语句2) {语句组1},大括号包括其中的语句组1 也可以是一条语句。其执行过程如下:先执行语句1,然后判断逻辑表达式1。如果逻辑表达式1 的值为"真(非0)",则执行语句组1,否则结束循环。在没结束循环的情况下,执行了语句组1 之后,执行语句2。然后再对逻辑表达式1 进行判断,再……,如此循环直到逻辑表达式1 为"假(0)"时为止。于是,例1 可以改写如下:

/* 例2 */

#include "grade.h"

#include

void main() {

int n, i;

for (i = 0; i < 5; i++) {

printf("请输入成绩: ");

scanf("%d", &n);

printf("等级为: %c", grade(n));

}

}

嘿,这么简洁?!知道循环结构的便利之处了吧。例2 中 i 从 0 到 4,共执行了 5 次循环体。当然,也可以跟据个人的习惯,将例2 中的 for 语句改写为:

for (i = 1; i <= 5; i++) {...}

这样或许更容易理解,但我不推荐这样做,因为 C 语言中的数组下标是以 0 开始的,采用例1 中的 for 语句更容易在循环体中读写数组元素。就上例,如果我们要把所有成绩输入完成之后再逐一将其等级打印出来,就需要用到数组:

/* 例3 */

#include "grade.h"

#include

#define N 5

void main() {

int n[N], i;

for (i = 0; i < N; i++) {

printf("请输入成绩: ");

scanf("%d", &n[i]);

}

for (i = 0; i < N; i++) {

printf("第 %d 个成绩的等级为: %c", i, grade(n[i]));

}

}

例3 中,如果 i 从 1 到 N 循环的话,读写数组元素时就应该使用 n[i - 1] 而不是 n[i]。那么每执行一次循环体就会多一次减法运算,在一个循环 N 次的循环中,就会多进行 N 次减法运算,大大降低了程序效率。

C 语言是一种灵活的语言。它的 for 循环也不是一成不变,必须按照它的基本格式书写。暂时卖个关子,先看看从例3 修改过来的例4:

/* 例4 */

#include "grade.h"

#include

#define N 5

void main() {

int n[N], i = 0;

for (; i < N; ) {

printf("请输入成绩: ");

scanf("%d", &n[i++]);

}

for (i = 0; ; i++) {

if (i == N) {

break;

}

printf("第 %d 个成绩的等级为: %c", i, grade(n[i]));

}

}

是不是很奇怪,例4 中的两个 for 循环中与上面两个例子的 for 循环相比,都少用了一些语句,怎么回事?且听我慢慢道来:

第一个 for 循环中,少了 i = 0 和 i++ 两句。其实仔细一看,这两句也没少。i = 0 已经在给 i 赋初值的时候就实现了,而 i++ 是在 scnaf 语句中顺便实现的。所以,虽然没有 i = 0 一句,但循环开始之前 i 的值已经是 0 了;虽然没有 i++ 一句,但循环体中实际也改变了 i 的值。

第二个 for 循环中少的只是那一句判断。而正是由于少了这一句判断,for 循环便不能自已结束。如果我在循环体中也不采取措施结束循环的话,这个循环将一直不停的执行下去,形成死循环。于是,我在循环体中对 i 进行判断,当它等于 N的时候执行一个 break 语句,跳出循环,填补了 for 语句中没有逻辑表达式的缺陷。

甚至,一个 for 语句就可以写成 for (; ; ) {...},这样一个 for 语句,简单的说,就是一个死循环。

还有一点需要说明,就是 break 语句。这个语句在讲解 switch 分支结构的时候就已经见到过了。它除了能用于 switch 分枝结构之外,还能用于所有的三种循环结构。其作用就是两个字--"跳出"。switch 分枝结构中,它用于跳出整个 switch 语句;而在循环结构中,它自然是用于跳出循环,执行它之后,循环体中所有其它语句都不会再执行,整个循环就此中断。

学会了 for 循环,虽然可以简化不少代码,但它似乎只能解决循环次数固定的情况。如果人数不固定,又该怎么办?比如规定如下:输入若干 0 至 100 的成绩,如果成绩不在此范围,则表式结束。请看例5,例6:

/* 例5 */

#include "grade.h"

#include

void main() {

int n;

printf("请输入成绩: ");

scanf("%d", &n);

while (grade(n) != 0) {

printf("等级为: %c", grade(n));

printf("请输入成绩: ");

scanf("%d", &n);

}

}

/* 例6 */

#include "grade.h"

#include

void main() {

int n;

do {

printf("请输入成绩: ");

scanf("%d", &n);

if (grade(n) != 0) {

printf("等级为: %c", grade(n));

}

} while (grade(n) != 0);

}

例5 和例6 分别使用了 while 循环和 do-while 循环结构。两种循环结构都是在 while 后的逻辑表达式为真时执行循环体,为假时结束循环。二者的不同在于:while 循环是先判断,再执行循环体;而 do-while 循环而是先执行循环体后再作判断。因此,使用 do-while 循环至少要执行一次循环体。至于循环的执行过程,就请读者自己分析了。

例6 中对于同一个 n,至少要执行两次 grade(n),大大降低了程序的效率。虽然可以用一个 char 型变量来解决这个问题,但我不想这样作。于是又有如下方式的改写:

/* 例7 */

#include "grade.h"

#include

void main() {

int n;

do {

printf("请输入成绩: ");

scanf("%d", &n);

if (grade(n) == 0) {

break;

}

printf("等级为: %c", grade(n));

} while (1);

}

例7 中 while 语句的逻辑表达示值始终是真(1),所以这个循环也就是一个死循环,必须在循环体中用 break 语句跳出。用一个 if 语句判断跳出的时机,这也是很好理解的,就不多说了。但是看看下面的例8,可能就不是那么明白了。

/* 例8 */

void main() {

int n;

do {

printf("请输入成绩: ");

scanf("%d", &n);

if (grade(n) == 0) {

continue;

}

printf("等级为: %c", grade(n));

} while (grade(n) != 0);

}

例8 的和例6 的区别主要就在于一个 continue 语句。这个语句可是循环结构所特有的,其作用与 break 语句相比,即有相似之处,也有相对之处。执行了 continue 语句之后,循环体中 continue 以下的语句将不再在这次循环中执行,但循环并不中断,而是开始下一次循环。

如例8 中,满足 grade(n) == 0 的条件后,执行 continue 语句。然后 printf 语句被跳过,直接到 while 语句判断是否结束循环,如果不满足结束循环的条件,那么将会要求输入下一个成绩。不过例8 中,只要能执行到 continue 语句,while 后的条件就一定为假,循环结束。例8 和例7 的区别就在于,例8 是正常结束,而例7 是被中断。

break 和 continue 两个语句在 C 语言的循环结构中有着举足轻重的作用。虽然使用巧妙的结构化程序手段可以避免使用这两个语句,但这两个语句的确能使程序结构更加简单明了。所以,只要能用上它们的地方,我极力推荐使用它们。

三种循环结构都说完了,但我还要强调 C 语言的灵活性。虽然循环结构有三种形式,但只使用其中仍意一种都能达到目的。例5 和例6 就展示了使用 while 和 do-while 两种形式完成同要的任务。至于 for 循环,前面说它"似乎只能解决循环次数固定的情况",这"似乎"二字并非笔误。它乍看只能解决循环次数固定的情况,但仔细一想,它也的确能解决循环次数不固定的情况。如例5 例6 用 for 循环的形式分别可以改写为:

/* 例9 */

#include "grade.h"

#include

void main() {

int n;

printf("请输入成绩: ");

scanf("%d", &n);

for (; grade(n) != 0; ) {

printf("等级为: %c", grade(n));

printf("请输入成绩: ");

scanf("%d", &n);

}

}

/* 例10 */

#include "grade.h"

#include

void main() {

int n;

int b = 1;

for (; b; ) {

printf("请输入成绩: ");

scanf("%d", &n);

if (grade(n) != 0) {

printf("等级为: %c", grade(n));

} else {

b = 0;

}

}

}

看看例9 和例5,例10 和例6,是不是有异曲同工之妙?其实 C 语言的循环结构远远不止这些变形,只要你细心思考,一定还会发现更多"变形妙用"。哈哈哈哈,一吐为快,心中舒服多了。

-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-

/ __________/LB\___ OUTINN

/ _[]_ /____\ /_________/| () |\__\ http://outinn.yeah.net/

| ____ /-| __ |-\| Welcome to visit OUTINN!

|__|==|___| || |__|

-=--=--=- |_||_| =- Fancy, outinn@china.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有