【C语言】分支与循环(循环篇)——结尾猜数字游戏实现
前言
C语言是一种结构化的计算机语言,这里指的通常是顺序结构、选择结构、循环结构,掌握这三种结构之后我们就可以解决大多数问题。
分支结构可以使用if、switch来实现,而循环可以使用for、while、do while来实现。
1. while循环
C语言中提供了三种循环语句,while就是其中一种。
1.1 while 与 if 的对比
while的语法:
while(表达式)语句;
具体我们可以通过与if语句对比一下来观察:
//代码1
int main()
{if(1)printf("hello\n");return 0;
}
int main()
{while(1)printf("hello\n");return 0;
}
通过运行我们可以发现,if语句只能执行一次后面的打印语句,而while循环可以一直打印。
1.2 while语句的执行流程

首先执行判断表达式,如果表达式值为0(为假),循环直接结束;表达式的值不为0(为真),则执行循环语句,语句执行后再继续进行判断。
1.3 while循环实践
比如:循环打印1~10的值
int main()
{int i = 1;while (i <= 10){printf("%d ", i);i++;}return 0;
}

2. for循环
通常for循环是循环中使用最多的,语法如下:
2.1 语法形式
for(表达式1; 表达式2; 表达式3)语句;
在这里表达式1用于初始化循环变量,表达式2用于循环结束条件的判断,表达式3用于循环变量的调整。
2.2 执行流程

进入循环首先执行表达式1初始化循环变量,然后执行表达式2进行判断,如果表达式2的结果为0,则 循环结束;表达式2不为0则执行循环语句,执行完成后,再执行表达式3调整循环变量,然后再进行表达式2判断。
整个循环中,表达式1的初始化部分只执行1次,接下来就是表达式2、循环语句、表达式3在循环。
2.3 for循环实践
还是以打印1~10的值为例:
int main()
{int i = 1;for (i = 1; i <= 10; i++){printf("%d ", i);}return 0;
}

3. do-while循环
3.1语法形式
一般do while循环使用的语句比较少,它的语法如下:
do语句;
while(表达式);
while 循环for循环都是先判断再进入循环,而do while循环是先进入循环体执行循环语句,再执行while后的判断表达式,表达式为真就进行下一次循环,为假则跳出不再循环。
3.2 执行流程

3.3 do while 循环的实践
这里我们还是以打印1~10的值为例:
int main()
{int i = 1;do{printf("%d ", i);i++;} while (i <= 10);return 0;
}

4. break和continue语句
在执行循环的时候,我们经常会遇到某些情况需要提前终止循环,而在C语言中提供了break和continue两个关键字:
break的作用是永久终止循环,只要break执行,那么就会直接跳出循环,执行当前循环外的语句。continue的作用是跳过本次循环continue后边的代码,进行下一轮循环。
4.1 while循环中的break和continue语句
4.1.1 break举例
int main()
{int i = 1;while (i <= 10){if (i == 8)break;printf("%d ", i);i++;}return 0;
}
这时我们再来看看结果:

这里我们可以看到,只打印到了7就停止了,这是因为i在等于8的时候就执行了break语句,直接跳出了整个循环,所以只打印到了7就停止。
4.1.2 continue举例
int main()
{int i = 1;while (i <= 10){if (i == 8)continue;printf("%d ", i);i++;}return 0;
}
在这段代码中的结果是会造成死循环,因为continue的特点是跳过当次循环后的代码,所以当 i 循环一直到值为 8 的时候,就会跳过后面的 printf 和 i++ 语句,导致 i 的值一直为 8 ,造成程序死循环,所以要避免将 continue 放在调整语句之前。
4.2 for循环中的break和continue
4.2.1 break举例
和 while 循环一样, for 循环中的 break 也是用于终止循环,只要执行到了break循环就彻底终止:
int main()
{int i = 0;for (int i = 1; i <= 10; i++){if (i == 8)break;printf("%d ", i);}return 0;
}

所以当 i 等于 8 的时候,break执行,跳出循环,结果打印1~7。
4.2.2 continue举例
如果把上面的代码中的break换成continue会什么结果:
int main()
{int i = 0;for (int i = 1; i <= 10; i++){if (i == 8)continue;printf("%d ", i);}return 0;
}

