Как srand относится к функции rand?

Я понимаю, что функция 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("%dn", rand() % 50);
    }

    return(0);
}

Я не вижу ссылки из srand

((unsigned) time(&t)); 

и Рэнд.

printf("%dn", rand() % 50);

где связь между rand и srand? Что я имею в виду или ожидаю я предполагаю, что rand() получит некоторый параметр из srand (), поэтому он знает, что каждый раз генерирует разные числа. Я предполагаю, что это будет выглядеть как rand(srand(time (null));

Это похоже на инициализацию переменной, не используя ее для меня. srand инициализируется, но я не вижу его.

генерирует ли rand разные числа, потому что srand вызывается первым перед rand?

4 ответов


семя случайных чисел является глобальной статической переменной. rand и srand оба имеют к нему доступ.


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


вы не видите ссылку, потому что (к счастью!) кто бы ни проектировал rand() решил сохранить эту деталь реализации, так же, как вы не видите, что внутри FILE от stdio; недостатком является то, что они решили сделать это состояние глобальной (но скрытой) переменной, а не параметром генератора.

сравните это с устаревшим rand_r(): состояние является целым числом без знака (предполагается, что >= 32 бита), что означает, что даже это запрещен to используйте любой лучший генератор, состояние которого больше, просто потому, что нет места для его хранения!

сохраняя внутреннее состояние скрытым, вместо этого можно выбрать любой алгоритм, который работает лучше всего (скорость, период,...) и используйте его за кулисами, если вы гарантируете, что вызов rand без инициализации совпадает с вызовом srand с seed==1.

Paxdiablo показал вам пример из стандарта C; см. например http://en.wikipedia.org/wiki/Multiply-with-carry например, используя другой генератор, который вы могли бы скрыть за rand/srand.

просто чтобы быть очень-очень ясно: had rand_r был разработан должным образом, был бы непрозрачный тип, скажем rand_t (который может быть целым числом, структурой, массивом,...), который вы бы передали rand_r и в какой-то hypotetical srand_r, а в

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

функция rand точно такая же, за исключением того, что только один!--8--> переменной.


Рэнд дает вам псевдослучайную последовательность чисел.

Это число генерируется алгоритмом, который возвращает последовательность явно не связанных чисел каждый раз, когда он вызывается. Этот алгоритм использует семя для генерации ряда, который должен быть инициализирован до некоторого отличительного значения с помощью функции srand.

srand при каждом вызове устанавливает указатель на какое-либо место в списке, в который вы входите. Если ты не позвонишь ... каждая попытка или дать ему фиксированное семя даст вам ту же последовательность. Многие предлагают дать текущую секунду в качестве семени. Но если вы попытаетесь запустить свой код в одну и ту же секунду дважды, он даст вам ту же последовательность.

для каждого другого начального значения, используемого в вызове srand, генератор псевдослучайных чисел может генерировать различную последовательность результатов в последующих вызовах rand для дальнейшего объяснения