Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КРАТКИЙ ОБЗОР С.doc
Скачиваний:
4
Добавлен:
26.10.2018
Размер:
2.11 Mб
Скачать

Начало формы

Конец формы

* КРАТКИЙ ОБЗОР С++

1.2 Парадигмы программирования

Паради́гма программи́рования — это совокупность идей и понятий, определяющая стиль написания программ Объектно-ориентированное программирование - это метод программирования, способ написания "хороших" программ для множества задач. Если этот термин имеет какой-то смысл, то он должен подразумевать: такой язык программирования, который предоставляет хорошие возможности для объектно-ориентированного стиля программирования. Здесь следует указать на важные различия. Говорят, что язык поддерживает некоторый стиль программирования, если в нем есть такие возможности, которые делают программирование в этом стиле удобным (достаточно простым, надежным и эффективным). Язык не поддерживает некоторый стиль программирования, если требуются большие усилия или даже искусство, чтобы написать программу в этом стиле. Однако это не означает, что язык запрещает писать программы в этом стиле. Действительно, можно писать структурные программы на Фортране и объектно-ориентированные программы на С, но это будет пустой тратой сил, поскольку данные языки не поддерживают указанных стилей программирования.   Поддержка языком определенной парадигмы (стиля) программирования явно проявляется в конкретных языковых конструкциях, рассчитанных на нее. Но она может проявляться в более тонкой, скрытой форме, когда отклонение от парадигмы диагностируется на стадии трансляции или выполнения программы. Самый очевидный пример - это контроль типов. Кроме того, языковая поддержка парадигмы может дополняться проверкой на однозначность и динамическим контролем. Поддержка может предоставляться и помимо самого языка, например, стандартными библиотеками или средой программирования.

1.2.1 Процедурное программирование

      Первоначальной (и, возможно, наиболее используемой) парадигмой программирования было:       Определите, какие процедуры вам нужны; используйте лучшие из известных вам алгоритмов!       Ударение делалось на обработку данных с помощью алгоритма, производящего нужные вычисления. Для поддержки этой парадигмы языки предоставляли механизм передачи параметров и получения результатов функций. Литература, отражающая такой подход, заполнена рассуждениями о способах передачи параметров, о том, как различать параметры разных типов, о различных видах функций (процедуры, подпрограммы, макрокоманды, ...) и т.д. Первым процедурным языком был Фортран, а Алгол60, Алгол68, Паскаль и С продолжили это направление.       Типичным примером хорошего стиля в таком понимании может служить функция извлечения квадратного корня. Для заданного параметра она выдает результат, который получается с помощью понятных математических операций:       double sqrt ( double arg )       {       // программа для вычисления квадратного корня       }       voide 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 ()       {       //проверить, не пуст ли стек, и считать из него       }       Вполне возможно, что реализация стека может измениться, например, если использовать для хранения связанный список. Пользователь в любом случае не имеет непосредственного доступа к реализации: v и p - статические переменные, т.е. переменные локальные в том модуле (файле), в котором они описаны. Использовать стек можно так:       #include "stack.h" // используем интерфейс стека       void some_function ()       {       push ( 'c' );       char c = pop ();       if ( c != 'c' ) error ( "невозможно" );       }       Поскольку данные есть единственная вещь, которую хотят скрывать, понятие упрятывания данных тривиально расширяется до понятия упрятывания информации, т.е. имен переменных, констант, функций и типов, которые тоже могут быть локальными в модуле. Хотя С++ и не предназначался специально для поддержки модульного программирования, классы поддерживают концепцию модульности ($$5.4.3 и $$5.4.4). Помимо этого С++, естественно, имеет уже продемонстрированные возможности модульности, которые есть в С, т.е. представление модуля как отдельной единицы трансляции.