我们已经有了最基本的程序的编写能力,即根据我们的思路一行一行的编写或者进行一些条件判断,这当然没有问题,我们已经能够运用他们解决许多问题,但是仍有一些问题无法处理,需要学习第三种流程控制—循环.

什么是循环执行

为了讲解循环,我们引入一个问题:我要计算从1+2+3+4+...+100的值为了说明问题,我们要求不允许使用简便方法(即高斯的做法),而仅仅只能一个个的累加起来,并编写一个程序,当然,我们可以一行一行的慢慢编写相加,这样可以,代码大概是类似这样子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>

int main() {
int sum = 0;

sum = sum + 1; // 这里的=是赋值,并不是数学意义上的=,也就是说是要把右面的值赋值给左面,
// sum一开始是0,这里先把sum在赋值前的值0加上1,把运算结果1重新赋值给sum,最后sum变成1
sum = sum + 2;
sum = sum + 3;
sum = sum + 4;
sum = sum + 5;
sum = sum + 6;
//...以此类推
sum = sum + 99;
sum = sum + 100;

printf("%d", sum);

return 0;
}

这个程序没有问题,但是可以看出来,代码量很大,从1加到100的运算就需要100行,笔者甚至都做了省略.

但是我们可以发现,每一步操作都是相似的—我们让sum加上一个特定的值,并且这个值是递增的.

那么,我们就有机会对其进行简化—既然每次增加的值都是递增的,而且所有的操作都是加法,我们可不可以写一个变量i,让他从1循环到100,然后让sum=sum+i;依次执行100次来达到相同的结果呢?

当然是可以的,循环控制就是为了解决这种类似的问题.

C语言有3种循环语句的实现,分别是while,do…while,for循环.下面依次进行讲解.

while循环语句

while循环语句是最简单的一种循环语句,他只有一个条件判断进行控制:

1
2
3
4
while(表达式){
//循环体
}
//后续其他语句

while循环就这么简单,其中,表达式是任何合法的表达式,但是从逻辑上,他应该是逻辑表达式(包含逻辑运算符的表达式),实际上,这个表达式应该叫做循环条件,后面我们也将其称为循环条件

下面来解释while循环的执行过程:

1.对表达式进行求值,并判断其是否为,如果是那么就继续第2步;否则跳转到第4步

2.依次执行循环体中的语句,也就是花括号括起来的这个复合语句

3.执行完毕后,跳转到第1步

4.忽略/结束该循环,继续向下执行后续其他语句

画成流程图是这样的:

image-20230924190520596

总结就是,每次循环开始前都要对指定的表达式进行一个求值判断,如果为则进入循环,执行完毕后再次进行判断,直到某一次判断的结果为才跳出循环.

那么这就意味着,循环的执行过程中必须能保证达到某个程度时表达式求值为假或直接跳出循环.

一般情况下,我们使用一个变量进行循环控制,例如每次这个变量自增1,直到该变量超出一个范围,则跳出循环.

综上,我们尝试编写计算从1+2+3+4+...+100的值:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main() {
int i = 1, sum = 0; // i就是那个用于循环控制的变量,同时,其值也可以加以利用
while (i <= 100) { // i小于等于100时一直进行,直到i增加到101则退出循环
sum = sum + i;
i = i + 1; // 循环变量进行自增
}
printf("%d", sum);
return 0;
}
image-20230924191251084

显然,代码的关键部分就是i<=100i=i+1这两个,同时,i必须在进入循环前就初始化,因为第一次循环就要进行判断.

do…while循环语句

do…while()语句和while语句只有一个唯一的一个区别,那就是:第一次循环是无条件执行的

换句话说,无论如何,do...while()语句控制的循环体至少会执行一次,而while()语句控制的循环体可能一次都不会执行—如果第一次条件判断就为假的话.

1
2
3
do{
//循环体
}while(循环条件); // 注意最后的;一定不能省略!

如前所述,循环条件就是一个表达式.

do…while()语句的执行过程和while基本完全一样,唯一的区别就是在第一次循环不会进行条件判断:

image-20230924200151214

除了第一次循环,往后的每一次循环前都要进行一次判断.

我们利用do…while()进行改写求和程序:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main() {

int i = 1, sum = 0;
do {
sum = sum + i;
i = i + 1;
} while (i <= 100);
printf("%d", sum);
return 0;
}

读者可以自行运行一下,或尝试自行编写一遍.

for循环语句

for()语句是C语言中最难,也最强大的循环语句,所有的while()语句,do...while()语句都可以轻易地修改为for语句,反过来,for()循环语句并不一定能轻易地修改为其他两种语句的写法.

1
2
3
for(表达式1;表达式2;表达式3){
//循环体
}

for()语句的执行顺序如下:

1.对表达式1求值,一般是循环变量的声明和初始化

2.对表达式2进行判断,一般是对循环变量的值进行判断,也就是说表达式2相当于while()中的循环条件,如果是那么就继续第3步;否则跳转到第5步

3.正常执行循环体

4.对表达式3进行求值,一般是循环变量的自增或自减,然后跳转到第2步

5.忽略/结束该循环,继续向下执行后续其他语句

流程图如下:

image-20230924201703987

实际上,表达式1会在第一次循环开始前(可能一次都不会执行)执行且仅执行一次,无论循环是否执行.

然后,接下来就是正常的条件判断,进而选择是否执行循环体.

当一次循环结束后,表达式3会被执行一次,然后才进行下一次条件判断.

如此反复,直到循环终止.

此外,这3个表达式都是可以省略的,甚至可以全部省略,但是两个;绝对不能省略,否则报错.

利用这个特性,还有while(1)等写法,我们可以写出死循环(并不是真的死循环,还是有终止条件的),但是关于这里的知识,我们会在跳转执行部分进行讲解.

同样,我们修改程序:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main() {

int sum = 0;
for (int i = 1; i <= 100; i = i + 1) {
sum = sum + i;
}
printf("%d", sum);
return 0;
}

到此,基本的讲解结束,另外,关于本章的求和程序还有一些其他写法,帮助各位深刻理解3种循环语句.

1到100求和的其他写法

第一个

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main() {

int sum = 0;
for (int i = 1; i <= 100;) {
sum = sum + i;
i = i + 1;
}
printf("%d", sum);
return 0;
}

第二个

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main() {

int sum = 0, i = 1;
for (; i <= 100;) {
sum = sum + i;
i = i + 1;
}
printf("%d", sum);
return 0;
}

第三个

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main() {

int sum = 0, i;
i = 0;
while (( i = i + 1 ) <= 100) {
sum = sum + i;
}
printf("%d", sum);
return 0;
}

---WAHAHA,2023.9.24



上一篇:c语言教程-6-选择执行

下一篇:c语言教程-8-跳转控制和嵌套