Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / Основы программирования на Си.doc
Скачиваний:
386
Добавлен:
02.05.2014
Размер:
1 Мб
Скачать
☆

16. Лекция: Функции в примерах.

-Функция получения случайных чисел.

-Поиск узлов из простых чисел.

-Матрица инцидентности.

-Структуры данных. Работа с файлами.

-Все операции со стеком.

-Примеры из графики, все преобразования трехмерного пространства.

Функция получения случайных чисел

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

Схема начинает с числа, называемого "зерно". Она использует его для создания нового числа, которое становится новым зерном. Затем новое зерно можно использовать для создания более нового зерна и т.д. Чтобы эта схема работала, функция случайных чисел должна помнить зерно, которое она использовала при последнем вызове. Отметим, здесь нужно использовать статическую переменную!

/* Первая версия функции rand( )*/

rand( )

{

static int randx = 1;

randx = (randx * 25173 + 13849)%65536;

/* магическая формула */

return(randx);

}

Статическая переменная randx начинает со значения 1 и изменяется при помощи магической формулы каждый раз при вызове функции. Результатом в нашей системе является число, находящееся в диапазоне -32768 до 32767. Системы с разной длиной переменной типа int будут давать различные результаты.

Проверим работу функции при помощи этого простого драйвера:

/*драйвер 1 функции rand( ) */

main( )

{

int count;

for(count = 1; count <= 5; count++)

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

}

Получим результат:

-26514

-4449

20196

-20531

3882

Эта последовательность чисел выглядит довольно случайной. Запустим драйвер еще раз. Теперь имеем

-26514

-4449

20196

-20531

3882

Получилось абсолютно то же самое. Это и есть псевдоэффект. Каждый раз, когда работает основная программа, мы начинаем с одного и того же значения зерна, равного 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("%\n",rand( ));

}

Программа проработала один раз:

Введите свое значение зерна.

1

-26514

-4449

20196

-20531

3882

Используя значение 1 для переменной seed, получаем те же значения, что и прежде. Введем значение 2 и посмотрим, что получится:

2

23832

20241

-1858

-30417

-16204

Мы получили другую последовательность чисел.