这里打印了1~10,但是没有打印8,这是因为当 i == 8 的时候, continue执行跳过了打印的语句,但是调整语句 i++ 在continue之前,所以 i 继续自增,变成 9, 不满足 if 语句,跳过continue,继续执行printf语句,所以结果没有打印 8。
4.3 do while循环中的break和continue语句
do while 语句中的break和continue作用与 while 循环中几乎一样,这里不再叙述。
5. goto语句
C语言中还提供了一种方法,就是goto语句和跳转标号,它可以实现在同一个函数内跳转到设置好的标号处。
比如:
int main()
{printf("hello\n");goto next;printf("world\n");next:printf("跳过了world的打印\n");return 0;
}

goto语句如果使用不好就会导致在函数内乱跳转;但也并非全是缺点,如果在多层循环代码中想要快速跳出,那么使用goto就会很方便:
for(...)
{for(...){for(...){if(表达式)goto next;}}
}
next:
如果我们使用break的话,一次只能跳出一层循环,想全部跳出需要3个break,但使用goto的话,满足条件直接跳出所有循环,就会更加快捷。
6. 猜数字游戏
当我们了解了分支与循环的结构之后,就可以尝试着写一个猜数字的小游戏,在控制台展示出来:
不过,在写之前我们还要先了解几个函数,因为在游戏里我们会用到它们:
6.1 rand、srand、time函数与随机数
6.1.1 rand函数
在写程序的时候,有很多时候需要用到随机数,于是我们就可以使用rand函数。如下所示:
int rand(void);
注:在使用rand函数时需要包含头文件
#include <stdlib.h>
但通过程序多试几次发现,rand函数实际上生成的是一个伪随机数,每次生成的数字都是一样的:
第一次:

第二次:

伪随机数并不是真的随机数,而rand函数生成的是基于一个叫种子的基准值进行运算从而生成的随机数。
之所以每次生成的随机数都是一样的,是因为种子的默认值为“1”。
如果想生成真正的随机数,那么就需要种子是一直变化的。
6.1.2 srand函数
C语言中又提供了一个函数叫srand,是用来初始化随机数生成器的。
void srand(unsigned int seed);
在调用rand函数前先调用srand函数,用过srand的参数设置rand函数的种子,这样每次生成的随机数就会变化。
6.1.3 time函数
而一般在写程序的时候,大多数时候都会使用时间做为种子,因为时间是一直在变化的。
在C语言中有一个函数叫time,可以返回当前的时间:
time_t time (time_t* timer);
使用time函数需要包含头文件:
#include <time.h>
如果只用time函数返回时间戳,那就可以写成:
time(NULL);
6.1.4 生成随机数
了解了这些这时就可以把代码改下:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>int main()
{srand((unsigned int)time(NULL));printf("%d\n", rand());printf("%d\n", rand());printf("%d\n", rand());printf("%d\n", rand());printf("%d\n", rand());return 0;
}
这时再看得到的结果:
第一次:

第二次:

