【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…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
