srand与rand函数有什么关系?

时间:2014-01-22 03:21:56

标签: c random srand

据我所知,如果不更改种子数,rand()函数会生成每个运行它的相同数字。这就是srand()的用武之地。时间总是在变化所以我知道你应该将time(null)参数传递给srand。我的问题是从教程网站下面的代码。

int main()
{
    int i, n=5;
    time_t t;

    /* Intializes random number generator */
    srand((unsigned) time(&t));

    /* Print 5 random numbers from 0 to 50 */
    for( i = 0 ; i < n ; i++ ) {
        printf("%d\n", rand() % 50);
    }

    return(0);
}

我看不到srand的链接

((unsigned) time(&t)); 

和兰特。

printf("%d\n", rand() % 50);

rand和srand之间的联系在哪里?我的意思或期望是我假设rand()将从srand()获取一些参数,因此它知道每次生成不同的数字。我假设它看起来像rand(srand(time(null));

就像初始化变量而不使用它一样。 srand正在初始化,但我没有看到它被使用。

rand会生成不同的数字,因为在rand之前首先调用srand吗?

4 个答案:

答案 0 :(得分:21)

随机数种子是全局静态变量。 randsrand都可以访问它。

答案 1 :(得分:13)

srand()设置rand使用的种子生成“随机”数字(引号中,因为它们通常是伪随机的)。如果您在第一次致电srand之前没有致电rand,就好像您已拨打srand(1)将种子设置为一个。

许多代码使用当前时间作为种子,以便使每个程序运行使用不同的随机数序列,但为了可重复性,您可以在调试期间将其更改为srand(42)。 。调用time()实际上并不需要需要变量来放置时间,你只需要传递NULL:

srand (time (NULL));

整个事情可以在单个文件中实现,类似于以下内容,标准中给出了示例(ISO C99 7.20.2.2 The srand function)。

// RAND_MAX assumed to be 32767.
static unsigned long int next = 1;
void srand(unsigned int seed) { next = seed; }
int rand(void) {
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}

next是文件顶部的静态变量这一事实意味着它对文件外部的所有内容都是不可见的,但对于内部的所有内容都是可见的(类似于本地化的全局)。这是srand()rand()之间的沟通方式。

答案 2 :(得分:4)

你没有看到链接,因为(幸运的是!)设计rand()的人决定保留一个实现细节,就像你从stdio看不到FILE里面的内容一样;缺点是他们决定将该状态设为全局(但隐藏)变量,而不是生成器的参数。

与已弃用的rand_r()对比:状态是无符号整数(假设为> = 32位),这意味着即使是禁止也要使用任何更好的生成器,国家大于那个,仅仅是因为没有空间存储它!

通过隐藏内部状态,可以自由选择最适合的算法(速度,周期,...)并在幕后使用它,只要你保证在没有初始化的情况下调用rand是相同的用种子== 1调用srand。

Paxdiablo向您展示了C标准的例子;有关使用可以隐藏在rand / srand后面的不同生成器的示例,请参阅例如http://en.wikipedia.org/wiki/Multiply-with-carry

只是要特别清楚:如果rand_r设计得恰当,会有一个不透明的类型,比如rand_t(可能是一个整数,一个结构,一个数组,...... ),您将传递给rand_r和一些hypotetical srand_r,如

rand_t state;
srand_r(&state, 1);
n = rand_r(&state);

rand函数与此完全相同,只是只有一个state变量。

答案 3 :(得分:0)

rand 为您提供伪随机数字序列。

此数字由算法生成,该算法每次调用时都会返回一系列明显不相关的数字。该算法使用种子生成序列,应使用函数srand将其初始化为某个独特的值。

每次调用时,

srand 会将指针设置为您所进入的列表中的某个位置。如果您在每次尝试时都没有调用它,或者给它一个修复种子它会给出你是相同的序列。很多人建议将当前的第二个作为种子。但是如果你尝试在同一秒内运行你的代码两次,它会给你相同的序列。

对于srand调用中使用的每个不同的种子值,伪随机数生成器可以在随后的rand for further explanation调用中生成不同的连续结果