C语言 srand 与 rand 函数有什么关系?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21273550/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:39:27  来源:igfitidea点击:

How does srand relate to rand function?

crandomsrand

提问by Arrow

I understand that rand() function generates the same number(s) each you run it if you don't change the seed number. That's where srand() comes in. Time is always changing so I know that you should pass the time(null) parameter to srand. My question is with the code below from a tutorial site.

我知道,如果您不更改种子编号,则 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);
}

I see no link from the srand

我看不到来自 srand 的链接

((unsigned) time(&t)); 

and rand.

和兰特。

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

Where is the connection between rand and srand? What I mean or expect is I assume rand() will get some parameter from srand() so it knows to generate different numbers each time. I assume it would look something like rand(srand(time(null));

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

It's like initializing a variable without using it to me. srand is being initialized, but I don't see it being used.

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

Does rand generate different numbers because srand is called first before rand?

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

回答by sqykly

The random number seed is a global static variable. randand srandboth have access to it.

随机数种子是一个全局静态变量。 rand并且srand两者都可以访问它。

回答by paxdiablo

srand()sets the seed which is used by randto generate "random" numbers (in quotes because they're generally pseudo-random). If you don't call srandbefore your first call to rand, it's as if you had called srand(1)to set the seed to one.

srand()设置用于rand生成“随机”数字的种子(用引号引起来,因为它们通常是伪随机的)。如果您srand在第一次调用之前没有调用rand,就好像您已经调用srand(1)将种子设置为 1。

A lot of code uses the current time as the seed so as to make each program run use a different sequence of random numbers but you can always change that to something like srand(42)during debugging, for the purposes of repeatability. And the call to time()doesn't actually needa variable to place the time in, you can just pass NULL:

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

srand (time (NULL));

The whole thing could be implemented in a single file with something like the following, the example given in the standard (ISO C99 7.20.2.2 The srand function).

整个事情可以在一个文件中实现,如下所示,标准中给出的例子 ( 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;
}

The fact that nextis a static variable at the top of the file means that it's invisible to everything outside the file but visible to everything inside (sort of a localised global). That's the communication method between srand()and rand().

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

回答by loreb

You don't see a link because (luckily!) whoever designed rand()decided to keep that an implementation detail, in the same way as you don't see what's inside a FILEfrom stdio; the downside is that they decided to make that state a global (but hidden) variable rather than a parameter to the generator.

您看不到链接,因为(幸运的是!)设计者rand()决定保留实现细节,就像您看不到FILEstdio 中的内容一样;缺点是他们决定将该状态设为全局(但隐藏)变量而不是生成器的参数。

Contrast that to the deprecated rand_r(): the state is an unsigned integer (assumed to be >= 32 bits), which means that even it's forbiddento use any better generator whose state is greater than that, simply because there is no room to store it!

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

By keeping the internal state hidden, instead, one is free to pick whatever algorithm works best (speed, period, ...) and use it behind the scenes, as long as you guarantee that calling rand without initialization is the same as calling srand with seed==1.

相反,通过保持内部状态隐藏,人们可以自由选择任何最有效的算法(速度、周期等)并在后台使用它,只要您保证在没有初始化的情况下调用 rand 与调用 srand 相同种子==1。

Paxdiablo showed you the example from the C standard; see eg http://en.wikipedia.org/wiki/Multiply-with-carryfor an example using a different generator that you could hide behind rand/srand.

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

Just to be extra-extra clear: had rand_rbeen designed properly, there would be an opaque type, say rand_t(which could be an integer, a structure, an array, ...), which you would pass to rand_rand to some hypotetical srand_r, as in

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

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

The rand function is exactly like this, except that there's only one statevariable.

rand 函数和这个完全一样,只是只有一个state变量。

回答by Jimit Rupani

randgives you a pseudo random sequence of numbers.

rand给你一个伪随机的数字序列。

This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using function srand.

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

srandon each call sets the pointer to some location in the list which you are getting in. If you don't call it on each attempt or give it a fix seed it will give you the same sequence. So many suggest giving the current second as seed. But if you try running your code in the same second twice, it will give you same sequence.

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

For every different seed value used in a call to srand, the pseudo-random number generator can be expected to generate a different succession of results in the subsequent calls to rand for further explanation

对于调用 srand 中使用的每个不同的种子值,伪随机数生成器可以预期在随后的 rand 调用中生成不同的结果序列以供进一步解释