作者:解学武
一文搞懂C语言循环结构(for、while和do while)
如果你正在学习循环结构,这篇文章一定要看完,将教会你 C 语言里的所有循环结构,一共有 3 种,分别是 while 循环、do while 循环和 for 循环。
C语言中常用的编程结构有三种(其它编程语言也是如此),它们分别是:
我们通常将“表达式”称为循环条件,把“语句块”称为循环体,整个循环的过程就是不停判断循环条件、并执行循环体代码的过程。
用 while 循环计算 1 加到 100 的值:
1) 程序运行到 while 时,因为 i=1,i<=100 成立,所以会执行循环体;执行结束后 i 的值变为 2,sum 的值变为 1。
2) 接下来会继续判断 i<=100 是否成立,因为此时 i=2,i<=100 成立,所以继续执行循环体;执行结束后 i 的值变为 3,sum 的值变为3。
3) 重复执行步骤 2)。
4) 当循环进行到第 100 次,i 的值变为 101,sum 的值变为 5050;因为此时 i<=100 不再成立,所以就退出循环,不再执行循环体,转而执行 while 循环后面的代码。
while 循环的整体思路是这样的:设置一个带有变量的循环条件,也即一个带有变量的表达式;在循环体中额外添加一条语句,让它能够改变循环条件中变量的值。这样,随着循环的不断执行,循环条件中变量的值也会不断变化,终有一个时刻,循环条件不再成立,整个循环就结束了。
如果循环条件中不包含变量,会发生什么情况呢?
1) 循环条件成立时的话,while 循环会一直执行下去,永不结束,成为“死循环”。例如:
2) 循环条件不成立的话,while 循环就一次也不会执行。例如:
再看一个例子,统计从键盘输入的一行字符的个数:
do while 循环的一般形式为:
用 do while 计算 1 加到 100 的值:
上节我们使用 while 循环来计算 1 加到 100 的值,代码如下:
for 循环的一般形式为:
1) 先执行“表达式1”。
2) 再执行“表达式2”,如果它的值为真(非 0),则执行循环体,否则结束循环。
3) 执行完循环体后再执行“表达式3”。
4) 重复执行步骤 2) 和 3),直到“表达式2”的值为假,就结束循环。
上面的步骤中,2) 和 3) 是一次循环,会重复执行,for 语句的主要作用就是不断执行步骤 2) 和 3)。
“表达式1”仅在第一次循环时执行,以后都不会再执行,可以认为这是一个初始化语句。“表达式2”一般是一个关系表达式,决定了是否还要继续下次循环,称为“循环条件”。“表达式3”很多情况下是一个带有自增或自减操作的表达式,以使循环条件逐渐变得“不成立”。
for 循环的执行过程可用下图表示:
我们再来分析一下“计算从 1 加到 100 的和”的代码:
1) 执行到 for 语句时,先给 i 赋初值1,判断 i<=100 是否成立;因为此时 i=1,i<=100 成立,所以执行循环体。循环体执行结束后(sum 的值为1),再计算 i++。
2) 第二次循环时,i 的值为2,i<=100 成立,继续执行循环体。循环体执行结束后(sum 的值为3),再计算 i++。
3) 重复执行步骤 2),直到第101次循环,此时 i 的值为101,i<=100 不成立,所以结束循环。
由此我们可以总结出 for 循环的一般形式:
1) 修改“从1加到100的和”的代码,省略“表达式1(初始化条件)”:
2) 省略了“表达式2(循环条件)”,如果不做其它处理就会成为死循环。例如:
3) 省略了“表达式3(自增或自减)”,就不会修改“表达式2(循环条件)”中的变量,这时可在循环体中加入修改变量的语句。例如:
4) 省略了“表达式1(初始化语句)”和“表达式3(自增或自减)”。例如:
5) 3 个表达式可以同时省略。例如:
6) “表达式1”可以是初始化语句,也可以是其他语句。例如:
7) “表达式1”和“表达式3”可以是一个简单表达式也可以是逗号表达式。
8) “表达式2”一般是关系表达式或逻辑表达式,但也可是数值或字符,只要其值非零,就执行循环体。例如:
【示例 1】for 嵌套执行的流程。
在 C语言中,代码是顺序、同步执行的,当前代码必须执行完毕后才能执行后面的代码。这就意味着,外层 for 每次循环时,都必须等待内层 for 循环完毕(也就是循环 4 次)才能进行下次循环。虽然 i 是变量,但是对于内层 for 来说,每次循环时它的值都是固定的。
【示例 2】输出一个 4×4 的整数矩阵。
外层 for 第二次循环时,i 为 2,内层 for 要输出四次 2*j 的值,也就是第二行的数据;接下来执行 printf("\n") 和 i++,外层 for 的第二次循环才算结束。外层 for 第三次、第四次循环以此类推。
可以看到,内层 for 每循环一次输出一个数据,而外层 for 每循环一次输出一行数据。
【示例 3】输出九九乘法表。
需要注意的是,内层 for 的结束条件是
九九乘法表还有更多输出方式,请查看:C语言输出九九乘法表(5种解法)
除了 while 和 for,C语言中还有一个 goto 语句,它也能构成循环结构。不过由于 goto 语句很容易造成代码混乱,维护和阅读困难,饱受诟病,不被推荐,而且 goto 循环完全可以被其他循环取代,所以后来的很多编程语言都取消了 goto 语句,我们也不再讲解。
对于 while 和 do while 循环,循环变量的初始化操作应该在 while 和 do while 语句之前完成,而 for 循环可以在内部实现循环变量的初始化。
for 循环是最常用的循环,它的功能强大,一般都可以代替其他循环。
声明:当前文章为本站“玩转C语言和数据结构”官方原创,由国家机构和地方版权局所签发的权威证书所保护。
C语言中常用的编程结构有三种(其它编程语言也是如此),它们分别是:
- 顺序结构:代码从前往后依次执行,没有任何“拐弯抹角”,不跳过任何一条语句,所有的语句都会被执行到。
- 选择结构:也叫分支结构。代码会被分成多个部分,程序会根据特定条件(某个表达式的运算结果)来判断到底执行哪一部分。
- 循环结构:程序会重新执行同一段代码,直到条件不再满足,或者遇到强行跳出语句(break 关键字)。
所谓循环(Loop),就是重复地执行同一段代码,例如要计算 1+2+3+……+99+100 的值,就要重复进行 99 次加法运算。顺序结构不用多说,对选择结构不了解的读者可猛击《C语言if else语句详解》一文系统了解。
C语言while循环
while 循环的一般形式为:
while(表达式){
语句块
}
我们通常将“表达式”称为循环条件,把“语句块”称为循环体,整个循环的过程就是不停判断循环条件、并执行循环体代码的过程。
用 while 循环计算 1 加到 100 的值:
#include <stdio.h> int main(){ int i=1, sum=0; while(i<=100){ sum+=i; i++; } printf("%d\n",sum); return 0; }运行结果:
5050
代码分析:1) 程序运行到 while 时,因为 i=1,i<=100 成立,所以会执行循环体;执行结束后 i 的值变为 2,sum 的值变为 1。
2) 接下来会继续判断 i<=100 是否成立,因为此时 i=2,i<=100 成立,所以继续执行循环体;执行结束后 i 的值变为 3,sum 的值变为3。
3) 重复执行步骤 2)。
4) 当循环进行到第 100 次,i 的值变为 101,sum 的值变为 5050;因为此时 i<=100 不再成立,所以就退出循环,不再执行循环体,转而执行 while 循环后面的代码。
while 循环的整体思路是这样的:设置一个带有变量的循环条件,也即一个带有变量的表达式;在循环体中额外添加一条语句,让它能够改变循环条件中变量的值。这样,随着循环的不断执行,循环条件中变量的值也会不断变化,终有一个时刻,循环条件不再成立,整个循环就结束了。
如果循环条件中不包含变量,会发生什么情况呢?
1) 循环条件成立时的话,while 循环会一直执行下去,永不结束,成为“死循环”。例如:
#include <stdio.h> int main(){ while(1){ printf("1"); } return 0; }运行程序,会不停地输出“1”,直到用户强制关闭。
2) 循环条件不成立的话,while 循环就一次也不会执行。例如:
#include <stdio.h> int main(){ while(0){ printf("1"); } return 0; }运行程序,什么也不会输出。
再看一个例子,统计从键盘输入的一行字符的个数:
#include <stdio.h> int main(){ int n=0; printf("Input a string:"); while(getchar()!='\n') n++; printf("Number of characters: %d\n", n); return 0; }运行结果:
Input a string:https://xiexuewu.github.io
Number of characters: 26
getchar()!='\n'
,其意义是,只要从键盘输入的字符不是回车就继续循环。循环体n++;
完成对输入字符个数计数。
C语言do while循环
除了 while 循环,在 C语言中还有一种 do while 循环。do while 循环的一般形式为:
do{
语句块
}while(表达式);
用 do while 计算 1 加到 100 的值:
#include <stdio.h> int main(){ int i=1, sum=0; do{ sum+=i; i++; }while(i<=100); printf("%d\n", sum); return 0; }运行结果:
5050
注意while 循环和 do while 各有特点,大家可以适当选择,实际编程中使用 while 循环较多。while(i<=100);
最后的分号;
,这个必须要有。
C语言for循环
除了 while 循环,C语言中还有 for 循环,它的使用更加灵活,完全可以取代 while 循环。上节我们使用 while 循环来计算 1 加到 100 的值,代码如下:
#include <stdio.h> int main(){ int i, sum=0; i = 1; //语句① while(i<=100 /*语句②*/ ){ sum+=i; i++; //语句③ } printf("%d\n",sum); return 0; }可以看到,语句 ① ② ③ 被放到了不同的地方,代码结构较为松散。为了让程序更加紧凑,可以使用 for 循环来代替,如下所示:
#include <stdio.h> int main(){ int i, sum=0; for(i=1/*语句①*/; i<=100/*语句②*/; i++/*语句③*/){ sum+=i; } printf("%d\n",sum); return 0; }在 for 循环中,语句 ① ② ③ 被集中到了一起,代码结构一目了然。
for 循环的一般形式为:
for(表达式1; 表达式2; 表达式3){
语句块
}
1) 先执行“表达式1”。
2) 再执行“表达式2”,如果它的值为真(非 0),则执行循环体,否则结束循环。
3) 执行完循环体后再执行“表达式3”。
4) 重复执行步骤 2) 和 3),直到“表达式2”的值为假,就结束循环。
上面的步骤中,2) 和 3) 是一次循环,会重复执行,for 语句的主要作用就是不断执行步骤 2) 和 3)。
“表达式1”仅在第一次循环时执行,以后都不会再执行,可以认为这是一个初始化语句。“表达式2”一般是一个关系表达式,决定了是否还要继续下次循环,称为“循环条件”。“表达式3”很多情况下是一个带有自增或自减操作的表达式,以使循环条件逐渐变得“不成立”。
for 循环的执行过程可用下图表示:
![for 循环的执行过程](/uploads/allimg/240821/101424BD-0.jpg)
我们再来分析一下“计算从 1 加到 100 的和”的代码:
#include <stdio.h> int main(){ int i, sum=0; for(i=1; i<=100; i++){ sum+=i; } printf("%d\n",sum); return 0; }运行结果:
5050
代码分析:1) 执行到 for 语句时,先给 i 赋初值1,判断 i<=100 是否成立;因为此时 i=1,i<=100 成立,所以执行循环体。循环体执行结束后(sum 的值为1),再计算 i++。
2) 第二次循环时,i 的值为2,i<=100 成立,继续执行循环体。循环体执行结束后(sum 的值为3),再计算 i++。
3) 重复执行步骤 2),直到第101次循环,此时 i 的值为101,i<=100 不成立,所以结束循环。
由此我们可以总结出 for 循环的一般形式:
for(初始化语句; 循环条件; 自增或自减){
语句块
}
for循环的三个表达式
for 循环中的“表达式1(初始化条件)”、“表达式2(循环条件)”和“表达式3(自增或自减)”都是可选项,都可以省略(但分号;
必须保留)。1) 修改“从1加到100的和”的代码,省略“表达式1(初始化条件)”:
int i = 1, sum = 0; for( ; i<=100; i++){ sum+=i; }可以看到,将
i=1
移到了 for 循环的外面。2) 省略了“表达式2(循环条件)”,如果不做其它处理就会成为死循环。例如:
for(i=1; ; i++) sum=sum+i;相当于:
i=1; while(1){ sum=sum+i; i++; }所谓死循环,就是循环条件永远成立,循环会一直进行下去,永不结束。死循环对程序的危害很大,一定要避免。
3) 省略了“表达式3(自增或自减)”,就不会修改“表达式2(循环条件)”中的变量,这时可在循环体中加入修改变量的语句。例如:
for( i=1; i<=100; ){ sum=sum+i; i++; }
4) 省略了“表达式1(初始化语句)”和“表达式3(自增或自减)”。例如:
for( ; i<=100 ; ){ sum=sum+i; i++; }相当于:
while(i<=100){ sum=sum+i; i++; }
5) 3 个表达式可以同时省略。例如:
for( ; ; ) 语句
相当于:while(1) 语句
6) “表达式1”可以是初始化语句,也可以是其他语句。例如:
for( sum=0; i<=100; i++ ) sum=sum+i;
7) “表达式1”和“表达式3”可以是一个简单表达式也可以是逗号表达式。
for( sum=0,i=1; i<=100; i++ ) sum=sum+i;或:
for( i=0,j=100; i<=100; i++,j-- ) k=i+j;
8) “表达式2”一般是关系表达式或逻辑表达式,但也可是数值或字符,只要其值非零,就执行循环体。例如:
for( i=0; (c=getchar())!='\n'; i+=c );又如:
for( ; (c=getchar())!='\n' ; ) printf("%c",c);
C语言循环嵌套
在 C 语言中,if else、while、do while、for 都可以相互嵌套。所谓嵌套(Nest),就是一条语句里面还有另一条语句,例如 for 里面还有 for,while 里面还有 while,或者 for 里面有 while,while 里面有 if else,这都是允许的。【示例 1】for 嵌套执行的流程。
#include <stdio.h> int main() { int i, j; for(i=1; i<=4; i++){ //外层for循环 for(j=1; j<=4; j++){ //内层for循环 printf("i=%d, j=%d\n", i, j); } printf("\n"); } return 0; }运行结果:
i=1, j=1
i=1, j=2
i=1, j=3
i=1, j=4
i=2, j=1
i=2, j=2
i=2, j=3
i=2, j=4
i=3, j=1
i=3, j=2
i=3, j=3
i=3, j=4
i=4, j=1
i=4, j=2
i=4, j=3
i=4, j=4
在 C语言中,代码是顺序、同步执行的,当前代码必须执行完毕后才能执行后面的代码。这就意味着,外层 for 每次循环时,都必须等待内层 for 循环完毕(也就是循环 4 次)才能进行下次循环。虽然 i 是变量,但是对于内层 for 来说,每次循环时它的值都是固定的。
【示例 2】输出一个 4×4 的整数矩阵。
#include <stdio.h> int main() { int i, j; for(i=1; i<=4; i++){ //外层for循环 for(j=1; j<=4; j++){ //内层for循环 printf("%-4d", i*j); } printf("\n"); } return 0; }运行结果:
1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16外层 for 第一次循环时,i 为 1,内层 for 要输出四次 1*j 的值,也就是第一行数据;内层 for 循环结束后执行 printf("\n"),输出换行符;接着执行外层 for 的 i++ 语句。此时外层 for 的第一次循环才算结束。
外层 for 第二次循环时,i 为 2,内层 for 要输出四次 2*j 的值,也就是第二行的数据;接下来执行 printf("\n") 和 i++,外层 for 的第二次循环才算结束。外层 for 第三次、第四次循环以此类推。
可以看到,内层 for 每循环一次输出一个数据,而外层 for 每循环一次输出一行数据。
【示例 3】输出九九乘法表。
#include <stdio.h> int main(){ int i, j; for(i=1; i<=9; i++){ //外层for循环 for(j=1; j<=i; j++){ //内层for循环 printf("%d*%d=%-2d ", i, j, i*j); } printf("\n"); } return 0; }运行结果:
1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81和示例 2 一样,内层 for 每循环一次输出一条数据,外层 for 每循环一次输出一行数据。
需要注意的是,内层 for 的结束条件是
j<=i
。外层 for 每循环一次,i 的值就会变化,所以每次开始内层 for 循环时,结束条件是不一样的。具体如下:
- 当 i=1 时,内层 for 的结束条件为 j<=1,只能循环一次,输出第一行。
- 当 i=2 时,内层 for 的结束条件是 j<=2,循环两次,输出第二行。
- 当 i=3 时,内层 for 的结束条件是 j<=3,循环三次,输出第三行。
- 当 i=4、5、6... 时,以此类推。
九九乘法表还有更多输出方式,请查看:C语言输出九九乘法表(5种解法)
总结
C语言中常用的循环结构有 while 循环和 for 循环,它们都可以用来处理同一个问题,一般可以互相代替。除了 while 和 for,C语言中还有一个 goto 语句,它也能构成循环结构。不过由于 goto 语句很容易造成代码混乱,维护和阅读困难,饱受诟病,不被推荐,而且 goto 循环完全可以被其他循环取代,所以后来的很多编程语言都取消了 goto 语句,我们也不再讲解。
国内很多大学仍然讲解 goto 语句,但也仅仅是完成教材所设定的课程,goto 语句在实际开发中很难见到。对于 while 和 do while 循环,循环体中应包括使循环趋于结束的语句。
对于 while 和 do while 循环,循环变量的初始化操作应该在 while 和 do while 语句之前完成,而 for 循环可以在内部实现循环变量的初始化。
for 循环是最常用的循环,它的功能强大,一般都可以代替其他循环。
掌握了循环结构,紧接着就是学习 C语言中的 continue 和 break 的用法,感兴趣的读者可猛击《C语言break和continue用法详解》一文系统学习。
声明:当前文章为本站“玩转C语言和数据结构”官方原创,由国家机构和地方版权局所签发的权威证书所保护。