初阶 《分支和循环语句》 3.循环语句

3.循环语句

while
for
do while

3.1 while循环

前面已经掌握了 if 语句

if(条件)
  语句;

当条件满足的情况下,if语句后的语句执行,否则不执行;但是这个语句只会执行一次。
由于我们发现生活中很多的实际的例子是:同一件事情我们需要完成很多次。那我们怎么做呢?
C语言中给我们引入了: while 语句,可以实现循环。
while 语法结构

while (表达式)
 循环语句;

例:

#include <stdio.h>
int main()
{
	while (1)
	{
		printf("小琪\n");//会无限打印 小琪
	}
	return 0;
}

while 语句执行流程:
在这里插入图片描述
比如我们实现:“在屏幕上打印1-10的数字

#include <stdio.h>
int main()
{
 int i = 1;
 while(i<=10)
 {
 printf("%d ", i);
 i = i+1;
 }
 return 0;
}

上面的代码已经帮我了解了 while 语句的基本语法

3.1.1 while语句中的break和continue

break介绍
#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
			break;
		printf("%d ", i);
		i++;
	}
	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		i++;
		if (5 == i)
			break;
		printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述
总结:
break在while循环中的作用:

在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。
while中的break是用于永久终止循环的。

continue介绍
#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		if (5 == i)
			continue;
		printf("%d ", i);//打印 1 2 3 4 死循环
		i++;
	}
	return 0;
}
#include <stdio.h>
int main()
{
	int i = 1;
	while (i <= 10)
	{
		i++;
		if (5 == i)
			continue;
		printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述
总结:
continue在while循环中的作用就是:

continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分,进行下一次循环的入口判断。

3.1.2 练习

例:

#include <stdio.h>
int main()
{
	int ch = getchar();
	printf("%c\n", ch);
	putchar(ch);
	return 0;
}

输入q                   回车
在这里插入图片描述

#include <stdio.h>
int main()
{
	int ch = 0;
	while ((ch = getchar()) != EOF)//end of file
	{
		putchar(ch);//CTRL+Z+回车-->终止
	}
	return 0;
}

在这里插入图片描述
例:假设密码是一个字符串

#include <stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");//假设密码是123456
	scanf("%s", password);
	printf("前请确认密码(Y/N):>");//无论密码输入什么都会直接打印No,因为密码后面有个\n,被ret读取了
	int ret = getchar();
	if ('Y' == ret)
	{
		printf("Yes\n");
	}
	else
	{
		printf("No\n");
	}
	return 0;
}

在这里插入图片描述
验证有个\n

#include <stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	printf("前请确认密码(Y/N):>");
	int ret = getchar();
	if ('\n' == ret)
	{
		printf("Yes\n");
	}
	else
	{
		printf("No\n");
	}
	return 0;
}

在这里插入图片描述
解决办法:

#include <stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	getchar();//读取了\n
	printf("前请确认密码(y/n):>");
	int ret = getchar();
	if ('y' == ret)
	{
		printf("yes\n");
	}
	else
	{
		printf("no\n");
	}
	return 0;
}

上个代码虽然正常了,但是密码中有空格,又会直接打印no
假设密码为123456 789
打印结果:
在这里插入图片描述
解决办法:

#include <stdio.h>
int main()
{
	char password[20] = { 0 };
	printf("请输入密码:>");
	scanf("%s", password);
	int ch = 0;
	while ((ch = getchar()) != '\n')
	{
		;
	}
	printf("前请确认密码(Y/N):>");
	int ret = getchar();
	if ('Y' == ret)
	{
		printf("Yes\n");
	}
	else
	{
		printf("No\n");
	}
	return 0;
}

例:只打印数字字符,跳过其他字符

#include <stdio.h>
int main()
{
	char ch = '\0';
	while ((ch = getchar()) != EOF)
	{
		if (ch < '0' || ch>'9')
			continue;
		putchar(ch);//只打印数字字符
	}
	return 0;
}