这时得到的就是真正的随机数。
6.2 代码实现
游戏要求:
- 自动生成1~100的随机数
- 根据玩家猜的数字电脑给出大了或者小了的反馈,直到正确。
//打印开始界面
void menu()
{printf("************************\n");printf("*******猜数字游戏********\n");printf("*********1.开始*********\n");printf("*********0.退出*********\n");printf("************************\n");
}//游戏主体
void game()
{//生成随机数,设定范围1~100以内int r = rand() % 100 + 1;//玩家要猜的数字int num = 0;while (1){printf("请猜数字:");scanf("%d", &num);if (num > r){printf("猜大了\n");}else if (num < r){printf("猜小了\n");}else{printf("恭喜你,猜对了!\n");break;}}
}int main()
{//用于选择开始游戏、退出游戏int input = 0;//设置种子,为了后面调用rand函数srand((unsigned int)time(NULL));do{//打印界面(封装为menu函数)menu();printf("请选择:");scanf("%d", &input);//根据玩家的输入来选择分支switch(input){case 1://游戏主体(封装为game函数)game();break;case 0:printf("退出游戏\n");break;default://对于输入0和1之外的处理printf("选择错误,请重新选择\n");break;}} while (input);return 0;
}
6.3 逻辑分析
6.3.1 main()函数
- 首先进入
main函数,因为游戏一开始就要打印一个菜单,所以我们使用do while循环,do while的特点就是第一次直接进入循环语句。 - 先打印菜单,然后使用
scnaf让玩家输入,根据玩家输入的值选择switch的分支语句,如果输入 1 就进入case1语句,开始游戏;选择 0 那么就提醒玩家退出游戏,接着break跳出,如果输入非 0 和 1 的数字就走default语句提示重新选择。 - 使用
input做为循环条件是因为,如果玩家输入 1 进入游戏之后,无论输赢导致游戏结束,都会再让玩家选择一次,也就是再打印一次菜单,再scanf输入选择,避免了游戏结束直接退出程序。而玩家输入0的话,整个循环也就随着停止,及退出游戏,如果输入其他的,只要是大于0就会提示重新选择,然后再次循环。
6.3.2 game()函数
- 如果玩家选择了1进入游戏主体,首先生成一个1~100的随机数并赋值给
r - 创建一个
num变量用于玩家输入,并且因为猜数字很难一次猜对,所以输入的动作我们也放在循环里。 while循环让他一直循环,内部就是一个比较的过程,根据玩家输入的数字走不通的分支并进行提示,直到猜对之后break跳出循环。
6.4 运行结果

