用C语言产生随机数重要用到rand函数、srand函数、及宏RAND_MAX(32767),它们均在stdlib.h中进行了声明。
int rand(void);//生成一个随机数
voidsrand(unsigned int seed); //为rand设置“种子”的值
srand()就是给rand()提供种子seed,如果srand每次输入的数值是一样的,那么每次运行产生的随机数也是一样的。通常的做法是以这样一句代码:
srand((unsigned)time(NULL));
来取代,这样将使得种子为一个不固定的数,这样产生的随机数就不会每次执行都一样了。先看一个例子:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int test_rand()
{
int i;
/* Seed therandom-number generator with current time so that
* thenumbers will be different every time we run.
*/
srand((unsigned)time( NULL ) );
/* Display10 numbers. */
for( i = 0;i < 10; i++ )
printf("%6d ", rand());
return 0;
}
C的函数库之所以没有把使用系统时钟初始化随机种子这步重要的操作直接放进rand函数的实现中,可能有如下原因:
1.可以高效产生连续的随机数,不用每次都初始化;
2.给程序员以更高的灵活性,因为可能在要求较高的场合,应该使用更好的的数据做种子,而不是系统时钟;
3.对于只是想产生大量伪随机数来尽兴某种验证或者统计,未必需要初始化,大不了程序每次运行都产生同样的一系列随机数而已——有些情况下,这是无所谓的。
4.作为伪随机序列产生器的rand()函数,必须具备的一个重要特性就是:产生的序列必须是可重现的。这不仅仅是一个算法,相当大的程度上,它关系到代码测试的准确性。如果算法中使用了和rand()的结果相关的数据,通过一个可控的可重现序列,我们就有机会再现每一次测试的过程,从而更有效的找到问题的所在。所以这里提出一个建议,代码中,如果rand()的函数结果关系到算法的结果,那么,必须保证你的rand()调用是可重现的。
另外使用rand还用几个问题:
如何生成 0到 100之间的随机数?
用"int x = rand() % 100;"这种方法是不或取的,会使产生的随机数不在随机。产生一个0到n之间的随机数的比较好的做法是:
j=(int)(n*rand()/(RAND_MAX+1.0));
如何产生一个范围在(a,b)之间的随机数?
先计算a与b的差值,设c=b-a;产生一个介于0和b-a的数值,设
d=(int)((b-a)*rand())/(RAND_MAX+1.0)
让上面产生的值d加上a就可以了。
如果你使用C++11编程,请使用C++11自己的随机数生成方法!
虽然前面介绍了那么多,但是我还是想说C语言的随机数生成方法有很多缺陷,很容易被引入非随机性,而且功能单一,如果可以的话去,你最好避免使用它。