Таким образом, хорошим тоном в программировании считается размещение прототипов функций и определенных констант в заголовочном файле. Давайте рассмотрим пример. Предположим, что вы управляете сетью из четырех отелей. В каждом отеле действует разная плата за номер, но все номера в одном и том же отеле стоят одинаково. Для тех, кто забронировал номер на несколько суток, плата за вторые сутки составляет 95% от платы за первые сутки, третьи сутки оплачиваются в размере
Функции 351
95% от платы за вторые сутки и т.д. Вам нужна программа, которая позволила бы выбрать отель, указать количество сугок и рассчитать суммарную стоимость проживания. Желательно, чтобы программа имела меню, которое позволило бы вводить данные до тех пор, пока не будет принято решение выйти из программы.
В листингах 9.9, 9.10 и 9.11 показано, как можно решить эту задачу. Листинг 9.9 содержит функцию main(), которая обеспечивает общую организацию для программы. В листинге 9.10 приведен код функций поддержки, хранящийся в отдельном файле. Наконец, в листинге 9.11 представлен заголовочный файл, в котором содержатся определения констант и прототипы функций для всех исходных файлов программы. Вспомните, что в средах Unix и DOS двойные кавычки в директиве #include "hotels.h" указывают на то, что включаемый файл хранится в текущем рабочем каталоге (обычно в каталоге, где находится исходный код). В IDE-среде необходимо знать, как заголовочные файлы включаются в проект.
Листинг 9.9. Управляющий модуль usehotel.с

Листинг 9.10. Модуль функций поддержки hotel.с

352 Глава 9

Листинг 9.11. Заголовочный файл hotel.h

Функции 353
Ниже показаны результаты пробного запуска:
Введите число, соответствующее выбранному отелю:
1) Fairfield Arms 2) Hotel Olympic
3) Chertworthy Plaza 4) The Stockton
5) выход
3
На сколько суток вы бронируете номер? 1 Общая стоимость составляет $255.00.
Введите число, соответствующее выбранному отелю:
1) Fairfield Arms 2) Hotel Olympic
3) Chertworthy Plaza 4) The Stockton
5) выход
4
На сколько суток вы бронируете номер? 3 Общая стоимость составляет $1012.64.
Введите число, соответствующее выбранному отелю:
1) Fairfield Arms 2) Hotel Olympic
3) Chertworthy Plaza 4) The Stockton
5) выход
5
Благодарим за использование и желаем успехов.
Кстати, эта программа сама по себе обладает рядом интересных особенностей. В частности, функции menu() и get nights() пропускают нечисловые данные, проверяя возвращаемое значение функции scanf() и применяя вызов scanf ("%*s") для пропуска следующего пробельного символа. Взгляните, как следующий фрагмент функции menu() производит проверку на предмет нечислового ввода и ввода числовых значений, выходящих за пределы установленного диапазона:
while ((status = scanf("%d", &code)) != 1 II (code <111 code > 5))
В этом фрагменте кода используется действующее в С правило о том, что логические выражения вычисляются слева направо и что вычисление прекращается, как только становится понятно, что выражение ложно. В данном случае значения code проверяются только после того, как будет установлено, что функция scanf() успешно прочитала целочисленное значение.
Назначение отдельных задач разным функциям способствует такому улучшению кода. На первом этапе написания программы функция menu() или getnights() может применять функцию scanf() без дополнительных функций проверки допустимости данных. Затем, когда базовая версия заработает, можно приступить к совершенствованию отдельных модулей.
Выяснение адресов: операция &
Одним из наиболее важных концепций языка С (и временами самой трудной для понимания) является указатель, который представляет собой переменную, используемую для хранения адреса. Вы уже видели, что функция scanf() работает с адресами
354 глава 9 аргументов. В общем случае любая функция С, которая изменяет значение в вызывающей функции без использования значения в return, применяет адреса. Далее мы рассмотрим функции, использующие адреса, и начнем с унарной операции &. (В следующей главе мы продолжим исследование и работу с указателями.)
Унарная операция & предоставляет адрес, по которому хранится переменная. Если pooh является именем переменной, то &pooh — адрес этой переменной. Об адресе можно думать как о ячейке в памяти. Пусть имеется следующий оператор:
Читать дальше