3.2 for循环

3.2.1 语法

for(表达式1; 表达式2; 表达式3)
  循环语句;

表达式1
表达式1为初始化部分,用于初始化循环变量的。
表达式2
表达式2为条件判断部分,用于判断循环时候终止。
表达式3
表达式3为调整部分,用于循环条件的调整。
例:

使用 for循环 在屏幕上打印1-10的数字

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10 ; i++)
	{
		printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述
对比for循环和while循环:

int i = 0;
//实现相同的功能,使用while
i=1;//初始化部分
while(i<=10)//判断部分
{
 printf("hehe\n");
 i = i+1;//调整部分
}
//实现相同的功能,使用for
for(i=1; i<=10; i++)
{
 printf("hehe\n");
}

注:
可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较
远,这样查找修改就不够集中和方便。所以,for循环的风格更胜一筹;for循环使用的频率也最高。

3.2.2 for循环中的break和continue

break
#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			break;
		printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			break;
		printf("%d ", i);
		i = 12;
	}
	return 0;
}

在这里插入图片描述

continue
#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			continue;
		printf("%d ", i);
	}
	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 1; i <= 10; i++)
	{
		if (i == 5)
			continue;
		printf("%d ", i);
		i = 12;
	}
	return 0;
}

在这里插入图片描述

3.2.3 for语句的循环控制变量

建议:

  1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制
  2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法

代码1

//两边都是闭区间
for(i=0; i<=9; i++)
{}

代码2

//前闭后开的写法
for(i=0; i<10; i++)
{}

注:
1.两个代码同样是循环10次,但是代码2更加直观
2.但是只是建议写成左闭右开,具体要视情况而定
比如:打印200~300之间的数字

#include <stdio.h>
int main()
{
	int i = 0;
	for (i = 200; i <= 300; i++)
	{
		printf("%d ", i);
	}
	return 0;
}

3.2.4 一些for循环的变种

代码1

int main()
{
	int i = 0;
	//for循环的判断部分省略意味着判断会恒成立
	for (;;)
	{
		printf("灰灰\n");
	}
	return 0;
}

for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题

代码2

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	for (a = 0; a < 3; a++)
	{
		for (b = 0; b < 3; b++)
		{
			printf("灰灰\n");
		}
	}
}

在这里插入图片描述
代码3:如果省略掉初始化部分,这里打印多少个灰灰?

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	for (; a < 3; a++)
	{
		for (; b < 3; b++)
		{
			printf("灰灰\n");
		}
	}
}

在这里插入图片描述
解析:j所在的for循环中,j没有初始化。当i=0时,j所在的for循环 循环了3次,打印了3次“灰灰”,最终j=3。当i=2和3时,j仍然等于 3,无法进入循环

代码4:使用多余一个变量控制循环

#include <stdio.h>
int main()
{
	int x, y;
	for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
	{
		printf("灰灰\n");
	}
	return 0;
}

在这里插入图片描述
代码5

#include <stdio.h>
int main()
{
	for (int a = 1; a < 5; a++)//C99语法才支持这种写法;C++中支持这种写法
	{
		printf("灰灰\n");
	}
	return 0;
}

3.2.5 一道笔试题

例:请问循环要循环多少次?

#include <stdio.h>
int main()
{
 int i = 0;
 int k = 0;
 for(i =0,k=0; k=0; i++,k++)
        k++;
 return 0;
}

答案:0次

3.3 do…while()循环

3.3.1 do语句的语法:

do
 循环语句;
while(表达式);

3.3.2 do语句的特点

循环至少执行一次,使用的场景有限,所以不是经常使用

#include <stdio.h>
int main()
{
	int a = 1;
	do
	{
		printf("%d ", a);
		a++;
	}
		while (a <= 10);
	return 0;
}

在这里插入图片描述

注:若不加“a++”会无限循环

3.3.3 do while循环中的break和continue

