How does srand relate to rand function?

2019-01-10 21:06发布

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.

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

((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));

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

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

标签: c random srand
4条回答
劳资没心,怎么记你
2楼-- · 2019-01-10 21:44

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

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 need a variable to place the time in, you can just pass 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).

// 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 next is 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().

查看更多
倾城 Initia
3楼-- · 2019-01-10 21:44

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 FILE from stdio; the downside is that they decided to make that state a global (but hidden) variable rather than a parameter to the generator.

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

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.

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

Just to be extra-extra clear: had rand_r been 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_r and to some hypotetical srand_r, as in

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

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

查看更多
男人必须洒脱
4楼-- · 2019-01-10 21:46

rand gives you a pseudo random sequence of numbers.

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 on 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.

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

查看更多
再贱就再见
5楼-- · 2019-01-10 21:55

The random number seed is a global static variable. rand and srand both have access to it.

查看更多
登录 后发表回答