学会随机数,与憨憨电脑互动

目录

1.前言

2.随机数生成函数:int rand(void)

2.1函数简介

2.2控制随机数的范围

2.3种子及其设置方法

2.3.1种子的作用

2.3.2种子的设置方法

2.4 time(NULL)获取时间戳

3.总结


 

1.前言

码接上回:三子棋逻辑的基本搭建

https://mp.csdn.net/mp_blog/creation/editor/128704393

为了让下篇“三子棋自定义函数的实现”的行文节奏更紧凑,这里先插叙一个小知识点:随机数的创建

假想我们已经实现了玩家下棋的功能,三子棋双人版这时候也就可以发布了,但考虑到一部分群体的需求,我们想再设计一个人机对战版,我们玩家下棋好办,键入两个数字表示坐标就好,但怎么让电脑自己选择两个数字呢?难不成是这样:)

printf("电脑,请选择两个不大于3的非零正整数:");

电脑内心os:哈 哈 !憨 憨 说 的 就 是 你 吧 !哈 哈 哈:)

2.随机数生成函数:int rand(void)

2.1函数简介

其实C语言的库函数里有个叫rand()的函数,它可以实现随机生成数字的功能,函数参数为void,函数返回值是一个根据种子生成的随机数(种子是什么,后面会给解释)头文件是<stdlib.h>

补充说明:rand()函数返回的随机数的范围是 0 到 RAND_MAX 之间,RAND_MAX 是一个常量,它的默认值在不同的环境中会有所不同,但是它的值至少是 32767。

77c0a3894c9440fa80f48eb2ed9c0126.png

example:

#include <stdlib.h>
#include <stdio.h>
int main()
{
	printf("随机数:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand());
	}
	return 0;
}

84ff5078c6ff41d8b8358980b5ebb9c2.png

2.2控制随机数的范围

有的老铁可能想问:“这个随机数的范围太广了,能不能给它限制一个范围?比如:1到10?”

这是个好想法,这时候就要用到神奇的取余符号:%,当 左操作数 % 右操作数 时,得到的值的范围就是 小于右操作数的正整数(包括0) 让我们看看效果:

#include <stdlib.h>
#include <stdio.h>
int main()
{
	printf("随机数:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand()%10);
	}
	return 0;
}

9be3a11a25c54583b58e22b90bd72b32.png

 good!生成的都是个位数,后面再 +1 即可将范围控制在 1 到 10 之间了。

2.3种子及其设置方法

2.3.1种子的作用

细心的老铁可能发现了:“怎么两次生成的随机数的个位都一样啊?那如果跟电脑下三子棋,它每次不都是一样的套路吗?”

good!你就是再世美猴王 吧!!!(火眼金睛的你再次发问:“你为什么要把 王 和 吧 两个字分开?!!” 我说:你轻声连贯地读几遍“美猴 王吧”就清楚了:)

咳咳......回到正题,两波生成的随机数其实不只是个位相同,它们是完全相同的!!!不信的话,你再运行几遍就明白了,这是因为rand()函数的种子一直都是默认的初始值,生成的随机数自然也是一样的了,设置不同的种子,计算机就会让rand()就会返回不同系列的数字。

2.3.2种子的设置方法

1.void srand(unsigned int seed)

一个种子设置函数(种子就是一个unsigned int型的数)头文件和rand()一样是<stdlib.h>,无返回值,函数参数是无符号整型,也即种子。

aed37fef55ba48bb9c94907609390724.png

example:

#include <stdlib.h>
#include <stdio.h>
int main()
{
	srand(1);
	printf("随机数1:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand());
	}

	srand(2);
	printf("\n随机数2:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand());
	}
	return 0;
}

0041c47ac3a64196a1f911bf33db03eb.png

 2.我们也可以在rand()函数的括号里设置它的种子:

#include <stdlib.h>
#include <stdio.h>
int main()
{
	printf("随机数1:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand(1));
	}
	printf("\n随机数2:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand(2));
	}
	return 0;
}

 

da578f87855f4ae9bd1f8e114aeeb3c9.png

通过设置不同的种子,电脑在下三子棋的时候就能使用不同的套路了,可是,每次种子的输入都是要我们人为输入,是不是感觉有点不对味,这随机数,随机地不够纯粹啊!还得人为输入,多麻烦啊!有没有一种一直变化的无符号整型数或者变量啊?

有“聪明”的小伙伴可能想到了:“用rand()做种子不就行了吗:)”呃呃,虽然不管用,但冲你看文章时还有在思考的行为点个赞,那为什么不管用呢?因为你这样做,每次重新运行时,种子是按一套固定的套路变化的,那么生成随机数的规律不也是一摸一样的?

那怎么办呢?其实,是有一直变化的无符号整型数的,它叫时间戳。

2.4 time(NULL)获取时间戳

time(NULL)的返回值就是时间戳,时间戳是一个无符号整型数,其大小是格林威治时间自1970年1月1日(00:00:00 GMT)至当前时间的总秒数,所以每过一秒它的值就会改变,将time(NULL)设置为种子,这样每一次随机数生成的种子都会是不一样的,也就无规律可言了,随机数也就实现了真正意义上的随机了。

time()函数的头文件是<time.h>,函数参数为NULL时返回的是时间戳:

d1856b6636944ebca5ba914e6f146760.png

example:

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

int main()
{
	srand((unsigned int)time(NULL));//虽然不进行类型转换也不会报错,但这里建议强制类型转化一下,让实参和形参的类型统一,养成良好的代码风格,代码的bug也就会少很多
	printf("随机数1:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand());
	}

	printf("\n随机数2:");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", rand());
	}
	return 0;
}

3.总结

创建随机数用int rand(void)函数,随机数的创建规律与种子有关,种子是一个无符号整型数,种子的设置可使用void srand(unsigned int seed)函数,要想每分每秒都设置不同的种子,用time (NULL)获取时间戳当种子即可。

文章到这里就结束了,如有错误之处,欢迎在评论区中指出,让我们一起学习!共同进步!

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值