文章目录
- 一、 rand函数 – 产生一个伪随机数
- 1. 函数介绍
- 二、 srand函数
- 1.函数介绍
- 三、 time函数
- 1.函数介绍
- 四、rand函数简单应用
- 1.rand函数生成[a, b]范围内的数字
- 2. 猜数字游戏实现
一、 rand函数 – 产生一个伪随机数
1. 函数介绍
int rand (void);//使用时包含头文件#include
rand函数在使用的时候无需传参,调用该函数时它返回一个介于0和RAND_MAX(32767)之间的伪随机整数。
例如:我们用rand函数生成10个随机数。
#include #include int main(){for (int i = 0; i < 10; ++i){printf("%d ", rand());//每次rand函数返回的都是不同的数字}printf("\n");return 0;}
运行结果如下:
当我们重复运行上面的代码时,我们会发现,每次的运行结果都是一样的,这说明了这里的随机指的是,如果程序持续运行,rand返回不同的数字,而这里每次程序运行结果都是相同序列明显不相关的数字,并没有做到真正意义上的随机。这是因为rand函数生成的随机数是由一个算法生成的,该算法每次调用它时都会返回一系列明显不相关的数字。而该算法是使用不同种子来生成不同的序列,且序列使用函数srand初始化为一些不同种子。如果用rand函数之前并没有调用srand函数来初始化进去不同的种子,它就会默认为1为种子,来生成随机数序列。而我们上面的程序,就是没有用srand函数初始化不同的种子,它都默认1为种子来生成随机数序列,而相同种子生成的随机数序列是相同的,因此当我们重复运行上面的代码时,程序每次的运行结果都是一样的。接下来我们就来了解一下srand函数是如何用不同的种子来进行初始化的。
二、 srand函数
1.函数介绍
> void srand (unsigned int seed);//使用时包含头文件#include
srand函数是用来初始化随机数生成器,它只有一个参数,这个参数就是伪随机数生成器算法用作种子的整数值。
注意事项:
- 对于srand调用中使用的不同种子值,可以使得伪随机数生成器在随后的rand调用中生成不同的连续结果。
例如:用10作为种子和20作为种子生成随机。
#include #include int main(){srand(10);//10作为种子//srand(20);//20作为种子for (int i = 0; i < 10; ++i){printf("%d ", rand());//每次rand函数返回的都是不同的数字}printf("\n");return 0;}
10作为种子运行结果如下:
20作为种子运行结果如下:
从两次代码运行结果就可以验证这一说法。
- 如果调用srand函数并将seed设置为1,则生成器将被重新初始化为其初始值,则与没调用srand函数产生相同的值。
例如:用1作为种子调用srand和不调用srand。
#include #include int main(){srand(1);//1作为种子for (int i = 0; i < 10; ++i){printf("%d ", rand());//每次rand函数返回的都是不同的数字}printf("\n");return 0;}
运行结果如下:
把1作为种子调用srand函数生成的10个随机和上面没调用srand相比较(没调用sran函数时,种子也默认设置成1),我们不难发现两次生成的随机数是一模一样的。
- 使用相同种子来初始化随机数生成器将在对rand的后续调用中生成相同的连续结果。
从上面用1作为种子调用srand和不调用srand的例子我们可以看出相用同种子初始化随机数生成器,将产生相同的随机数序列,这里就不在举例,读者下去可自行测试。
我们如何才能使得程序每次运行的时候让srand自动获取到不同的种子呢?接下来我们介绍一下time函数便可以知晓答案。
三、 time函数
1.函数介绍
time_t time (time_t* timer);//使用时包含头文件#include
time函数的功能是获取当前时间,并返回自1970年1月1日00:00到当前时间以来的秒数(时间戳),time函数只有1个参数,如果参数不是空指针,它还会将计算的时间戳存储在指针指向的变量中,该参数也可以是空指针,在这种情况下,不使用该参数,但函数仍然返回时间戳。
例如:计算当前时间的时间戳。
#include #include int main(){printf("1970年1月1日00:00到当前时间以来的秒数:%d\n", time(NULL));return 0;}
运行结果如下:
当我们每次运行上面打的代码的时候会发现,每次打印的数字都不一样,这是因为每次运行程序的时间不同,time函数返回的时间戳就不同,因此我们可以用time函数返回的时间戳当作srand初始化随机生成器的种子。
注意事项:
- srand的参数类型是unsigned int,而time函数的返回值是time_t,因此把time函数的返回值当srand函数的参数时,需要强制类型转换一下。
- 而我们也不需要time函数通过参数把时间戳存储起来,因此可以给传一个空指针(NULL)。
代码如下: - srand函数在每次程序运行的时候在调用rand函数之前调用一次即可,只需要保证这次运行程序的种子和下次运行程序的种子不同。
srand((unsigned int)time(NULL));
四、rand函数简单应用
1.rand函数生成[a, b]范围内的数字
- 我们知道,如果我们要想生成1~100内的随机数,只需要用生成的随机数%100,就能得到 0~99之间的数字,然后在此基础上+1,即可得到,即
rand() % 100 + 1。 - 因此我们要生成[a, b]范围内的数字,只需要用生成的随机数%(b-a+1),就能得到 0~(b-a)之间的数字,然后在此基础上+a,即可得到[a, b]范围内的数字,即
rand() % (b-a+1) + a
2. 猜数字游戏实现
- 游戏规则:系统随机生成一个1~100的数字,让玩家来猜,若玩家猜大了,提示玩家猜大了,并让其重新猜,猜小了也同理,直到玩家猜对为止。
代码如下:`
//猜数字游戏//数字范围 0 ~ 100#include #include //打印菜单void menu(){printf("******************************\n");printf("********** 1. play ***********\n");printf("********** 0. exit ***********\n");printf("******************************\n");}//游戏逻辑void game(){int guess = 0;int ret = rand() % 100 + 1;//生成随机数while (1){printf("请输入你要猜的数字>:");scanf("%d", &guess);if (guess > ret){printf("猜大了\n");}else if (guess < ret){printf("猜小了\n");}else{printf("恭喜你,猜对了!!!\n");break;}}}int main(){int input = 0;srand((unsigned int)time(NULL));//使用rand函数之前需要调用srand函数,设置随机数的种子,每次程序运行的时候调用一次即可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;}
若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。
创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!
如果本篇博客有任何错误,请批评指教,不胜感激 !