相关文章:
【C语言】分支与循环(循环篇)——结尾猜数字游戏实现
前言 C语言是一种结构化的计算机语言,这里指的通常是顺序结构、选择结构、循环结构,掌握这三种结构之后我们就可以解决大多数问题。 分支结构可以使用if、switch来实现,而循环可以使用for、while、do while来实现。 1. while循环 C语言中…...
【数据结构】链表篇
文章目录 1.链表的概念以及结构2.链表的分类2.1 单向或者双向2.2 带头或者不带头2.3 循环或者不循环2.4 无头单向非循环链表和带头双向循环链表 3.单链表的实现3.1 准备工作3.2 节点的创建3.3 单链表的释放3.4 打印链表3.5 单链表的尾插3.6 单链表的尾删3.7 单链表头删3.8 单链…...
Python SciPy介绍
在数据科学和工程领域,Python已经成为了一个不可或缺的工具,这主要得益于其强大的库和框架支持。其中,SciPy库作为Python科学计算的核心库之一,为研究人员、工程师和数据分析师提供了大量高效的算法和数学工具。本文将带您深入了解…...
docker镜像源
1、直接在服务器上创建这个文件,将镜像源配置在里面 /etc/docker/daemon.json {"registry-mirrors": ["https://do.nark.eu.org","https://dc.j8.work","https://docker.m.daocloud.io","https://dockerproxy.com&qu…...
【clion】clion打开文件目录卡死问题
巨卡,几乎无法打开,据说是fsnotifier64.exe 被限制了。删除 火绒就好了。 关闭windows defender 官方:关闭 Windows 安全中心中的Defender 防病毒保护 此时,删除火绒: 界面变这样了:...
[CR]厚云填补_GridFormer
GridFormer: Residual Dense Transformer with Grid Structure for Image Restoration in Adverse Weather Conditions Abstract 恶劣天气条件下的图像恢复是计算机视觉中的一个难点。在本文中,我们提出了一种新的基于变压器的框架GridFormer,它可以作为…...
PostgreSQL数据库内核(二):通过initdb传递guc参数
目录 增加guc参数 initdb参数传递 pg_ctl参数传递 参数验证 新增guc参数pg_test_parameter,支持从initdb和pg_ctl命令中传递/覆盖参数,使用场景是TDE透明加密指定算法或者某些定制化需求。 增加guc参数 pg源码是这样描述guc参数的:它是全局…...
rust常用的宏使用记录(九)
matches! 宏使用 matches! 是 Rust 标准库中一个非常有用的宏,它允许你方便地匹配一个表达式的结果是否符合某个模式。它的基本用法如下:matches!(expression, pattern) 这个宏返回一个布尔值,如果 expression 匹配 pattern,则返回…...
【Python机器学习】支持向量机——手写数字识别问题
基于SVM的数字识别步骤: 1、收集数据:提供的文本文件 2、准备数据:基于二值图像构造向量 3、分析数据:对图像向量进行目测 4、训练算法:采用两种不同的核函数,并对径向基核函数采用不同的设置来运行SMO算法…...
学习笔记-Cookie、Session、JWT
目录 一、验证码的生成与校验 1. 创建生成验证码的工具类 2. 写一个 Controller 3. 实现验证码验证 1. 获取验证码 2. 验证码请求过程 3. 验证码的校验 4. 原理说明 5. 验证 6. 总结 二、JWT登录鉴权 1. 为什么要做登录鉴权? 2. 什么是 JWT 3. JWT相比…...
题海战术,面试必胜秘诀
目录 1.Java 的优势是什么?2.什么是 Java 的多态特性?3.Java 中的参数传递是按值还是按引用?4.为什么 Java 不支持多重继承?5.什么是 Java 中的不可变类?总结 题目 来自面试鸭刷题神器 1.Java 的优势是什么? Java 的跨平台性、垃圾回收机制以及其强…...
设计模式详解(十九)——命令模式
命令模式简介 命令模式定义 命令模式(Command Pattern)是一种在面向对象程序设计中常用的行为型设计模式。命令模式的核心思想在于将请求封装成一个对象,从而使发出请求的责任和执行请求的责任分割开。它可以让请求发送者和请求接收者之间消…...
实战:MySQL数据同步神器之Canal
1.概叙 场景一:数据增量实时同步 项目中业务数据量比较大,每类业务表都达到千万级别,虽然做了分库分表,每张表数据控制在300W以下,但是效率还是达不到要求,为了提高查询效率,打算使用ES进行数…...
5.6软件工程-运维
运维 系统转换系统维护系统评价练习题 系统转换 新老系统的转换 系统转换是指:新系统开发完毕,投入运行,取代现有系统的过程,需要考虑多方面的问题,以实现与老系统的交接,有一下三种转换计划: …...
在JavaScript中如何确保构造函数只被new调用
构造函数是一个特殊的函数,用于初始化一个新创建的对象。它是在创建对象时自动调用的。构造函数通常用于为对象的属性赋值,或者执行其他必要的设置。 使用函数名大写字母开头,这是一种命名约定,用于区分构造函数和普通函数。如何…...
【数据结构算法经典题目刨析(c语言)】反转链表(图文详解)
💓 博客主页:C-SDN花园GGbond ⏩ 文章专栏:数据结构经典题目刨析(c语言) 目录 一、题目描述 二、思路分析 三、代码实现 一、题目描述: 二、思路分析 : 通过三个指针n1,n2,n3来实现链表的反转 1.首先初始化 n1为…...
机器学习之争:Python vs R,谁更胜一筹?
一、引言 随着人工智能和大数据的迅速发展,机器学习已成为现代科技的重要组成部分。在医疗、金融、零售、制造等多个领域,机器学习技术的应用无处不在。从数据分析到预测建模,再到深度学习,机器学习正在改变我们的工作和生活方式…...
Vulnhub靶机:JANGOW_ 1.0.1
目录 前言: 一、安装虚拟机Jangow:1.0.1靶机 二、Web部分 前言: 难度:简单,本文使用VirtualBox打开,下载地址: https://download.vulnhub.com/jangow/jangow-01-1.0.1.ova 一、安装虚拟机J…...
Python脚本实现USB自动复制文件
USB驱动器作为常见的数据存储设备,经常用于数据传输和备份。 然而,我们在手动处理文件复制可能效率低下且容易出错。 因此,我们可以利用Python编写脚本来自动化这一过程,提高效率和数据安全性。 准备工作 首先,我们需…...
【C++学习第19天】最小生成树(对应无向图)
一、最小生成树 二、代码 1、Prim算法 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 510, INF 0x3f3f3f3f;int n, m; int g[N][N]; int dist[N]; bool st[N];int prim() {memset(dist, 0x3f, sizeof di…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