break
#include <stdio.h>
int main()
{
	int a = 1;
	do
	{
		a++;
		if (a == 5)
			break;
		printf("%d ", a);
	}
		while (a <= 10);
	return 0;
}

在这里插入图片描述

#include <stdio.h>>
int main()
{
	int a = 1;
	do
	{
		if (a == 5)
			break;
		printf("%d ", a);
		a++;
	}
		while (a <= 10);
	return 0;
}

在这里插入图片描述

continue
#include <stdio.h>
int main()
{
	int a = 1;
	do
	{
		if (a == 5)
			continue;
		printf("%d ", a);//1234 死循环
		a++;
	}
		while (a <= 10);
	return 0;
}

在这里插入图片描述

#include <stdio.h>
int main()
{
	int a = 1;
	do
	{
		a++;
		if (a == 5)
			continue;
		printf("%d ", a);
	}
		while (a <= 10);
	return 0;
}

在这里插入图片描述

3.4 练习

1. 计算 n的阶乘
#include <stdio.h>
int main()
{
	int n = 0;
	int a = 1;
	int sum = 1;
	scanf("%d", &n);
	for (a = 1; a <= n; a++)
	{
		sum = sum * a;
	}
	printf("%d\n", sum);
	return 0;
}
2.计算 1!+2!+3!+……+10!

方法一

#include <stdio.h>
int main()
{
	int a = 0;
	int n = 0;
	int sum = 1;
	int add = 0;
	for (n = 1; n <= 10; n++)
	{
		sum = 1;
		for (a = 1; a <= n; a++)
		{
			sum = sum * a;
		}
		add = add + sum;
	}
	printf("%d\n", add);
	return 0;
}

方法二

#include <stdio.h>
int main()
{
	int add = 0;
	int sum = 1;
	int a = 0;
	int n = 0;
	for (a = 1; a <= 10; a++)
	{
		sum = sum * a;
		add = add + sum;
	}
	printf("%d\n", add);
	return 0;
}
3. 在一个有序数组中查找具体的某个数字n

二分查找法

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k =0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	scanf("%d", &k);
	for (i = 0; i < sz; i++)
	{
		if (arr[i] ==k)
		{
			printf("找到了,下标是:%d\n", i);
			break;
		}
	}
	if (i == sz)
	{
		printf("没找到\n");
	}
	return 0;
}

