Бьерн Страуструп.
Язык программирования С++
24
Типичным примером хорошего стиля в
таком понимании может служить функция извлечения
квадратного корня. Для заданного параметра она выдает результат, который получается с помощью
понятных математических операций:
double sqrt ( double arg )
{
// программа для вычисления квадратного корня
}
void some_function ()
{
double root = sqrt ( 2 );
// ..
}
Двойная наклонная черта // начинает комментарий, который продолжается до конца строки.
При такой
организации программы функции вносят определенный порядок в хаос различных
алгоритмов.
1.2.2 Модульное программирование
Со временем при в
проектировании программ акцент сместился с организации процедур на
организацию структур данных. Помимо всего прочего это вызвано и ростом размеров программ.
Модулем обычно называют совокупность связанных процедур и тех данных, которыми они управляют.
Парадигма программирования приобрела вид:
Определите, какие модули нужны; поделите программу так, чтобы данные были скрыты в этих модулях
Эта парадигма известна также как "принцип сокрытия данных". Если в
языке нет возможности
сгруппировать связанные процедуры вместе с данными, то он плохо поддерживает модульный стиль
программирования. Теперь метод написания "хороших" процедур применяется для отдельных процедур
модуля. Типичный пример модуля - определение стека. Здесь необходимо решить такие задачи:
[1] Предоставить пользователю интерфейс для стека (например, функции push () и pop ()).
[2] Гарантировать, что представление стека (например, в виде массива элементов) будет доступно
лишь через интерфейс пользователя.
[3] Обеспечивать инициализацию стека перед первым его использованием.
Язык Модула-2 прямо поддерживает эту парадигму, тогда как С
только допускает такой стиль. Ниже
представлен на С возможный внешний интерфейс модуля, реализующего стек:
// описание интерфейса для модуля, реализующего стек символов:
void push ( char );
char pop ();
const int stack_size = 100;
Допустим, что описание интерфейса находится в файле stack.h, тогда реализацию стека можно
определить следующим образом:
#include "stack.h"
// используем интерфейс стека
static char v [ stack_size ];
// ``static''
означает локальный
// в данном файле/модуле
static char * p = v;
// стек вначале пуст
void push ( char c )
{
//проверить на переполнение и поместить в стек
}
char pop ()
{
//проверить, не пуст ли стек, и считать из него
}
Бьерн Страуструп.
Язык программирования С++
25
Вполне возможно, что реализация стека может измениться, например, если использовать для хранения
связанный список. Пользователь в любом случае не имеет непосредственного доступа к реализации: v
и p – статические переменные, т.е. переменные локальные в
том модуле (файле), в котором они
описаны. Использовать стек можно так:
#include "stack.h"
// используем интерфейс стека
void some_function ()
{
push ( 'c' );
char c = pop ();
if ( c != 'c' ) error ( "невозможно" );
}
Поскольку данные есть единственная вещь, которую хотят скрывать,
понятие упрятывания данных
тривиально расширяется до понятия упрятывания информации, т.е. имен переменных, констант,
функций и типов, которые тоже могут быть локальными в модуле. Хотя С++ и не предназначался
специально для поддержки модульного программирования, классы поддерживают концепцию
модульности ($$5.4.3 и $$5.4.4). Помимо этого С++, естественно, имеет уже продемонстрированные
возможности модульности, которые есть в С, т.е. представление модуля как отдельной единицы
трансляции.
Достарыңызбен бөлісу: