Сейчас мы покажем генератор псевдослучайных чисел. Это означает, что фактическая последовательность чисел предсказуема, но они разбросаны довольно равномерно в пределах возможного диапазона значений.
Схема начинает с числа, называемого "зерно". Она использует его для создания нового числа, которое становится новым зерном. Затем новое зерно можно использовать для создания более нового зерна и т.д. Чтобы эта схема работала, функция случайных чисел должна помнить зерно, которое она использовала при последнем вызове. Отметим, здесь нужно использовать статическую переменную!
/* Первая версия функции rand()*/rand(){ static int randx = 1; randx = (randx * 25173 + 13849)%65536; /* магическая формула */ return(randx);}Статическая переменная randx начинает со значения 1 и изменяется при помощи магической формулы каждый раз при вызове функции. Результатом в нашей системе является число, находящееся в диапазоне -32768 до 32767. Системы с разной длиной переменной типа int будут давать различные результаты.
Проверим работу функции при помощи этого простого драйвера:
|
|
Получим результат:
-26514-444920196-205313882Эта последовательность чисел выглядит довольно случайной. Запустим драйвер еще раз. Теперь имеем
-26514-444920196-205313882Получилось абсолютно то же самое. Это и есть псевдоэффект. Каждый раз, когда работает основная программа, мы начинаем с одного и того же значения зерна, равного 1. Можно обойти эту проблему, введя вторую функцию srand(), которая позволяет вновь устанавливать зерно в начальное значение. Хитрость заключается в том, чтобы сделать randx внешней статической переменной, известной только функциям rand() и srand(). Эти две функции нужно хранить в своем собственном файле и компилировать этот файл отдельно. Вот модификатор программы:
/* Файл для rand() и srand() */static int randx = 1;rand(){ randx = (randx * 25173 + 13849) % 65536; return(randx);}srand(x)unsigned x;{ randx = x;}Используем другой драйвер:
/* драйвер 2 функции rand() */main(){ int count; int seed; printf(" Введите свое значение зерна.\n"); scanf("%d", & seed); srand(seed); /* установите зерно в начальное значение */ for(count = 1; count <= 5; count++) printf("%d\n",rand());}Программа проработала один раз:
Введите свое значение зерна. 1-26514-444920196-205313882Используя значение 1 для переменной seed, получаем те же значения, что и прежде. Введем значение 2 и посмотрим, что получится:
22383220241-1858-30417-16204Мы получили другую последовательность чисел.