4.C语言分支和循环(下)猜数字

我们来写个简单的小游戏:猜数字
先看流程图(建议放大)
在这里插入图片描述

首先,我们要了解怎么用代码生成随机数,并且约束随机数生成的范围

1.怎么生成随机数

了解之前,我们需要知道一些知识背景;
rand函数:返回一个伪随机数,该随机数范围:0~RAND_MAX(RAND_MAX大小依赖编译器实现,但大部分编译器上RAND_MAX是32767)
使用rand函数需要包含一个头文件:stdlib.h
先看该函数原型:

int rand(void);

然后,我们打印出rand函数生成的随机值,看看是不是每次生成都有所区别

#include<stdio.h>
#include<stdlib.h>
int main()
{
    printf("%d\n",rand());
    printf("%d\n",rand());
    printf("%d\n",rand());
    printf("%d\n",rand()); 
    printf("%d\n",rand());
            return 0;
}

我们生成两次,发现结果都一样。说明这随机序列没有随机嘛!

在这里插入图片描述
问题在这里:rand 函数生成的是伪随机数,伪随机数不是真正的随机数。

那为什么两次生成随机数序列一样呢:rand函数是对⼀个叫“种⼦”的基准值进⾏运算,然后⽣成的随机数。⽣成随机数的默认种⼦是1,所以每次运⾏程序产⽣的随机数序列是⼀样的。
如果要⽣成不同的随机数,就要让种⼦是变化的。

所以,看第二个函数:srand函数
srand原型:

void srand(unsigned int seed);

通过 srand 函数的参数seed来设置rand函数⽣成随机数的时候的种⼦。
种子在变化,则生成的随机数序列才变化。
给srand的种⼦是如果是随机的,rand就能⽣成随机数;
在⽣成随机数的时候⼜需要⼀个随机数,这就⽭盾了。

所以,看第三个函数time:程序中我们⼀般是使⽤程序运⾏的时间作为种⼦的,因为时间时刻在发⽣变化的。
time原型:

time_t time (time_t* timer);

time函数其实返回的是1970年1月1日0时0分0秒到现在程序运行时间之间的差值,单位是秒。
返回的差值类型是time_t,time_t 类型本质上其实就是32位或者64位的整型类为后面为什么要强制类型转换铺垫)。
time函数使用时需要包含头文件:time.h
我们用everything搜索time.h,可以发现time.h整型类型
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
从time_t time (time_t* timer);可知time函数的参数是timer。
如果timer是非NULL指针,函数返回时间差值同时,也会将返回的差值放在timer指向的内存中带回去。
如果timer是NULL(空),就只返回时间的差值,这个时间差也叫:时间戳
举例:只返回时间戳(差值),不接收返回值

time(NULL);//调用函数返回时间戳(差值),这里没有接受返回值

所以我们将代码改成:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
    srand((unsigned int)time(NULL));
    //因为srand函数是unsigned int类型,所以time函数返回值要强制类型转换
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    return 0;
}

在这里插入图片描述
在这里插入图片描述
两次运行结果不一样。随机数序列随机了!!
注意:srand函数不需要频繁调用,一次运行程序调用一次就够了。

2.设置随机数范围

接下来,设置随机数范围。
1.表示范围0~99
(%100余数是0~99)

rand()%100;
//0+rand()%(99-0+1);

2.表示范围1~100(余数)
(%100余数范围+1)

1+rand()%100;
//1+rand()%(100-1+1);

3.表示范围100~200(余数)
(%101余数范围(0~100)+100)

100+rand()%101;
//100+rand()%(200-100+1);

4.总结:表示范围a~b的随机数

a+rand()%(b-a+1);

3.实现游戏

再放大看一遍流程图的思路,实现猜数字游戏:(加上猜数字的次数限制,如果5次猜不出来,就算失败)
在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

void game()
{
	int r = rand() % 100 + 1;
	int guess = 0;
	int count = 5;
	while (count)
	{
		printf("请输入数字:>");
		scanf("%d", &guess);
		count--;
		if (guess < r)
		{
			printf("猜小了\n");
		}
		else if (guess > r)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,猜对了!\n");
			break;
		}
	}
	if (count == 0)
	{
		printf("你失败了,正确数字是:%d\n", r);
	}
}
void menu()
{
	printf("***********************\n");
	printf("******  1.play   ******\n");
	printf("******  0.exit   ******\n");
	printf("***********************\n");
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("游戏结束了\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

在这里插入图片描述
若有补充地方,后续会更新。
如果有发现不足,望各位指正,谢谢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值