前言
在C语言中是如何来得到随机数的呢?需要得到随机数我们要用到一个库函数rand;这函数可以⽣成随机数,那目录里提到的srand函数、time函数又是干什么用的呢?下面就让我们一起来看看。
一、rand函数
rand函数的原型如下:
可以看到rand函数会返回一个int型的伪随机数,返回的随机数的范围是:0~RAND_MAX;RAND_MAX的大小依赖于编译器,在⼤部分编译器上是32767。我们看看在VS中这个RAND_MAX的值是多少:
rand函数在使用的时候需要包含头文件<stdlib.h>,0x7fff是十六进制数换算为十进制就为32767。
下面我们使用rand函数来生成一些随机数看看:
我们在多试几次,就会发现这其中有猫腻了!
可以发现,每次生成的随机数都是相同的;其实这里是因为我们还没有完全用对rand函数,rand函数是对⼀个叫“种⼦”的基准值进⾏运算来⽣成随机数的,要想每次运行都产生不一样的随机数,我们则需要为rand函数设置一个不断变化的“种子”。而设置这个种子就需要使用到srand函数。
二、srand函数
srand函数是用来初始化随机数的⽣成器的,它的原型如下:
我们在使用rand函数之前,通过srand函数的参数seed来设置rand函数⽣成随机数时候的种⼦,当种⼦时刻在发生变化,每次⽣成的随机数序列也就不一样了。这也就是说,srand这个函数的参数也需要给一个不断变化的值,这不就和前面矛盾了吗?我们需要一个随机数,这个随机数我们还没得到呢;这里又需要一个随机数,要想rand函数能够生成随机数,又必须要先给这个srand函数的参数设置一个不断变化值。这该如何是好呢?我们接着往下看。
三、time函数
我们都知道时间是无时不刻都在发生变化的,那时间正好能够满足这个srand函数参数的要求呀!那时间能否为我们所用呢?是可以的,C语言中time函数可以获得这个时间,它的原型如下:
time函数可以获取当前的系统时间,返回的是一个time_t类型的从1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的差值,time_t类型本质上其实就是整型类型。可以看到time函数的参数timer是指针类型的,如果我们给time函数传一个空指针(NULL),就会只返回这个时间的差值,这个差值也被称为时间戳。time函数在使用前需要包含头文件<time.h>。
在了解了这些之后,我们就来给srand函数一个不断变化的参数,我们通过代码来看看:
由于srand函数的参数是需要一个unsigned int 类型的值,虽然time函数的返回值为time_t类型的,但是时间戳是一个正数;所以我们只要把time函数的返回值强制类型转换为unsigned int类型即可。
不断变化的“种⼦”设置好之后我们在来看看rand函数产生的随机数。
我们可以看到多次运行,每次的生成的随机数都是不一样的了。还需要注意srand函数是不需要频繁调⽤的,⼀次运⾏的程序中调⽤一次就够了。
四、设置随机数的范围
怎样得到需要范围的随机数呢?这里需要用到一个运算符(%),这个运算符是取模运算符,得到的就是除以一个数的余数。我们只需要将得到的随机数除上规定的范围那个数就可以得到需要范围的数。
例如:要得到0~99之间的随机数我们只需要这样即可:
如果需要得到1-100之间的随机数只需如下即可:
我们可以发现一个规律,如需要生成a~b范围里的随机数,只需要这样来写:( a + rand() % (b - a + 1); )
现学现用写猜数字游戏
了解怎样得到需要范围内的随机数后,我们就能利用这个来写出一个猜数字的小游戏了!例如我来写一个可以指定范围的猜数字游戏。
思路
我们来理理思路:
1. 首先我们需要一个菜单,这个菜单里提供了选项可供我们选择。
2. 开始游戏时,先要让玩家输入玩家需要指定的范围,从而可以用rand函数得到一个在指定范围里的数
3. 开始游戏后我们让玩家输入一个范围内的数字,对玩家输入的数字与得到的数字进行比较,若玩家猜小了,就提示猜小了,反之就提示猜大了,一直到玩家猜到该数字。
参考代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//菜单函数声明
void menu()
{
printf("|-----------------------|\n");
printf("|----- >1 开始游戏 -----|\n");
printf("|----- >0 退出游戏 -----|\n");
printf("|-----------------------|\n");
}
//游戏函数声明
void game(int min, int max)
{
int ret = min + rand() % (max - min +1);
int guess = 0;
printf("本次游戏数字范围:%d至%d\n", min, max);
printf("\n>>> 游戏开始!!!<<<\n");
while (1)
{
printf("输入你猜测的数字:");
scanf("%d", &guess);
if (ret == guess)
{
printf("恭喜你猜对了!\n");
break;
}
else if (guess > ret)
printf("猜大了!");
else
printf("猜小了!");
}
}
int main()
{
int min = 0;//指定范围的小值初始化
int max = 0;//指定范围的大值初始化
int input = 0;//选项初始化
srand((unsigned int)time(NULL));//设置随机数生成的种子
do {
menu();//菜单函数
printf("请选择!>");
scanf("%d", &input);
switch (input)
{
case 0:
printf("欢迎下次再玩!\n");
break;
case 1:
printf("请指定范围!输入两个正整数:");
scanf("%d %d", &min, &max);
game(min,max);//游戏函数
break;
default:
printf("请输在0/1里面选择!\n");
break;
}
} while (input);
return 0;
}
拓展功能
我们还能给这个小游戏里添加更多的功能,比如加上猜数字的次数限制,还能给游戏加上计时的功能。
例如:限制猜数字次数为5次,参考代码:
void game(int min, int max)
{
int count = 5;//限制猜数字次数为5次
int ret = min + rand() % (max - min +1);
int guess = 0;
printf("本次游戏数字范围:%d至%d\n", min, max);
printf("\n>>> 游戏开始!!!<<<\n");
while (count)
{
printf("剩余猜数字次数:%d\n", count);
printf("输入你猜测的数字:");
scanf("%d", &guess);
if (ret == guess)
{
printf("恭喜你猜对了!\n");
break;
}
else if (guess > ret)
printf("猜大了!\n");
else
printf("猜小了!\n");
count--;
if (count == 0)
printf("很抱歉你没有在规定的次数猜到\n");
}
}
加上计算功能,计时功能需要使用到用到clock函数,关于clock函数大家可以看看:
参考代码:
void game(int min, int max)
{
clock_t start = 0;//开始计时初始化
clock_t end = 0;//结束计时初始化
int ret = min + rand() % (max - min + 1);
int guess = 0;
printf("本次游戏数字范围:%d至%d\n", min, max);
printf("\n>>> 游戏开始!!!<<<\n");
start = clock();
while (1)
{
printf("输入你猜测的数字:");
scanf("%d", &guess);
if (ret == guess)
{
printf("恭喜你猜对了!\n");
end = clock();
printf("共用时:%.1lf秒\n", (double)(end - start) / CLOCKS_PER_SEC);
break;
}
else if (guess > ret)
printf("猜大了!\n");
else
printf("猜小了!\n");
}
}
以上两个拓展代码都只奉上了game函数的代码,只需把上面给的参考代码的game函数替换这里的game函数即可!
总结
到这里就结束,我们再来复盘一下;使用rand函数来生成随机数时,需要先使用srand函数来设置不断变化的“种子”,srand函数又需要一个不断变化的参数;而time函数又可以获取系统时间来为srand函数提供不断变化的参数。还需要注意srand函数在⼀次运⾏的程序中调⽤一次就够了。还有想要得到a~b范围内的随机数只需要写成这样即可( a + rand() % (b - a + 1); )到这里就结束啦,非常感谢大家的阅读!