那么什么是循环语句?
循环语句是能重复执行其他语句的一种语句,简单讲就是能够重复做某些事情。
循环语句包括:while循环语句,do while循环语句,for循环语句。
while(条件表达式) { 语句; }
看到这里是否觉得while循环格式和if语句类似呢
if(条件表达式) { 语句; }
当语句只有1句时,循环语句和if语句都可以省略{}。所以这里就会有一个小坑,需要注意有无{ } 。
int a = 1;
int b = 2;
if(a>b)//条件a>b不满足
printf("haha");//不打印
printf("haha");//打印
if(a>b)
{
printf("haha");//都不打印
printf("haha");
}
我们再来具体对比一下while语句和if语句
//代码1
#include <stdio.h>
int main()
{
if(1)
printf("hehe\n"); //if后边条件满⾜,打印⼀次hehe
return 0;
}
//代码2
#include <stdio.h>
int main()
{
while(1)
printf("hehe\n"); //while后边的条件满⾜,死循环的打印hehe
return 0;
}
这就是他们的区别,while能实现循环效果。
先来看一个它的流程图
当条件满足时执行循环语句,所以while循环又称“当型”循环。
首先一来就判断条件表达式的值,如果值为0,则直接结束循环;如果表达式值为1,则进入循环执行语句,执行完后再判断条件来判断是否进入下一次循环。如果条件表达式的值一直为1,则会一直循环,除非循环体中含有可以跳出循环控制的语句(break、goto、return)。
让我们来写几个题熟悉一下while语句的用法
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
printf("%d ", i);
i = i+1;
}
return 0;
}
例如: 输入:1234,输出:4 3 2 1
题目解析 1. 要想得到n的最低位,可以使用n%10的运算,得到的余数就是最低位
2. 要想去掉n的最低位,找出倒数第二位,则使用n=n/10 操作就可以去掉最低位的,如: n=1234/10得到123,123相较于1234就去掉了最低位,123%10就得到倒数第二位3。
3. 循环1和2两个步骤,在n变成0之前,就能到所有的位。
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
while(n)
{
printf("%d ", n%10);
n /= 10;
}
return 0;
}
相对于其他两种循环,for循环更多应用于确定循环次数的循环中
for(表达式;表达式;表达式) 语句;//语句不止一句时,加上大括号
表达式1 用于循环变量的初始化 ;
表达式2 用于循环结束条件的判断;
表达式3 用于循环变量的调整 ;
流程图
先对表达式1进行初始化,然后执行表达式2去判断,如果条件为假则结束循环,如果条件为真,则执行循环语句,然后再执行表达式3去调整循环变量,调整完后再进入表达式2去判断条件是否满足,决定是否再执行循环。
这个过程中,表达式1初始化只执行一次,然后就是表达式2、循环语句和表达式3在循环执行。
而此处的break语句和continue语句会在后面讲到。
#include <stdio.h>
int main()
{
int i = 0;
for(i=1; i<=10; i++)
{
printf("%d ", i);
}
return 0;
}
运行结果:
#include <stdio.h>
int main()
{
int i = 0;
int sum = 0;
for(i=1; i<=100; i++)
{
if(i % 4 == 0)
sum += i;
}
printf("%d\n", sum);
return 0;
}
//优化
//如果能直接产⽣4的倍数的数字就省去了多余的循环和判断
#include <stdio.h>
int main()
{
int i = 0;
int sum = 0;
for(i=4; i<=100; i+=4)
{
sum += i;
}
printf("%d\n", sum);
return 0;
}
我们发现他们都有初始化、判断、调整这三个部分,但是for循环中这三个部分更集中些,便于维护代码。
do 语句; while(条件表达式);
do while语句和前两个循环不同,它是先执行一遍循环语句再来判断是否满足条件表达式,如果满足条件则继续循环,不满足条件则停止循环。
需要注意do while语句循环末尾需要添加分号。
在do while循环中先进入循环体执行循环语句,然后进入判断表达式,如果表达式值为0则结束循环;如果值为1则继续循环执行语句,直到不满足判断表达式,再退出循环。因此do while循环又叫“直到型”循环。
#include <stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
一般 do while 使用在循环体至少被执行一次的场景下,所以较少一些。
②输入一个正整数,计算这个整数是几位数?
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int count = 0;
do
{
count++;
n = n / 10;
} while (n);
printf("%d\n", count);
return 0;
}
这里并非只能用do while循环,只是这里用它更合适,就算输入的n为0,那也至少会执行一次循环语句,计算出的count即0的位数为1。
前面讲了while、for、do while三种循环,有时候为了更好解决问题,我们会将它们进行嵌套使用,即循环嵌套。看个例子:
题目:找出100~200之间的素数,并打印在屏幕上(素数就是质数,是那些只能被1和它本身整除的数字,比如5)
解析:1.先要有100~200之间的数字,用循环实现。
2.需要再用循环产生2 ~ i-1之间的数字,i为我们要判断的数字
3.如果数字i被2 ~ i-1之间的某个数字整除,那么i就不是素数,就跳出循环不需要再往后判断;如果没有被2 ~ i-1之间的任何数整除,那么数字i就是一个素数。
代码:方法一
//方法一:试除法
int main()
{
int i = 0;
int count = 0;
// 外层循环用来获取100~200之间的所有数据,100肯定不是素数,因此i从101开始
for(i=101; i<=200; i++)
{
//判断i是否为素数:用[2, i)之间的每个数据去被i除,只要有一个可以被整除,则不是素数
int j = 0;
for(j=2; j<i; j++)
{
if(i%j == 0)
{
break;
}
}
// 上述循环结束之后,如果j和i相等,说明[2, i)之间的所有数据都不能被i整除,则i为素数
if(j==i)
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
方法二
//上述方法的缺陷:超过i一半的数据,肯定不是i的倍数,上述进行了许多没有意义的运算,因此可以采用如下
// 方式进行优化
// 方法二:每拿到一个数据,只需要检测其:[2, i/2]区间内是否有元素可以被2i整除即可,可以说明i不是素数
int main()
{
int i = 0;//
int count = 0;
for(i=101; i<=200; i++)
{
//判断i是否为素数
//2->i-1
int j = 0;
for(j=2; j<=i/2; j++)
{
if(i%j == 0)
{
break;
}
}
//...
if(j>i/2)
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
法三
/*
方法二还是包含了一些重复的数据,再优化:
如果i能够被[2, sqrt(i)]之间的任意数据整除,则i不是素数
原因:如果 m 能被 2 ~ m-1 之间任一整数整除,其二个因子必定有一个小于或等于sqrt(m),另一个大于或等于 sqrt(m)。
*/
int main()
{
int i = 0;
int count = 0;
for(i=101; i<=200; i++)
{
//判断i是否为素数
//2->i-1
int j = 0;
for(j=2; j<=sqrt(i); j++)
{
if(i%j == 0)
{
break;
}
}
//...
if(j>sqrt(i))
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
此处的sqrt()是一个开平方根的函数,sqrt(i)就是根号i。
法四
//方法4
/*
继续对方法三优化,只要i不被[2, sqrt(i)]之间的任何数据整除,则i是素数,但是实际在操作时i不用从101逐渐递增到200,因为出了2和3之外,不会有两个连续相邻的数据同时为素数
*/
int main()
{
int i = 0;
int count = 0;
for(i=101; i<=200; i+=2)
{
//判断i是否为素数
//2->i-1
int j = 0;
for(j=2; j<=sqrt(i); j++)
{
if(i%j == 0)
{
break;
}
}
//...
if(j>sqrt(i))
{
count++;
printf("%d ", i);
}
}
printf("\ncount = %d\n", count);
return 0;
}
在循环过程中如果发生某些状况需要提前终止循环,我们可以使用break和continue两个关键字。
break:它的作用是永久性地跳出循环,直接执行循环后面的内容
continue:它的作用是跳过本次循环中continue后面的代码,然后执行下次循环。在for循环和while循环中有所差异。
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
break;//当i等于5后,就执⾏break,循环就终⽌了
printf("%d ", i);
i = i+1;
}
return 0;
}
i会打印1、2、3、4,当i==5时,就会执行if语句中的break,然后就跳出循环不再打印了。所以break的作用是永久性地跳出循环,会跳出break当前所在的循环。
continue是继续的意思,在c语言中,遇到continue会跳过本次循环在它后面的代码,继续进行下一次循环的判断。
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
continue;
//当i等于5后,就执⾏continue,直接跳过continue的代码,去循环的判断的地⽅
//因为这⾥跳过了i = i+1,所以i⼀直为5,程序陷⼊和死循环
printf("%d ", i);
i = i+1;
}
return 0;
}
continue 可以帮助我们跳过某一次循环 continue 后边的代码,直接到循环的判断部分,进行下一次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成死循环。
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
break;
printf("%d ", i);
}
return 0;
}
在for循环中break和在while循环中一样,遇到break后就彻底终止循环。
把上面的break换成continue试试
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
continue;//这⾥continue跳过了后边的打印,来到了i++的调整部分
printf("%d ", i);
}
return 0;
}
和在while循环中不同,这里打印出了除5以外的1~10的数字。因为在上面while循环的代码中,continue执行后来到条件表达式i<=10进行判断,而这里continue执行后是进行循环变量的调整i++。
do while循环中break和continue的作用与while中的几乎一样。
#include <stdio.h>
int main()
{
int i = 1;
do
{
if(i == 5)
break;
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
#include <stdio.h>
int main()
{
int i = 1;
do
{
if(i == 5)
continue;
printf("%d ", i);
i = i + 1;
}while(i<=10);
return 0;
}
goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next;
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}
但是如果使用不当的话,就会导致在函数内乱跳转,扰乱程序执行流程。但在多层循环中想要快速跳出循环使用goto就很容易,如果使用break的话,它只能一层一层循环的跳出,这种情况使用goto就很快捷。
for(...)
{
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
}
error:
//……
到这里我们本次的学习就结束了,期待下次再见😘💕
请多点点关注,您的点赞、评论都将激励我继续前行,谢谢!