👀 📔 читать онлайн » Компьютеры и Интернет » Программирование » Linux программирование в примерах - Роббинс Арнольд

Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"

Перейти на страницу:

Этот код явно патологический, но он предназначен для иллюстрации нашей мысли:

setjmp()
и
longjmp()
могут вести к трудно обнаруживаемым утечкам памяти. Предположим, что
f1()
правильно вызвал
free()
. Было бы далеко неочевидно, что память никогда не будет освобождена. В более крупной и более реалистичной программе, в которой
longjmp()
мог быть вызван лишь посредством
if
, найти такую утечку становится даже еще труднее.

Таким образом, при наличии

setjmp()
и
longjmp()
динамическая память должна управляться посредством глобальных переменных, а у вас должен быть код, который обнаруживает вход через
longjmp()
(посредством проверки возвращаемого значения
setjmp()
). Такой код должен затем освободить динамически выделенную память, которая больше не нужна.

В-шестых,

longjmp()
и
siglongjmp()
не следует использовать из функций, зарегистрированных посредством
atexit()
(см. раздел 9.1.5.3 «Функции завершения»).

В-седьмых,

setjmp()
и
longjmp()
могут оказаться дорогими операциями на машинах с множеством регистров.

При наличии всех этих проблем вы должны строго рассмотреть дизайн своей программы. Если вам не нужно использовать

setjmp()
и
longjmp()
, то, может, стоит обойтись без их использования. Однако, если их использование является лучшим способом структурировать свою программу, продолжайте и используйте их, но делайте это осмотрительно.

12.6. Псевдослучайные числа

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

fortune
, содержащей большую коллекцию афоризмов; каждый раз при запуске она «случайно» выдает новое высказывание.) Многие криптографические алгоритмы также требуют наличия случайных чисел «высокого качества». В данном разделе описываются различные способы получения последовательностей случайных чисел.

ЗАМЕЧАНИЕ. Природа случайности, генерация случайных чисел и их «качество» являются обширными темами, выходящими за рамки данной книги. Мы предоставляем введение в доступные функции API, но это все, что мы можем сделать Другие источники с более подробной информацией см в разделе 12.9 «Рекомендуемая литература»

Компьютеры по своему строению являются детерминистическими. Одно и то же вычисление с одними и теми же входными данными всегда должно давать одни и те же результаты. Соответственно, они не годятся для генерации истинно случайных чисел, то есть последовательностей чисел, в которых каждое число в последовательности полностью независимо от числа (или чисел), идущих перед ним. Вместо этого разновидности чисел, обычно используемых на программном уровне, называются псевдослучайными числами. То есть в любой данной последовательности номера выглядят независимыми друг от друга, но сама последовательность в целом повторяющаяся. (Эта повторяемость может быть ценным качеством; она обеспечивает детерминизм для программы в целом.)

Многие методы предоставления последовательностей псевдослучайных чисел работают посредством осуществления каждый раз одного и того же вычисления с начальным значением (seed). Сохраненное начальное значение затем обновляется для использования в следующий раз. API предоставляет способ указания нового начального значения. Каждое начальное значение дает одну и ту же последовательность псевдослучайных чисел, хотя различные начальные числа дают (должны давать) различные последовательности.

12.6.1. Стандартный С:

rand()
и
srand()

Стандартный С определяет две связанные функции для псевдослучайных чисел.

#include <stdlib.h> /* ISO С */

int rand(void);

void srand(unsigned int seed);

rand()
каждый раз после вызова возвращает псевдослучайное число в диапазоне от 0 до
RAND_MAX
(включительно, насколько мы можем судить по стандарту C99). Константа
RAND_MAX
должна быть по крайней мере 32 767; она может быть больше.

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

Следующая программа,

ch12-rand.c
, использует
rand()
для вывода граней игральных костей.

1  /* ch12-rand.c --- генерирует игральные кости, используя rand(). */

2

3  #include <stdio.h>

4  #include <stdlib.h>

5

6  char *die_faces[] = { /* Управляет ASCII графика! */

7   "       ",

8   "   *   ", /* 1 */

9   "       ",

10

11  "       ",

12  " *   * ", /* 2 */

13  "       ",

14

15  "       ",

16  " * * * ", /* 3 */

17  "       ",

18

19  " *   * ",

20  "       ", /* 4 */

21  " *   * ",

22

23  " *   * ",

24  "   *   ", /* 5 */

25  " *    * ",

26

27  " * * * ",

28  "       ", /* 6 */

29  " * * * ",

30 };

Перейти на страницу:
Оставить комментарий о книге
Подтвердите что вы не робот:*

Отзывы о книге "Linux программирование в примерах, автор: Роббинс Арнольд":

Все материалы на сайте размещаются его пользователями. Администратор сайта не несёт ответственности за действия пользователей сайта. Вы можете направить вашу жалобу на почту booksreadonlinecom@gmail.com
© 2021 - 2026 booksread-online.com