【C语言】分支与循环(循环篇)——结尾猜数字游戏实现

前言

C语言是一种结构化的计算机语言,这里指的通常是顺序结构、选择结构、循环结构,掌握这三种结构之后我们就可以解决大多数问题。

分支结构可以使用ifswitch来实现,而循环可以使用forwhiledo 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语言中提供了breakcontinue两个关键字:

  • 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. 自动生成1~100的随机数
  2. 根据玩家猜的数字电脑给出大了或者小了的反馈,直到正确。
//打印开始界面
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()函数

  1. 首先进入main函数,因为游戏一开始就要打印一个菜单,所以我们使用do while循环,do while的特点就是第一次直接进入循环语句。
  2. 先打印菜单,然后使用scnaf让玩家输入,根据玩家输入的值选择switch的分支语句,如果输入 1 就进入case1语句,开始游戏;选择 0 那么就提醒玩家退出游戏,接着break跳出,如果输入非 01 的数字就走default语句提示重新选择。
  3. 使用input做为循环条件是因为,如果玩家输入 1 进入游戏之后,无论输赢导致游戏结束,都会再让玩家选择一次,也就是再打印一次菜单,再scanf输入选择,避免了游戏结束直接退出程序。而玩家输入0的话,整个循环也就随着停止,及退出游戏,如果输入其他的,只要是大于0就会提示重新选择,然后再次循环。

6.3.2 game()函数

  1. 如果玩家选择了1进入游戏主体,首先生成一个1~100的随机数并赋值给r
  2. 创建一个num变量用于玩家输入,并且因为猜数字很难一次猜对,所以输入的动作我们也放在循环里。
  3. while循环让他一直循环,内部就是一个比较的过程,根据玩家输入的数字走不通的分支并进行提示,直到猜对之后break跳出循环。

6.4 运行结果

在这里插入图片描述

  • 31
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值