Парадигмы программирования Императивное, структурное, функциональное, объектноориентированное, обобщённое, автоматное, событийное, мультипарадигмальное. Императивное программирование • Вычисления описываются в виде инструкций, изменяющих состояние программы. • Первый императивный язык – нативный, его структура упрощает исполнение, но затрудняет написание больших программ Императивное программирование • Является отражением архитектуры традиционных ЭВМ (Фон Нэймана) • Теоретическая модель: машина тьюринга • Конкретная машина Тьюринга задаётся перечислением элементов множества букв алфавита A, множества состояний Q и набором правил, по которым работает машина. Они имеют вид: qiaj→qi1aj1dk (если головка находится в состоянии qi, а в обозреваемой ячейке записана буква aj, то головка переходит в состояние qi1, в ячейку вместо aj записывается aj1, головка делает движение dk, которое имеет три варианта: на ячейку влево (L), на ячейку вправо (R), остаться на месте (N)). Для каждой возможной конфигурации <qi, aj> имеется ровно одно правило. Правил нет только для заключительного состояния, попав в которое машина останавливается. Кроме того, необходимо указать конечное и начальное состояния, начальную конфигурацию на ленте и расположение головки машины. Императивное программирование • Переменные – ячейки памяти, команды – последовательный набор действий jmp start _mul proc push bp mov bp,sp mov ax,[bp+4] mul word ptr [bp+6] mov [bp+4],ax mov [bp+6],dx pop bp ret start: mov dx,130h push dx push 100h call _mul pop ax pop bx 1 2 X=Xn Y=ZN(A,B,C,X) WRITE(*,2) X,Y 2 FORMAT (1X,'X=',F5.1,2X,'Y=',F6.2) X=X+H IF (X.LE.Xk) GOTO 1 Структурное программирование • Методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. • Предложена в 70-х годах Э. Дейкстрой, разработана и дополнена Н. Виртом Структурное программирование • Любая программа представляет собой структуру, построенную из трёх типов базовых конструкций: 1. Последовательное исполнение 2. Ветвление 3. Цикл Повторяющиеся фрагменты программы могут быть оформлены в виде процедур и функций Структурное программирование • Наибольшей критике подвергается использование оператора GOTO (безусловного перехода) • Строгое следование позволяет значительно повысить читаемость программы Структурное программирование • Позволяет значительно сократить число вариантов построения программы по заданной спецификации • Логически связанные операторы оказываются визуально ближе, что позволяет обходиться без блок-схем • Сильно упрощается процесс тестирования и отладки Структурное программирование for i:=1 to M do begin sum:=0; for j:=1 to N do sum:=sum+A[i,j]; if sum>max_str_sum then begin max_str_sum:=sum; max_str:=i; end; if sum<min_str_sum then begin min_str_sum:=sum; min_str:=i; end; end; Функциональное программирование • Процесс вычисления трактуется как вычисление значений функций в математическом понимании последних • Чистые функциональные языки не предполагают возможности изменения данных • В отличии от императивных языков, где базовое понятие «переменная» или «ячейка памяти» – здесь только значения Функциональное программирование • Haskell — чистый функциональный. Назван в честь Хаскелла Карри. • LISP (Джон МакКарти, 1958, множество его потомков, наиболее современные из которых — Scheme и Common Lisp). • ML (Робин Милнер, 1979, из ныне используемых диалектов известны Standard ML и Objective CAML). • Miranda (Дэвид Тёрнер, 1985, который впоследствии дал развитие языку Haskell). • Erlang — (Joe Armstrong, 1986) функциональный язык с поддержкой процессов. • Nemerle — гибридный функционально/императивный язык. • F# - функциональный язык для платформы .NET Функциональное программирование • Создание программы приближается к математическому описанию задачи • В чистых функциональных языках нет строгой последовательности действий, поскольку отсутствует «состояние памяти» • Отказ от циклических конструкций в пользу рекурсивных Функциональное программирование • Sisal, быстрая сортировка type Info = array[ integer ] function Main (Data : Info returns Info ) if array_size( Data ) > 2 then let L, Middle, R := for E in Data returns array of E when E < Data[ 1 ] array of E when E = Data[ 1 ] array of E when E > Data[ 1 ] end for in Main( L ) || Middle || Main( R ) end let else Data end if end function Функциональное программирование • Python, быстрая сортировка def qsort(L): if L == []: return [] return qsort([x for x in L[1:] if x< L[0]]) + L[0:1] + qsort([x for x in L[1:] if x>=L[0]]) Объектно-ориентированное программирование • Парадигма программирования, в которой основными концепциями являются понятия объектов и классов o Абстракция данных o Наследование o Инкапсуляция o Полиморфизм Объектно-ориентированное программирование • Понижение производительности: o Динамическое связывание методов o Значительная глубина абстракции o Наследование «размывает» код o Инкапсуляция снижает скорость доступа к данным o Динамическое создание и уничтожение объектов Объектно-ориентированное программирование • Повышается: o Управляемость проекта o Модифицируемость o Скорость разработки Обобщённое программирование • Парадигма программирования, заключающаяся в таком описании данных и алгоритмов, которое можно применять к различным типам данных, не меняя само это описание • Реализовано во многих языках как средство описания алгоритмов с параметризуемыми типами данных. Такие описания не могут быть использованы напрямую Обобщённое программирование • Шаблоны в C++ // Описание шаблонной функции template <typename T> T max(T x, T y) { if (x < y) return y; else return x; } ... // Применение шаблонной функции int a = max(10,15); ... double f = max(123.11, 123.12); Автоматное программирование • Парадигма программирования, при использовании которой программа или её фрагмент осмысливается как модель какого-либо формального автомата Автоматное программирование • Временной период исполнения разбивается на «шаги автомата» • Состояния автомата – набор переменных • Выполнение кода в автоматном стиле представляет собой цикл (возможно неявный) шагов автомата Автоматное программирование • Императивная программа: #include <stdio.h> int main(void) { int c; do { c = getchar(); while(c == ' ') c = getchar(); while(c != EOF && c != ' ' && c != '\n') { putchar(c); c = getchar(); } putchar('\n'); while(c != EOF && c != '\n') c = getchar(); } while(c != EOF); return 0; } Автоматное программирование #include <stdio.h> int main(void) { enum states { before, inside, after } state; int c; state = before; while((c = getchar()) != EOF) { switch(state) { case before: if(c == '\n') { putchar('\n'); } else if(c != ' ') { putchar(c); state = inside; } break; case inside: switch(c) { case ' ': state = after; break; case '\n': putchar('\n'); state = before; break; default: putchar(c); } break; case after: if(c == '\n') { putchar('\n'); state = before; } } } return 0; } Автоматное программирование Событийное программирование • Явным образом выделяется главный цикл приложения, тело которого состоит из выборки и обработки событий Событийное программирование • При построении пользовательских интерфейсов • При создании серверных приложений • В программировании игр Событийное программирование • • • • Nginx Lighttpd Squid QT Мультипарадигмальное программирование • Программирование с одновременным использованием нескольких парадигм программирования • Наиболее известным примером можно назвать C++, который был расширен