【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…...
AUTOSAR BSW里的“共享文件夹”:ECUC模块如何管理PDU路由与多核分区?
AUTOSAR BSW中的ECUC模块:多核与PDU路由的"中央调度站" 想象一下,在一个大型跨国企业的IT部门中,不同团队需要频繁交换文件,但又不希望直接访问彼此的服务器。这时候,一个设计精良的共享文件夹系统就成了必需…...
为AI编程助手加装安全层:Claw Gatekeeper风险分级与动态审批实践
1. 项目概述:为AI助手戴上“安全刹车”如果你和我一样,日常重度依赖像OpenClaw、Cursor、Claude Code这类AI编程助手,那你肯定体验过那种“冰火两重天”的感觉。一方面,它们能极大地提升效率,一个指令就能帮你重构代码…...
基于DETAMINtea的策略模拟器:从游戏平衡到AI决策的量化分析
1. 项目概述:一个基于DETAMINtea的怪物选择对战器最近在GitHub上看到一个挺有意思的项目,叫“DETAMINtea/monster-selection-battler”。光看名字,你可能会觉得这又是一个普通的游戏Demo或者对战模拟器。但当我真正点进去,花时间研…...
翰墨续千年 李体书法风华 20米长卷铸就当代临帖巅峰
近日,李体书法创始人李送文先生倾尽毕生书法造诣,沉淀数十年深耕底蕴,日夜凝神潜心淬炼,倾力创作二十米恢弘《九成宫醴泉铭》巨幅临帖长卷,以超凡笔墨风骨传承盛唐经典,以独树一帜书韵惊艳当代书坛。泱泱华…...
论文AI率达标指南:亲测5款实用降AI工具,高效消除AIGC痕迹
每到毕业季,不少同学都会收到导师的同款提醒:“你这篇论文AIGC率太高了,拿回去重改。”但“太高”到底是指多少?不同院校的要求天差地别,不同检测系统的结果也各不相同:有的学校要求AI率不超过30%才算合格&…...
AISMM模型能否救活你的创新 pipeline?5分钟自测当前成熟度等级,超86%团队卡在Level 2.4→2.5死区
更多请点击: https://intelliparadigm.com 第一章:AISMM模型与产品创新能力 AISMM(Artificial Intelligence-enabled Software Maturity Model)是一种面向AI原生产品的成熟度评估框架,聚焦于将大模型能力深度融入软件…...
基于vLLM与FastAPI构建高效LLM推理服务:从量化部署到生产优化
1. 项目概述与核心价值如果你正在尝试将开源的大语言模型(LLM)部署到自己的服务器上,并且对“推理速度慢”、“显存爆炸”、“部署流程复杂”这几个词深有体会,那么你很可能已经听说过或者正在寻找像titanml/takeoff-community这样…...
基于向量数据库与语义检索的AI记忆增强工具Memok-AI深度解析
1. 项目概述:一个面向记忆增强的AI工具最近在GitHub上闲逛,发现了一个挺有意思的项目,叫galaxy8691/memok-ai。乍一看这个名字,memok很容易让人联想到 “Memory” 和 “OK” 的组合,直译过来就是“记忆没问题”。点进去…...
智能体框架agentsrc-py:从核心架构到生产部署的完整指南
1. 项目概述:一个面向开发者的智能体构建框架最近在GitHub上闲逛,发现了一个挺有意思的项目,叫agentsrc-py。这个项目名听起来就很有指向性,agentsrc直译过来就是“智能体源代码”,后缀-py明确指向Python。简单来说&am…...
CSharpier代码生成器揭秘:自动生成语法节点打印器的实现原理
CSharpier代码生成器揭秘:自动生成语法节点打印器的实现原理 【免费下载链接】csharpier CSharpier is an opinionated code formatter for c#. 项目地址: https://gitcode.com/gh_mirrors/cs/csharpier CSharpier是一款针对C#的代码格式化工具,它…...
