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