【C】分支与循环2--while/for/do-while/goto以及break和continue在不同循环中的辨析~

分支与循环

while循环

if与while的对比

c 复制代码
if(表达式)
	语句;

while(表达式)
	语句;

下面来看一个例子:

用 if 写:

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	if (1)
		printf("hehe");//if后面条件满足,打印一次hehe
	return 0;
}

用 while 写:

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	while (1)
		printf("hehe");//while后面条件满足,死循环打印hehe
	return 0;
}

可以看出,它们的区别就是while可以实现循环

while语句的执行流程

首先要执行判断表达式,表达式的值为0,循环直接结束

表达式的值不为0,则执行循环语句

语句执行完后继续判断,是否进行下一次循环

  • 练习1:在屏幕上打印1~10
c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	int i = 1;
	while (i <= 10) {
		printf("%d ", i);
		i++;
	}
	return 0;
}

输出如下:

  • 练习2:输入一个正的整数,逆序打印这个整数的每一位
c 复制代码
#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循环

c 复制代码
for(表达式1;表达式2;表达式3

表达式1 用于循环变量的初始化
表达式2 用于循环结束条件的判断
表达式3 用于循环变量的调整

while:

c 复制代码
#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

c 复制代码
#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之间三的倍数的和
c 复制代码
#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;
}

或者优化一下:

c 复制代码
#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

语法形式

c 复制代码
do
	语句;
while(表达式);

特征:循环体至少被执行一次

执行流程

  • 练习1:用do-while打印1~10的值
c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	int i = 1;
	do
	{
		printf("%d ", i);
		i++;
	} while (i <= 10);
	return 0;
}
  • 练习2:输入一个正整数,计算一下这个数是几位数
c 复制代码
#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语句

在循环执行的过程中,如果某些状况发生的时候,需要提前终止循环,这就需要breakcontinue 两个关键字

break 的作用是用于永久的终止循环,只要break 被执行,直接就会跳出循环,继续往后执行

continue 的作用是跳过本次循环中continue 后边的代码,在 for 循环和 while循环中有所差异的

while循环中的break和continue

while:

c 复制代码
#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;
}

输出结果为:

c 复制代码
#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:

c 复制代码
#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;
}

输出结果为:

c 复制代码
#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循环的代码变为这样:

c 复制代码
#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

c 复制代码
#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;
}

输出结果如下:

c 复制代码
#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;
}

输出结果仍为死循环

  • 练习:判断下面代码的输出
c 复制代码
#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是素数
c 复制代码
#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就是素数

故,代码可以优化为:

c 复制代码
#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:
c 复制代码
#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:
c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>//数学相关的头文件
int main() {
again:
	printf("hehe\n");
	goto again;
	return 0;
}

输出结果为:
hehe的死循环

代码中出现的goto语句太多的话,代码的执行流程就比较乱,可控性不高

但在多层循环的代码中,如果想快速跳出,goto就非常方便

c 复制代码
1 for(...)
{
	for(...)	
	{
		if(disaster)	
			goto error;	
	}	
}
 error;

for循环想提前退出得使用break,一个 break 只能跳出一层for循环,如果3层循环嵌套就得使用3个 break 才能跳出循环,所以此时使用goto语句就会更加的快捷

END ...

截至到这里,分支与循环就完事一半啦

已经很晚了,要早点休息喔~zzz

最后...

"我们不全是长篇小说,也不全是短篇故事,

最后的最后,我们成为一部人生作品集。"

相关推荐
Theodore_10222 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
----云烟----4 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024065 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it5 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康5 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神6 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
搬砖的小码农_Sky6 小时前
C语言:数组
c语言·数据结构
宅小海6 小时前
scala String
大数据·开发语言·scala