上一节中我们讲到,在C语言中可以使⽤ if 、 switch 实现分⽀结构,这一节我们使⽤ for 、 while 、 do while 实现循环结构。
1. while循环结构
while语句的语法结构和 if语句非常相似。
1.1while的语法形式
while(表达式)
{
语句;
}
1.2 if和while的对比
if语句 | while循环 |
---|---|
if(表达式) { 语句; } | while(表达式) { 语句; } |
用代码看下他们的使用方法上有什么区别:
if语句满足条件打印一次“这里是if语句。”
#include <stdio.h>
int main()
{
if (1)
{
printf("这里是if语句。\n");
}
return 0;
}
while语句满足条件无限打印“这里是while语句。”
#include <stdio.h>
int main()
{
while (1)
{
printf("这里是while语句。\n");
}
return 0;
}
1.2 while语句的执行流程
首先执行判断表达式,表达式的值为0,不进入循环,直接结束;表达式的值不为0,进入循环,执行语句,语句执行完毕后继续判断,如此往复,直到表达式的值为0或break跳出while结构。
1.3 while循环实践
练习:在屏幕上打印1-10的值。
参考代码:
#include <stdio.h>
int main()
{
int num = 1;
while (num <= 10)
{
printf("%d\n", num);
num++;
}
return 0;
}
执行效果如下:
1.4 练习
输⼊⼀个正整数,逆序打印这个整数的每⼀位。
例如:
输⼊:1234,输出:4 3 2 1
输⼊:521,输出:1 2 5
题目解析:
- 要想得到n的最低位,可以使⽤n%10的运算,得到的余数就是最低位,如:1234%10得到4
- 要想去掉n的最低位,找出倒数第⼆位,我们使用int类型的特性,使⽤n=n/10操作就可以去掉最低位的数值,如:n=1234/10得到123,123相较于1234就去掉了最低位,123%10就得到倒数第⼆位3。
- 循环1和2两个步骤,在n变成0之前,就能到所有的位。
参考代码:
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
while (num)
{
printf("%d", num%10);
num /= 10;
}
return 0;
}
执行结果如下:
—————————————————————————————————————————————
2. for循环
做为C语言中三大循环结构中的for语句,它是使用率最高的。
2.1 for的语法形式
for的使用方法如下:
for(表达式1; 表达式2; 表达式3)
{
语句;
}
表达式1:用于循环变量的初始化。
表达式2:用于循环结束条件的判断。
表达式3:用于循环变量的调整。
2.3 for循环的执行流程
首先执行表达式1的变量初始化,然后进行表达式2的判断,如果表达式为假,跳出循环直接结束;如果表达式为真,那么就执行循环语句,循环语句执行完成后,再去执行表达式3,调整循环变量后,再去执行表达式2,直到表达式2的值为假,跳出循环到结束。
整个循环中,表达式只有在初次进入的时候执行了一次,剩下的就是表达式2,循环语句,表达式3在循环。
for循环的实践
练习:在屏幕上打印1~10的值
参考代码:
#include <stdio.h>
int main()
{
int num = 0;
for (num = 1; num <= 10; num++)
{
printf("%d ", num);
}
return 0;
}
运行结果:
2.4 while循环和for循环对比
流程图对比:
代码对比:
从上面的对比中看出,for和while在实现循环的过程中都有初始化、判断、调整这三部分。
- for循环的三个部分非常集中,便于代码的维护。
- 在代码多的时候while循环的三个部分就很分散,不利于维护和阅读。
所以从形式上for循环要更好一些。
2.5 练习
练习:计算1~100之间3的倍数的数字之和。
#include <stdio.h>
int main()
{
int num = 0;
for (num = 1; num <= 100; num++)
{
if (num % 3 == 0)
{
printf("%d ", num);
}
}
return 0;
}
上面的代码是从1到100每个数值对数值3进行求余计算,当然我们也可以优化下写成下面的样式:
#include <stdio.h>
int main()
{
int num = 0;
for (num = 3; num <= 100; num += 3)
{
printf("%d ", num);
}
return 0;
}
3.do-while循环
do-while语句在C语言中使用的是最少的。
3.1 do-while循环的语法形式
do-while的语法形式如下:
do
{
语句;
}while(表达式);
do-while最大的特点是,不论如何它都要先执行一次循环语句,即至少执行一次循环语句,然后再判断条件的真假来决定是否进行下一次的循环语句。
while和for这两个循环都是先判断,条件如果满足就进入循环,执行循环语句,如果不满足就跳出循环。
3.2 do while循环的执行流程
在do-while循环中先执⾏图上的“语句”,执⾏完语句,在去执行“判断表达式”,判断表达式的结果是真,则继续循环,执⾏循环语句;判断表达式的结果是假,则循环结束。
所以在do-while语句中循环体是⾄少执⾏⼀次的,这是do-while循环⽐较特殊的地⽅。
3.3 do while循环的实例
练习:在屏幕上打印1~10的值。
#include <stdio.h>
int main()
{
int num = 1;
do
{
printf("%d ", num);
num++;
} while (num <= 10);
return 0;
}
执行结果如下:
3.4 练习
输⼊⼀个正整数,计算这个整数是⼏位数?
例如:
输⼊:1234 输出:4
输⼊:12 输出:2
#include <stdio.h>
int main()
{
int num = 0;
int count = 0;
scanf("%d", &num);
do
{
count++;
num = num/10;
} while (num);
printf("输入数值的位数是%d位。", count);
return 0;
}
执行结果如下:
4. break和continue语句
在循环执行的过程中,经常会遇到一些特殊情况需要提前终止循环。在C语言中, break和 continue就是用于这种特殊情况的关键字。
- break的作⽤是⽤于永久的终⽌循环,只要 break被执⾏,直接就会跳出循环,执行循环以后的语句。
- continue的作⽤是跳过本次循环continue后边的代码,重新进行表达式判断。在 for循环和 while循环中有所差异的。
4.1 while循环中的 break和continue
4.1.1 break在while循环中
#include <stdio.h>
int main()
{
int num = 0;
while (num <= 10)
{
if (5 == num)
{
break;
}
printf("%d ", num);
num++;
}
return 0;
}
执行结果如下:
打印了0,1,2,3,4后,当 i 等于5的时候,循环在 break的地⽅终⽌,不再打印,跳出循环体。
所以 break的作⽤就是永久的终⽌循环,只要 break被执⾏, break外的第⼀层循环就终⽌了。
那以后我们在循环中,想在某种条件下终⽌循环,则可以使⽤ break来完成我们想要的效果。
4.1.2 continue 语句在while循环中
continue从英文字面上来看,就是继续的意思,在循环语句中的作用就是忽略此次循环,跳过本次循环 continue后面的代码,执行下一次循环判断。
我们把上面 break中的代码换成 continue看下会发生什么:
#include <stdio.h>
int main()
{
int num = 0;
while (num <= 10)
{
if (5 == num)
{
continue;
}
printf("%d ", num);
num++;
}
return 0;
}
执行结果如下:
上面的结果中我们发现,程序并没有运行完毕, 进入了一个死循环的状态,这是因为在 num的值自加到 5时,进入了 if语句的判断中,此时 if 语句条件成立,进入分支语句执行 continue语句,我们前面说过, continue 是跳过此次循环,忽略 continue后面的代码,进入到下一次的循环判断,而我们终端代码的 while 循环的调整语句是在 continue语句后面的,所以,造成了此段代码在运行中出现死循环的情况。
4.2 for循环中的break和continue语句
4.2.1 break在for循环中
break在for循环中,和在 while循环是一样的,都是终止循环,只要是执行到了 break语句,循环就会终止,执行循环后面代码。
#include <stdio.h>
int main()
{
int num = 0;
for (num = 1; num <= 10; num++)
{
if (5 == num)
{
break;
}
printf("%d ", num);
}
printf("\n我跳出来了。");
return 0;
执行效果如下:
从上面看出来, break在 for中的效果和 while中是一样的。
4.2.2 continue语句在for循环中
我们在把上面代码中 break替换成 continue看下会发生什么,与在 while中有什么区别。
#include <stdio.h>
int main()
{
int num = 0;
for (num = 1; num <= 10; num++)
{
if (5 == num)
{
continue;
}
printf("%d ", num);
}
return 0;
}
我们看下运行结果:
这里的输出结果和 whlie中结果不一样,在while中我们讲过它进入了死循环,但是在 for中却正常运行结束了,这是为什么呢?回答这个问题之前我们先回顾下前面讲的 while 和 for的代码结构对比图。
从结构图中我们可以很明显的发现, while的调整语句是在循环语句中的, continue执行后是跳过了调整语句 num++,而 for循环的 continue语句执行后还是会继续执行调整语句的。
从上图中我们可以明显的看出 continue 在 for 和 while 循环中的区别。
4.3 do while循环中的break和continue语句
break和 continue 语句在 do while循环中和 while 循环中是一样的效果。
4.3.1 do while循环中的break
我们把 while中的代码修改下看下结果:
#include <stdio.h>
int main()
{
int num = 1;
do
{
if (5 == num)
{
break;
}
printf("%d ", num);
num++;
} while (num <= 10);
return 0;
}
4.3.2 do while循环中的continue
#include <stdio.h>
int main()
{
int num = 0;
do
{
if (5 == num)
{
continue;
}
printf("%d ", num);
num++;
} while (num <= 10);
return 0;
}
4.4 总结
经过上面的代码展现, break语句在三个循环中的效果是一样的,没有什么变化。
而 continue在while和do while中的效果是一样的,for循环中不一样的。
5. 循环的嵌套
上面我们讲了for 、 while 、 do while 三种循环的使用方法,但是我们在实际写代码中经常是嵌套在一起才能更好的去解决问题,这就是嵌套循环。我们做个练习看下如何应用:
练习
找出100~200之间的素数,并打印在屏幕上。
注:素数⼜称质数,只能被1和本⾝整除的数字。
我们先分析下这个题目:
我们先把100-200之间的数定义为 i,素数的定义是只能被1和本身整除,那么我们要用i去除以从2到i-1的所有数,只要有一个能被整除,那么他就不是整数。
首先我们先实现如何产生100~200之间数:
for (i = 100; i <= 200; i++)
{
}
好了 上面我们实现了 100~200之间的数,那么下一步我们就要实现如何从2到i-1的数。
for(j = 2; j <= i-1; j++)
{
}
我们把上面这两个循环进行嵌套写成如下形式:
for (i = 100; i <= 200; i++)
{
for(j = 2; j <= i-1; j++)
{
}
}
100~200的数i除以2到i-1的数,如果能被整除就不是素数,我们用if判断。
if(i % j ==0)
{
}
结合以上的思路我们把代码整合一下:
#include <stdio.h>
#include <stdbool.h>
int main()
{
int i = 0;
int j = 0;
for (i = 100; i <= 200; i++)
{
bool flag = true;
for (j = 2; j <= i - 1; j++)
{
if (i % j == 0)
{
flag = false;
break;
}
}
if (flag)
{
printf("%d ", i);
}
}
return 0;
}
6. goto 语句
在C语言中提供了一个语⾔提供了⼀种⾮常特别的语法,就是goto 语句和跳转标号, goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。使用方法如下
goto 标记;
标记:
语句;
我们用代码看下它的效果:
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next;
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}
执行结果如下:
goto 语句使用起来很方便,但是如果使用不当,它带来的问题也是灾难性的,它会打乱程序的运行顺序,可能跳过了某些对象的构造、变量的初始化、重要的计算等语句,因此我们在写代码的时候尽量避免去使用它。
goto 也不是并没有一点用处,比如我们在多层嵌套循环中,如果一层一层的用 break语句跳出循环会很麻烦,那么此时goto 语句的作用就显现出来了。
for ()
{
for()
{
for()
{
goto error;
}
}
}
error:
语句;
从上面的代码中我们看出,如果不使用goto 语句,那么我们要使用3个break语句才能跳出整个循环体系,而使用goto 语句我们只需要在需要使用的地方直接跳转到我们想让它到达的地方就可以了。
就象楼房着火了,来不及从楼梯一级一级往下走,可从窗口跳出火坑。所以我们主张少用、慎用 goto 语句,而不是禁用。
此句引用自《高质量C++/C编程指南》