Помимо метода "сверху вниз", вторым важным методом структурного проек-
тирования является метод модульного программирования. Он предполагает разделе-
ние текста программы на несколько файлов, в каждом из которых сосредоточены не-
зависимые части программы (сгруппированные по смыслу функции).
В программах на Си++ часто применяются библиотечные функции (например,
"sqrt(...)"). Для использования большинства функций, в том числе и библиотечных,
необходимы два файла (в скобках примеры даны для "sqrt(...)"):
• Заголовочный файл ("math.h") с прототипом функции ("sqrt(...)" и многих
других математических функций). Поэтому в программах, вызывающих
37
"sqrt(...)", есть строка "#include <math.h>", а не явное объявление этой
функции.
• Файл реализации (для пользовательских функций это файлы с исходным
текстом на Си++, а библиотечные функции обычно хранятся в скомпилиро-
ванном виде в специальных библиотечных файлах, например,
"libcmtd.lib"). Файлы реализации пользовательских функций (обычно с
расширением ".cpp") содержат определения этих функций.
Разделение исходного текста на заголовочные файлы и файлы реализации по-
казано в программе 6.1, которая выполняет те же действия, что и программа 4.1. Те-
перь программа состоит из трех файлов: главного файла, заголовочного файла с опи-
саниями двух функций расчета среднего значения, и соответствующего файла реали-
зации.
В главном файле содержится следующий текст:
#include <iostream.h>
#include "averages.h"
int main()
{
int number_A = 5, number_B = 3, number_C = 10;
cout << "Целочисленное среднее чисел " << number_A << " и ";
cout << number_B << " равно ";
cout << average(number_A, number_B) << ".\n\n";
cout << "Целочисленное среднее чисел " << number_A << ", ";
cout << number_B << " и " << number_C << " равно ";
cout << average(number_A, number_B, number_C) << ".\n";
return 0;
}
Главный файл программы 6.1.
Обратите внимание, что имя файла стандартной библиотеки "iostream.h" в ди-
рективе препроцессора "include" заключено в угловые скобки ("<>"). Файлы с имена-
ми в угловых скобках препроцессор ищет в библиотечных каталогах, указанных в на-
стройках компилятора. Имена пользовательских заголовочных файлов обычно за-
ключаются в двойные кавычки, и препроцессор ищет их в текущем каталоге про-
граммы.
Далее приведено содержимое файла "averages.h". В нем есть идентификатор
препроцессора "AVERAGES_H" и служебные слова препроцессора "ifndef" ("если не оп-
ределено"), "define" ("определить") и "endif" ("конец директивы if"). Идентифика-
тор "AVERAGES_H" является глобальным символическим именем заголовочного файла.
Первые две строки файла служат защитой от повторной обработки текста заголовоч-
ного файла препроцессором, на случай, если в исходном тексте программы строка
"#include "averages.h"" встречается несколько раз.
В заголовочных файлах, кроме прототипов функций, часто размещаются опи-
сания глобальных констант и пользовательских типов. Подробнее об этом говорится в
курсе объектно-ориентированного программирования.
#ifndef AVERAGES_H
# define AVERAGES_H
38
// (Определения констант и пользовательских типов)
// ПРОТОТИП ФУНКЦИИ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО
// ЗНАЧЕНИЯ 3-Х ЦЕЛЫХ ЧИСЕЛ:
int average(int first_number, int second_number,
int third_number);
// ПРОТОТИП ФУНКЦИИ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО
// ЗНАЧЕНИЯ 2-Х ЦЕЛЫХ ЧИСЕЛ:
int average(int first_number, int second_number);
#endif
Заголовочный файл averages.h.
Ниже показано содержимое файла "averages.cpp" с исходным текстом поль-
зовательских функций:
#include <iostream.h>
#include "averages.h"
// ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО
// ЗНАЧЕНИЯ 3-Х ЦЕЛЫХ ЧИСЕЛ:
int average(int first_number, int second_number,
int third_number)
{
return ((first_number + second_number + third_number)/3);
}
// ФУНКЦИЯ ДЛЯ ВЫЧИСЛЕНИЯ ЦЕЛОЧИСЛЕННОГО СРЕДНЕГО
// ЗНАЧЕНИЯ 2-Х ЦЕЛЫХ ЧИСЕЛ:
int average(int first_number, int second_number)
{
return ((first_number + second_number)/2);
}
Файл реализации averages.cpp.
Программа 6.1 демонстрирует основное достоинство модульного подхода: при
изменении деталей реализации в файле "averages.cpp" не обязательно вносить из-
менения в файл "averages.h" или в главный файл программы.
Сводка результатов
В данной лекции описано, как в Си++ можно создавать новые функции. Есть
Два способа передачи параметров внутрь функции: по значению и по ссылке. Функ-
Ции облегчают применение процедурной абстракции при разработке программ мето-
дом "сверху вниз". При модульном подходе описание и реализация функций разме-
Щаются в отдельных файлах, в таком случае для вызова функции необходимо вклю-
Чать в текст программы заголовочный файл.
39
Упражнения
Упражнение 1
В программе из упражнения 2 лекции 2 (файл ex2_2.cpp) выделите 6 функций,
имена и назначение которых перечислены ниже:
Fahrenheit_of
Возвращает значение температуры по шкале Фаренгейта для передан-
Ного значения по шкале Цельсия.
Absolute_value_of
Возвращает значение температуры в абсолютной шкале для передан-
Ного значения по шкале Цельсия.
Print_preliminary_message
Печать сообщения, поясняющего назначение программы.
Input_table_specifications
Запрос параметров таблицы с клавиатуры.
Print_message_echoing_input
Повторное отображение параметров, введенных пользователем.
Print_table
Печать таблицы температур.
Проверьте свою программу для различных исходных данных. В качестве кон-
трольного примера можете использовать следующие выходные данные:
Эта программа печатает значения температур в разных шкалах.
Введите минимальное (целое) значение температуры
По Цельсию, которое будет в первой строке таблицы: 0
Введите максимальное значение температуры: 100
Введите разницу температур между соседними строками таблицы: 20