折半查找法

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
	int k = 0;
	scanf("%d", &k);
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		//int Mid = (left + right) / 2;
		int Mid = left + (right - left) / 2;
		if (arr[Mid] < k)
		{
			left = Mid + 1;
		}
		else if (arr[Mid] > k)
		{
			right = Mid - 1;
		}
		else
		{
			printf("找到了,下标是;%d\n", Mid);
			break;
		}
	}
	if (left > right)
	{
		printf("没找到\n");
	}
	return 0;
}
4. 编写代码,演示多个字符从两端移动,向中间汇聚
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
int main()
{
	char arr1[] = "Welcome to Beijing!";
	char arr2[] = "###################";
	int left = 0;
	int right = strlen(arr2) - 1;
	//int right = sizeof(arr1) / sizeof(arr1[0]) - 2;
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		Sleep(1000);//Sleep是库函数,头文件是<windows.h>
		//清空屏幕
		system("cls");//system是一个库函数,可以执行系统命令;头文件是<stdlib.h>
		left++;
		right--;
	}
	printf("%s\n", arr2);
	return 0;
}
5. 编写代码实现,模拟用户登录情景,并且只能登录三次(只允许输入三次密码,如果密码正确,则提示登录成功;如果三次均输入错误,则退出程序)
#include <stdio.h>
#include <string.h>
int main()
{
	int i = 0;
	char password[20] = { 0 };
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:>");
		scanf("%s", password);
		//假设密码为1213456
		//if(password=="123456")
		//比较2个字符串是否相等,不能使用==,而应该使用一个库函数:strcmp
		//如果返回值是0,表示2个字符串相等
		if (strcmp(password, "123456") == 0)
		{
			printf("登陆成功\n");
		}
		else
		{
			printf("密码错误\n");
		}
	}
	if (i == 3)
	{
		printf("三次密码均输入错误,推出程序\n");
	}
	return 0;
}
6.猜数字游戏实现(电脑产生一个1~100的随机数)
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void menu()
{
	printf("play(1)      exit(2)\n");
}
//0~RAND_MAX(32767)
void game()
{
	int guess = 0;
	int ret = rand()%100+1;//rand生成随机数的函数,产生一个1~100的随机数
	//printf("%d\n", ret);
	while (1)
	{
		printf("请猜数字\n");
		scanf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if(guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
		printf("猜对了\n");
		break;
		}
	}
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//printf("猜数字\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/695974.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MYSQL 索引下推 45讲

刘老师群里,看到一位小友 问<MYSQL 45讲>林晓斌的回答 大意是一个组合索引 (a,b,c) 条件 a > 5 and a <10 and b123, 这样的情况下是如何? 林老师给的回答是 A>5 ,然后下推B123 小友 问 "为什么不是先 进行范围查询,然后在索引下推 b123?" 然后就…

Leetcode 力扣114. 二叉树展开为链表 (抖音号:708231408)

给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。 示例 1&#xf…

欢乐打地鼠小游戏html源码

这是一款简单的js欢乐打地鼠游戏&#xff0c;挺好玩的&#xff0c;老鼠出来用鼠标点击锤它&#xff0c;击中老鼠获得一积分。 欢乐打地鼠小游戏html源码

不同数据库背后的数据存储方案

在大数据和AI时代&#xff0c;数据库成为各类应用不可或缺的重要组成部分。而数据库中的数据依赖存储引擎进行管理&#xff0c;包括数据的存储、查询、更新和删除等。因此&#xff0c;在设计系统时&#xff0c;选择正确的数据库存储引擎方案变得尤为重要。这篇文章将以关系型、…

滑动窗口算法:巧妙玩转数据的窗外世界

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一 滑动窗口是什么&#xff1f; 二 相关题目解析 1. 长度最小的子数组 &#x1f973;题目解析 &#x1f973;算法原理 ✏️思路1 暴力枚举出所有子数组之和 ✏️思路2 滑动窗…

LabVIEW调用DLL时需注意的问题

在LabVIEW中调用DLL&#xff08;动态链接库&#xff09;是实现与外部代码集成的一种强大方式&#xff0c;但也存在一些常见的陷阱和复杂性。本文将从参数传递、数据类型匹配、内存管理、线程安全、调试和错误处理等多个角度详细介绍LabVIEW调用DLL时需要注意的问题&#xff0c;…

有趣的数学 为什么绝对值和模都用两个竖线表示?

绝对值和模都可以使用两个竖线表示&#xff0c;是因为它们在数学概念上有相似的性质&#xff0c;不过是应用场景不同。 绝对值&#xff08;Absolute Value&#xff09;&#xff1a; 绝对值是一个实数的非负值。它表示一个数在数轴上距离原点的距离。例如&#xff0c; 和 。 模&…

Hadoop3:MapReduce源码解读之Map阶段的TextInputFormat切片机制(3)

Job那块的断点代码截图省略&#xff0c;直接进入切片逻辑 参考&#xff1a;Hadoop3&#xff1a;MapReduce源码解读之Map阶段的Job任务提交流程&#xff08;1&#xff09; 5、TextInputFormat源码解析 类的继承关系 它的内容比较少 重写了两个父类的方法 这里关心一下泛型参数…

基于Java+SpringBoot制作一个软考助手答题小程序

基于Java+SpringBoot制作一个软考小助手考试答题小程序。其中系统前端功能包括注册登录、公告通知、考试答题、视频课程、考试记录、题库、题目评论、错题统计、我的收藏和用户信息管理模块;系统后台功能包括用户管理、题库管理、答题管理、学习视频管理以及系统管理模块。 摘…

WINUI——Behavior(行为)小结

前言 在使用MVVM进行WINUI或WPF开发时&#xff0c;Command在某些时候并不能满足逻辑与UI分离的要求。这时肯定就需要其它技术的支持&#xff0c;Behavior就是一种。在WPF中是有Behavior直接支持的&#xff0c;转到WINUI后&#xff0c;相对有一些麻烦&#xff0c;于是在此记录之…

RainBond 制作应用并上架【以ElasticSearch为例】

文章目录 安装 ElasticSearch 集群第 1 步:添加组件第 2 步:查看组件第 3 步:访问组件制作 ElasticSearch 组件准备工作ElasticSearch 集群原理尝试 Helm 安装 ES 集群RainBond 制作 ES 思路源代码Dockerfiledocker-entrypoint.shelasticsearch.yml制作组件第 1 步:添加组件…

搭建RocketMQ主从异步集群

搭建RocketMQ主从异步集群 1、RocketMQ集群模式 为了追求更好的性能&#xff0c;RocketMQ的最佳实践方式都是在集群模式下完成的。RocketMQ官方提供了三种集群搭建方式&#xff1a; 2主2从异步通信方式&#xff1a;使用异步方式进行主从之间的数据复制。吞吐量大&#xff0c;…

通过 AI Edge Torch 生成式 API 在设备上使用自定义大语言模型

作者 / 首席工程师 Cormac Brick&#xff0c;软件工程师 Haoliang Zhang 我们很高兴地发布 AI Edge Torch 生成式 API&#xff0c;它能将开发者用 PyTorch 编写的高性能大语言模型 (LLM) 部署至 TensorFlow Lite (TFLite) 运行时&#xff0c;从而无缝地将新的设备端生成式 AI 模…

[大模型]Gemma-2B-Instruct FastApi 部署调用

环境准备 在 平台中租赁一个 3090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch-->2.1.0-->3.10(ubuntu22.04)-->12.1。 接下来打开刚刚租用服务器的 JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下载和运行演示。 pip 换源加速下载…

[qt] qt程序打包以及docker镜像打包

目录 一 环境准备: 1.1 qt环境 1.2 linuxdeplouqt打包工具 二 qt包发布: 2.1 搜索链接库 2.2 应用程序APP打包 2.3 发布 三 docker镜像包发布 3.1 环境准备 3.2 镜像生产脚本 3.3 加载镜像并运行docker容器 一 环境准备: qt环境linuxdeployqt打包工具docker环境 1…

Python学习打卡:day01

day1 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 1、Python 软件&#xff08;PyCharm&#xff09; 安装&#xff1a;在 Linux 环境下安装 Pycharm 插件&#xff1a;汉化、翻译 设置字体大小 常用快捷…

【MySQL】(基础篇五) —— 排序检索数据

排序检索数据 本章将讲授如何使用SELECT语句的ORDER BY子句&#xff0c;根据需要排序检索出的数据。 排序数据 还是使用上一节中的例子,查询employees表中的last_name字段 SELECT last_name FROM employees;输出结果&#xff1a; 发现其输出并没有特定的顺序。其实&#xf…

【Linux】进程3——PID/PPID,父进程,子进程

在讲父子进程之前&#xff0c;我们接着上面那篇继续讲 1.查看进程 mycode.c makefile 我们在zs_108直接编译mycode.c&#xff0c;直接运行&#xff0c;然后我们转换另一个账号来查看这个进程 我们可以通过ps指令来查看进程 我们就会好奇了&#xff0c;第二行是什么&#xff…

牛客热题:矩阵的最小路径和

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;矩阵的最小路径和题目链接方法一…

[数据集][目标检测]变电站火灾检测电力场景烟雾明火检测数据集VOC+YOLO格式140张2类别真实场景非PS合成

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;140 标注数量(xml文件个数)&#xff1a;140 标注数量(txt文件个数)&#xff1a;140 标注类别…