分支与循环
while循环
if与while的对比
if(表达式)语句;while(表达式)语句;
下面来看一个例子:
用 if 写:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {if (1)printf("hehe");//if后面条件满足,打印一次hehereturn 0;
}
用 while 写:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {while (1)printf("hehe");//while后面条件满足,死循环打印hehereturn 0;
}
可以看出,它们的区别就是while可以实现循环
while语句的执行流程
首先要执行判断表达式,表达式的值为0,循环直接结束
表达式的值不为0,则执行循环语句
语句执行完后继续判断,是否进行下一次循环
- 练习1:在屏幕上打印1~10
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;while (i <= 10) {printf("%d ", i);i++;}return 0;
}
输出如下:
- 练习2:输入一个正的整数,逆序打印这个整数的每一位
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int num;int n;scanf("%d", &num);while (num!=0) {n = num % 10;printf("%d", n);num /= 10;}return 0;
}
输入12345
输出如下:
for循环
for(表达式1;表达式2;表达式3
表达式1 用于循环变量的初始化
表达式2 用于循环结束条件的判断
表达式3 用于循环变量的调整
而while:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;//循环变量的初始化while (i <= 10) //循环的判断条件{printf("%d ", i);i++;//循环变量的调整}return 0;
}
for循环的执行流程
首先执行 表达式1初始化循环变量,接下来就是执行表达式2的判断部分
表达式2的结果如果==0,则循环结束;表达式2的结果如果!=0,则执行循环语句
循环语句执行完后,再去执行表达式3,调整循环变量
然后再去表达式2 的地方执行判断,表达式2的结果是否为0,决定循环是否继续
整个循环的过程中,表达式1初始化部分只被执行1次,剩下的就是表达式2循环,语句表达式3在循环.
用for循环打印1~10:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 0;for (int i = 1;i <= 10;i++) {printf("%d ", i);}return 0;
}
- 练习:计算1~100之间三的倍数的和
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 0,sum=0;for (i = 1;i <= 100;i++) {if (i % 3 == 0) {sum += i;}}printf("%d", sum);return 0;
}
或者优化一下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 0,sum=0;for (i = 3;i <= 100;i+=3) {sum += i;}printf("%d", sum);return 0;
}
结果是一样的:
do-while
语法形式
do语句;
while(表达式);
特征:循环体至少被执行一次
执行流程
- 练习1:用do-while打印1~10的值
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;do{printf("%d ", i);i++;} while (i <= 10);return 0;
}
- 练习2:输入一个正整数,计算一下这个数是几位数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int num,count=0;scanf("%d",&num);do{num /= 10;count++;} while (num);//当num为真(非零),执行printf("%d ", count);return 0;
}
break和continue语句
在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这就需要break 和 continue 两个关键字
break 的作用是用于永久的终止循环,只要break 被执行,直接就会跳出循环,继续往后执行
continue 的作用是跳过本次循环中continue 后边的代码,在 for 循环和 while循环中有所差异的
while循环中的break和continue
while:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;while (i <= 10) {if (i == 5)break;printf("%d ", i);i++;}return 0;
}
输出结果为:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;while (i <= 10) {if (i == 5)continue;printf("%d ", i);i++;}return 0;
}
输出结果为:
打印 1 2 3 4 光标在闪烁
是因为:
i==5时,continue会跳过printf和i++语句
然后判断while里面的语句是否为真,显然为真,则继续执行循环
此时的i仍为5…,循环会一直在i==5时执行下去,所以为死循环
for:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 0;for (int i = 1;i <= 10;i++) {if (i == 5)break;printf("%d ", i);}return 0;
}
输出结果为:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 0;for (int i = 1;i <= 10;i++) {if (i == 5)continue;printf("%d ", i);}return 0;
}
输出结果为:
是因为·:
i==5时,continue会跳过printf和i++d语句
然后i++,i变为6,循环继续执行
如果将for循环的代码变为这样:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 0;for (int i = 1;i <= 10;) {if (i == 5)continue;printf("%d ", i);i++;}return 0;
}
那么输出结果也为死循环:
执行的顺序与while循环相同
do-while循环中的break和continue
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;do{if (i == 5)break;printf("%d ", i);i++;} while (i <= 10);return 0;
}
输出结果如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;do{if (i == 5)continue;printf("%d ", i);i++;} while (i <= 10);return 0;
}
输出结果仍为死循环:
- 练习:判断下面代码的输出
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 1;while (i <= 10) {i++;if (i == 5)continue;printf("%d ", i);}return 0;
}
结果是:
循环的嵌套
- 练习:打印100~1200之间的素数(只能被1和本身整除的数字)
- 判断素数方法:拿2~i-1之间的数字去试除i
- 如果找到了一个数字能整除i,则i不是素数
- 如果没有数字能整除i,则i是素数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {int i = 0;for (i = 100;i <= 200;i++) {int flag = 1;//假设i是素数int j = 0;for (j = 2;j < i;j++) {if (i % j == 0) {flag = 0;//i不是素数break;}}if (flag == 1) {printf("%d ", i);//是素数}}return 0;
}
输出为:
但是这个代码效率不够高
思考一下:
如果n=a*b到时候,a和b中至少有一个数字<=根号n
所以,如果n不是素数,一定有个因子在2~根号n之间
如果在2~根号n之间没有摘到能整除n的数字,那么n就是素数
故,代码可以优化为:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>//数学相关的头文件
int main() {int i = 0;for (i = 101;i<= 200;i+=2) //偶数不可能是素数{int flag = 1;int j = 0;for (j = 2;j < sqrt(i);j++) {if (i % j == 0) {flag = 0;break;}}if (flag == 1) {printf("%d ", i);}}return 0;
}
goto语句
goto语句可以实现在同一个函数内跳转到设置好的标号处
- eg1:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>//数学相关的头文件
int main() {printf("hehe\n");goto next;printf("haha\n");
next:printf("heihei\n");return 0;
}
输出为:
可见,跳过了haha的输出
- eg2:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>//数学相关的头文件
int main() {
again:printf("hehe\n");goto again;return 0;
}
输出结果为:
hehe的死循环
代码中出现的goto语句太多的话,代码的执行流程就比较乱,可控性不高
但在多层循环的代码中,如果想快速跳出,goto就非常方便
1 for(...)
{for(...) {if(disaster) goto error; }
}error;
for循环想提前退出得使用break,一个 break 只能跳出一层for循环,如果3层循环嵌套就得使用3个 break 才能跳出循环,所以此时使用goto语句就会更加的快捷
END…
截至到这里,分支与循环就完事一半啦
已经很晚了,要早点休息喔~zzz
最后…
“我们不全是长篇小说,也不全是短篇故事,
最后的最后,我们成为一部人生作品集。”