认识随机函数rand()和srand(unsigned int )
rand函数
int rand( void );
该函数是一个无参数函数,返回值是一个int类型的随机数,其值的范围是[0 , 0x7fff]即[0 , 32767]。虽然这个函数不需要参数,但是rand函数运行是需要一个seed(种子),种子由srand()函数提供。这个srand函数我们待会在介绍.rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。
srand函数
void srand(unsigned seed);
srand和rand()配合使用产生伪随机数序列。只要该函数的参数发生变化,rand函数就能产生随机值,如果该函数的参数是一个定值,那么rand函数每次函数的随机数就和上一次产生的值一样.如果我们需要多次调用rand函数,产生不同的随值,我们就需要给他设置不同的seed。
实例一:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
unsigned int seed;
int input;
for(i=0;i<10;i++)
{
scanf("%d",&input);
seed = (unsigned)input;
srand(seed);
printf("Random value is %d\n",rand());
}
return 0;
}
运行上面的程序后,我们又发现,我们不能保证每次输入的seed值绝对与上次不一样。于是我们采用时间来作为seed,因为时间当前时间总是在变化的,或者说时间流逝的距离总是在变化的。我们可以采用当前前时间作为种子。
实例二:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
int i;
time_t t;
srand((unsigned)time(&t));
for(i =0; i<10;i++)
{
printf("Random value is %d\n",rand());
}
return 0;
}
产生指定区间内的随机数
在实际的编程的时候,我们不总是需要[0 , 0x7fff]区间内的所有数,可能我们只需要其中一部分[0 , 15]内的随机数。这是我们就该避免产生大于15的数。我们可以通过对rand()函数的返回值取余数 RandomValue = rand() % (15 + 1) 。一般的,我们要产生[0 , N]的随机数,可以RandomValue = rand() % (N + 1);如果要产生[0 , N)随机数,可以RandomValue = rand() % N 。需求总是越来越多,需要产生[M , N]区间的随机数是怎么办呢?我们可以认为区间[M , N]是由[0 , N - M]向右边位移 M 个单位得到的。我们通过产生[0 , N - M]区间内的随机数加上M得到 [M , N]区间内的随机数,这好似一个巧妙的转换过程。
实例三:
/*获取区间[2,99]的随机数
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define M 2
#define N 99
int main()
{
int i;
time_t t;
srand((unsigned)time(&t));
for(i=0;i<100;i++)
{
printf("%d\t",M + rand() % (M - N + 1));
}
return 0;
}
产生随机浮点数
rand /(double)RANDMAX; 可以随机产生[0.0 , 1.0]区间内的小数, rand / (double)(RANDMAX + 1) 可以产生[0.0 , 1.0)区间的小数。结合上面产生任意区间数的方法,我们就可以随机产生任意区间内的浮点数了.(注: 第一次rand()产生[M , N)区间内的整数 x1,第二次rand()产生[0.0 ,1.0]的浮点数,最终的到随机在[M , N]区间内的浮点数 FloatValue = x1 + x2).
实例四:
#include<stdio.h>
#include<stdli.h>
#include<time.h>
int Sentinel = 0;//设置哨兵,保证只设置一次种子
double RandomFloate(int M, int N)
{
int RandomValue1;
double RandomValue2;
if(Sentinel == 0)
{
time_t t;
srand((unsigned)time(&t));
}
RandomValue1 = M + rand() % (M - N + 1);
RandomValue2 = rand() / (double)(RAND_MAX + 1);
return RandValue + RandomValue2;
}
int main()
{
int i;
for(i= 0;i<100; i++)
{
printf("%f\t",RandomFloate(2,5));
}
}
rand函数误区
rand()函数设置一次种子就可以多次使用。不要将srand((unsigned)time(&t))和rand()这样的组合放在一个循环中,因为在time()函数的单位是秒,可能你的程序在一秒内就运行了 n 次,那么这n次设置的种子就一样的,产生的随机数也是一样的。还需要注意的就是你没有调用srand()函数时候,系统默认你调用了srand(1).