高质量博主,点个关注不迷路🌸🌸🌸!
目录
I. 案例引入
II. while语句
III. do while语句
IV. for语句
前言: 书接上回,判断结构已经解决,接下来是另一种很重要的结构:循环结构的实现,在C语言中,有两种循环结构的实现方式,一种是用while语句实现,另一种则是通过for语句实现,我们在本篇笔记中对两种语句进行讲解。
I. 案例引入
首先,我们理解为什么我们需要循环结构,我们看这样一个需求:
现在我想要输出从1到100,总计一百个数字,我们要如何实现呢?
方法一:手写一百条printf()语句
但显然方法一不可取,因为方法一产生了庞大的代码量,既不利于编写程序,也不利于阅读和纠错,并且当我更改需求时,例如从1到10000,则会导致程序无法被快速的修改。
方法二:使用一种循环的结构,循环一百次,每次循环输出一个数字。
显然,方法二才是我们需要的方法,同时引出了我们的学习目标:while和for两种循环语句。
II. while语句
首先介绍第一种实现循环的语句:while语句
while语句的语法格式是这样的:
while(条件表达式){
当条件表达式为真时,会循环执行的内容
}
看到这个格式定义之后,我们先思考一个问题:
假设有这样的一段程序:
#include<stdio.h>
int main(){
int a = 3;
while(a > 0){
printf("%d\n",a);
}
return 0;
}
这段程序执行后,会发生什么呢?我们分析一下:
首先,a被赋值3,而后进入while语句,while判断a是否大于零,而很显然,a是大于零的,于是执行while语句内部的执行内容,是打印a的值,打印之后,又进行下一次判断,但是,由于a的值并没有发生修改,所以这个循环会一直执行下去,也就是说,它会一直输出a的值3:
当出现这种情况时,往往是因为我们的判断表达式中的变量在循环中并没有修改,进而引发了无限的循环,我们通常称之为死循环。
死循环是一种错误,我们需要避免它,避免的方法就是要确保我们的条件表达式中的变量会随着循环的执行而修改。
例如我们要实现打印1到100,一百个数字,可以这么写:
#include<stdio.h>
int main(){
int a = 1;
while(a <= 100){
printf("%d\n",a);
a++;
}
return 0;
}
这段程序中,当每一次循环在执行的过程中,while的判断表达式的变量a的值都在自增,于是我们就实现了破除死循环的效果,当a的值增加到101时,由于不满足a <= 100,循环发生了终止。
III. do while语句
学习了while循环语句后,我们介绍它的一个变种,叫do while语句。do while语句有什么作用呢?我们先看一个例子:
#include<stdio.h>
int main(){
int a = 1;
while(a < 0){
printf("%d\n",a);
}
return 0;
}
上面是一段while循环的例子,这个例子中,a的值是1,而while的判断条件是a<0,于是乎循环一次也不会执行,即我们运行后没有任何效果:
现在我提出需求: 还是上面的这段程序,不修改while的条件表达式,也不修改a的值,如何让这个循环执行一次,而后退出呢?这就引入了do-while语句:
do{
会先执行一次,而后检查while中的条件表达式,如果符合条件,则继续循环,否则退出
} while(条件表达式);
也就是说,使用了do-while时,无论条件是否成立,do中的语句会先执行一次,而后才进行判断;当第一次无条件执行过后,do-while的逻辑完全等价于while,即条件成立则继续执行,否则退出循环。于是上面的需求可以用下面的代码实现:
#include<stdio.h>
int main(){
int a = 1;
do{
printf("%d",a);
}
while(a < 0);
return 0;
}
这段代码执行之后,会输出一次a,而后由于不满足条件,退出了循环:
IV. for语句
介绍完了while循环语句之后,我们介绍另一种循环语句:for语句,for语句相较于while,具有更高的灵活度,但相应的,格式也会更复杂一些,我们先看一下它的通用格式:
for(表达式1;表达式2;表达式3){
循环体
}
看这个通用格式,其实看不出它的执行逻辑,因此我们再进一步深究一下:
表达式1:表达式1通常是用来做一些对变量赋值的操作,这些变量往往是控制循环执行次数的变量,例如我们使用变量a作为控制循环执行次数的变量,那么表达式1可以是:a = 1
表达式2: 表达式2是用来判断循环是否能够继续执行下去的判定式,例如我们可以写: a < 10,表示当a小于10时,循环继续执行
表达式3: 表达式3一般用来对控制循环执行次数的变量的值进行修改,以便跳出循环,避免死循环的发生。
那么这三个表达式,和循环体,它们的执行次序是怎么样的呢?
表达式1(只会执行一次) - - - > 表达式2 - - - > 循环体 - - - > 表达式3
也就是说,表达式3,对变量值的修改,发生在循环体之后,但很多新手认为三个表达式是先执行的,而后执行循环体,因此我们可以用一段代码验证表达式3确实在循环体之后执行:
#include<stdio.h>
int main(){
int a;
for(a = 1;a >= 1 ; a --){
printf("a = %d",a);
}
return 0;
}
上面这段代码很有意思,如果说,表达式3先于循环体执行,也就是按照:
表达式1(只会执行一次) - - - > 表达式2 - - - > 表达式3 - - - > 循环体
这样的顺序执行,那么我们分析一下输出的a的值:
表达式1执行后,a = 1
表达式2执行后,a = 1 不变
表达式3执行后,a = a - 1 = 0
于是输出结果为0,但我们运行代码发现:
因而我们证明了循环体确实在表达式3之前执行,也即for循环三个表达式与循环体执行顺序应该为:
表达式1(只会执行一次) - - - > 表达式2 - - - > 循环体 - - - > 表达式3 (牢记次序)
另外补充一个细节:
在C语言中,"通常" 不支持在表达式1中对变量进行声明,而只可以赋值,即不支持:
int a = 1
而支持
a = 1
因此我们通常是这样写的:
#include<stdio.h>
int main(){
int a;
for(a = 1;a >= 1 ; a --){
printf("a = %d",a);
}
return 0;
}
即先声明a,而后在for中进行赋值操作(当然,现在的编译器可能支持在for中第一个表达式里定义,但通常不这样写。)
那到这里,循环语句也已学习完成,我们继续向C语言入门冲锋!