Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015

Тут можно читать онлайн Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - бесплатно полную версию книги (целиком) без сокращений. Жанр: Прочая старинная литература, издательство Вильямс, год 0101. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - описание и краткое содержание, автор Стивен Прата, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать книгу онлайн бесплатно, автор Стивен Прата
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Вот результаты пробного запуска:

Введите положительное целое число (0 для завершения): 5 итерация цикла: 1 subtotal: 15; total: 15

Введите положительное целое число (0 для завершения): 10 итерация цикла: 2 subtotal: 55; total: 70

Введите положительное целое число (0 для завершения) : 2 итерация цикла: 3 subtotal: 3; total: 73

Введите положительное целое число (0 для завершения): 0 Цикл выполнен 3 раз(а)

Классы хранения, связывание и управление памятью 501

Классы хранения и функции

Функции также имеют классы хранения. Функция может быть либо внешней (по умолчанию), либо статической. (В стандарте С99 добавлена третья возможность — встраиваемая функция, которая обсуждается в главе 16.) Доступ к внешней функции могуг получать функции в других файлах, но статическая функция может применяться только внутри файла, где она определена. Рассмотрим, например, файл со следующими прототипами функций:

double gamma(double); /* по умолчанию внешняя */

static double beta(int, int);

extern double delta(double, int);

Функции gamma() и delta() могут использоваться функциями в других файлах, которые являются частью программы, но beta() — нет. Из-за такого ограничения функции beta() одним файлом в остальных файлах можно применять другие функции с этим же именем. Причина использования класса хранения static связана с созданием функций, закрытых в отношении конкретного модуля, благодаря чему устраняется возможность конфликта имен.

Обычная практика предусматривает применение ключевого слова extern при объявлении функции, определенной в другом файле. Главным образом это касается ясности, т.к. объявление функции предполагается как extern, если только не указано ключевое слово static.

выбор класса хранения

Ответом на вопрос о том, какой выбрать класс хранения, чаще всего будет — автоматический. В конце концов, по какой еще причине автоматический класс хранения был выбран по умолчанию? Да, мы знаем, что на первый взгляд внешний класс хранения выглядит более привлекательным. Стоит лишь сделать все свои переменные внешними, и не придется беспокоиться об использовании аргументов и указателей при взаимодействии между функциями.

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

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

const int DAYS = 7;

const char * MSGS[3] = {"Да", "Нет", "Возможно"};

Одним из золотых правил защитного программирования является принцип “необходимого знания”. Держите всю внутреннюю работу каждой функции максимально закрытой в рамках этой функции, совместно используя только те переменные, которые должны совместно использоваться. Друтие классы хранения удобны, и они доступны. Однако прежде чем выбирать какой-то из них, подумайте, есть ли в этом необходимость.

502 Глава 12

Функция генерации случайных чисел и статическая переменная

Теперь, когда вы получили необходимый минимум знаний о классах хранения, давайте рассмотрим пару программ, в которых они применяются. Первым делом мы взглянем на функцию, которая использует статическую переменную с внутренним связыванием: функцию генерации случайных чисел. Для генерации случайных чисел библиотека ANSI С предлагает функцию rand(). Существуют разнообразные алгоритмы генерации случайных чисел, и ANSI С позволяет реализациям выбирать наилучший алгоритм для конкретной машины. Однако ANSI С также предлагает стандартный переносимый алгоритм, который выдает те же самые случайные числа в разных системах. В действительности функция rand() является “генератором псевдослучайных чисел”, т.е. фактическая последовательность чисел предсказуема, но числа достаточно равномерно распределены по диапазону возможных значений.

картинка 390

Вместо применения встроенной функции rand() компилятора, мы будем использовать переносимую версию ANSI, чтобы вы могли видеть, что происходят внутри. Схема начинается с числа, которое называется “начальным”. Функция применяет начальное число для получения нового числа, которое становится новым начальным числом. Затем новое начальное число может использоваться для получения следующего нового начального числа и т.д. Чтобы эта схема работала, функция генерации случайных чисел должна запоминать начальное число, которое применялось при ее последнем вызове. Здесь и возникает потребность в статической переменной. В листинге 12.7 представлена версия 0 (вскоре появится и версия 1).

В листинге 12.7 статическая переменная next начинает со значения 1 и изменяет ся магической формулой при каждом вызове функции. Результатом будет возвращаемое значение, находящееся где-то в диапазоне от 0 до 32767. Обратите внимание, что next является статической переменной с внугренним связыванием, а не просто статической переменной без связывания. Дело в том, что позже пример будет расширен, чтобы переменная next совместно использовалась двумя функциями в том же самом файле.

Давайте протестируем функцию rand0() с помощью простого драйвера, показанного в листинге 12.8.

Листинг 12.8. Драйвер r_drive0. с

rdrive0c тестирование функции rand0 компилировать вместе с - фото 391/* r_drive0.c -- тестирование функции rand0() */

/* компилировать вместе с rand0.c */

#include extern int rand0(void);

Классы хранения, связывание и управление памятью 503

Здесь вы имеете еще один шанс попрактиковаться с применением нескольких файлов - фото 392

Здесь вы имеете еще один шанс попрактиковаться с применением нескольких файлов. Поместите код из листинга 12.7 в один файл, а код из листинга 12.8 — в другой. Ключевое слово extern напоминает, что функция rand0() определена в отдельном файле, хотя оно необязательно.

Вывод имеет следующий вид:

16838

5758

10113

17515

31051

Выходные данные производят впечатление случайных, но давайте запустим программу снова. И вот какие результаты получены на этот раз:

16838

5758

10113

17515

31051

Числа выглядят знакомыми; в этом и заключается аспект “псевдо”. Каждый раз, когда главная программа запускается, старт происходит с одного и того же начального числа 1. Проблему можно обойти путем ввода второй функции по имени srandl(), которая позволит переустанавливать начальное число. Трюк заключается в том, чтобы сделать next статической переменной с внутренним связыванием, которая известна только функциям randl() и srandl(). (Эквивалент srandl() в библиотеке С называется srand().) Добавьте функцию srandl() в файл, содержащий randl().

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Стивен Прата читать все книги автора по порядку

Стивен Прата - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Язык программирования C. Лекции и упражнения (6-е изд.) 2015 отзывы


Отзывы читателей о книге Язык программирования C. Лекции и упражнения (6-е изд.) 2015, автор: Стивен Прата. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x