Развитие языков программирования. Эволюция вычислительных систем

Первые языки программирования возникли в 20-е, 30-е годы ХХ столетия и были довольно примитивны и ориентированы на численные расчеты (математические и физические) и прикладные задачи, в частности, в области военного дела.

Программы, написанные на ранних языках программирования, были оптимизированы под аппаратную архитектуру конкретного компьютера, для которого предназначались. Они обеспечивали высокую эффективность вычислений, но до стандартизации было еще далеко. Программа, которая была вполне работоспособной на одной вычислительной машине, зачастую не могла выполняться на другой. Таким образом, ранние языки программирования зависели от того, что принято называть средой вычислений и приблизительно соответствовали современным машинным кодам или языкам ассемблер. Это так называемые низкоуровневые языки программирования.

Язык программирования считается языком низкого уровня, если он ориентирован на конкретный тип процессора и учитывает его особенности (операторы языка близки к машинному коду и ориентированы на конкретные команды процессора). Подобные языки обычно применяются для написания небольших системных приложений, драйверов устройств. Примером такого языка может служить Ассемблер (assembler – сборщик), который появился в конце 50-х – начале 60-х г.г.

Следующее поколение языков программирования – языки высокого уровня. Различие состоит в повышении эффективности труда разработчиков за счет абстрагирования от конкретных деталей аппаратного обеспечения. Одна инструкция (оператор) языка высокого уровня соответствовала последовательности из нескольких низкоуровневых инструкций, или команд. Исходя из того, что программа, по сути, представляла собой набор директив, обращенных к компьютеру, такой подход к программированию получил название императивного.

Еще одной особенностью языков высокого уровня была возможность использования ранее написанных программных блоков, которые получили название функций и процедур.

Кроме того, с появлением языков высокого уровня зависимость реализации от аппаратного обеспечения существенно уменьшилась. Платой за это стало появление специальных программ-трансляторов.

Первым языком, для которого был реализован транслятор, стал FORTRAN (FORmula TRANslator) _ для трансляции формул. Первые версии FORTRANа не знали понятия подпрограмма. Она появилась в нем позже, предвосхитив идею модульного программирования.

Многие из первых языков высокого уровня оказались настолько удачно реализованными, что активно используются и сегодня: FORTRAN, PASCAL, BASIC.

Следующим этапом в развитии технологии программирования стала концепция структурного программирования. Структурный подход предполагает использование только нескольких основных структур (следование, разветвление, цикл), комбинация которых дает все многообразие алгоритмов и программ. Данный подход содержит в себе несколько идей, позволяющих представлять алгоритмы в виде блочной структуры, а не при помощи нагромождений операторов перехода GOTO. Эти идеи определили синтаксис нового языка программирования ALGOL. Вот отличительные черты этого языка:

- операторные скобки, синтаксически объединяющие группу операторов в один оператор-блок;

- условный оператор с альтернативой (IF…THEN…ELSE…);

- несколько разновидностей цикла;

- кроме того, появилось требование обязательного описания данных.

Если удалось структурировать алгоритм, то почему бы ни структурировать и данные? Эта идея была заложена в концепцию абстракции данных. Смысл ее состоял в том, чтобы позволить программисту описывать новые типы данных со сколь угодно сложной структурой и работать с ними как с единым целым. Такой подход был впервые реализован в языке PASCAL.

С течением времени программные проекты становились сложнее и больше по размеру. Развитие технологии программирования требовало подхода, который бы позволил выделять алгоритмы, данные и описания новых типов в независимые блоки – модули.

Модуль – логически взаимосвязанная совокупность функциональных элементов, оформленных в виде отдельных программ.

Модульное программирование основано на понятии модуля.Принципы модульного программирования программных продуктов во многом сходны с принципами нисходящего проектирования.

Метод нисходящего проектирования предполагает последовательное разложение общей функции обработки данных на простые функциональные элементы методом «сверху - вниз», от целого к части.

В результате строится иерархическая схема, отражающая состав и взаимоподчиненность отдельных функций, которая носит название функциональная структура алгоритма (ФСА) приложения. Каждый отдельный элемент ФСА описывает законченную содержательную функцию обработки информации, которая предполагает определенный способ реализации на программном уровне. Функции ввода-вывода информации рекомендуется отделять от функций вычисления или логической обработки данных.

Подобная структура приложения отражает наиболее важное – состав и взаимосвязь функций обработки информации для реализации приложений (хотя и не раскрывает логику выполнения каждой отдельной функции, условия или периодичность их вызовов).

При модульном подходе сначала определяются состав и подчиненность функций, а затем – набор программных модулей, реализующих эти функции. Однотипные функции реализуются одними и теми же модулями. Функция верхнего уровня обеспечивается главным модулем, который управляет выполнением нижестоящих функций, реализуемых подчиненными модулями.

В результате создается функционально-модульная схема (ФМС) алгоритма приложения, которая является основой для программирования.

Программа может состоять из нескольких модулей. Каждый модуль имеет главную часть. В ней описываются процедуры и функции модуля.

Один из модулей называется главным. Он содержит так называемую точку входа, с которой начинается выполнение программы. В каждой программе может быть только один главный модуль. К главному модулю можно подключить вспомогательные (дополнительные) модули.

 

Преимущества модульного программирования:

- т.к. вспомогательные модули – это отдельные файлы программ, в них обычно выносятся процедуры и функции, которые используются одновременно в нескольких программах;

- это позволяет избежать ситуации, когда одна и та же процедура существует в нескольких вариантах в каждой программе;

- если вы исправляете или дополняете какую-либо процедуру или функцию из вспомогательного модуля, то все исправления автоматически становятся доступны всем программам, которые эти модули используют.

 

В языках, ориентированных на модульный подход, предусмотрены специальные средства, позволяющие создавать подпрограммы, устанавливать жесткий контроль типов, определять видимость (область определения) переменных и процедур. В таких модулях различают раздел описания и раздел реализаций.

 

Структурное программирование основано на модульной структуре программного продукта и типовых управляющих структурах алгоритмов обработки данных различных программных модулей. В любой типовой структуре блок, кроме условного (который имеет два выхода), имеет только один вход и один выход. Виды основных управляющих структур – последовательность, альтернатива (условие выбора), цикл.

 

Важным шагом по пути к совершенствованию языков программирования стало появление объектно-ориентированного подхода к программированию и соответствующего класса языков. В рамках данного подхода программа представляет собой описание объектов, их свойств, совокупностей, отношений между ними, способов их взаимодействия и операций над объектами (методов). Важным свойством объектно-ориентированного подхода является поддержка механизма обработки событий, которые изменяют атрибуты объектов и моделируют их взаимодействие.

Объектно-ориентированное программирование снабжает программные объекты встроенными характеристиками. Важнейшими характеристиками объектной парадигмы[1] являются:

- инкапсуляция – это понятие означает, что в качестве единого целого, называемого объектом, рассматриваются некоторая структура данных, определяющая его свойства, и некоторая группа функций;

- наследование – позволяет одним объектам приобретать атрибуты и поведение других. Группы более низкого уровня наследуют характеристики групп более высоких уровней;

- полиморфизм – множественность форм, которые может принимать правило с одним и тем же именем.

В концепции объектно-ориентированного программирования новый подход заключается в объединении данных и алгоритмов (функций), относящихся к одному типу объектов, в единое описание классов объектов (инкапсуляция). При этом алгоритмы называются методами данного класса. Каждый объект объединяет в себе как данные, так и программу обработки этих данных. Программный продукт, созданный с помощью инструментальных средств объектно-ориентированного программирования, содержит объекты с их характерными свойствами, для которых разработан графический интерфейс пользователя.

Кроме того, в объектно-ориентированных языках предусмотрен механизм порождения классов – когда порождаемый класс наследует данные и методы порождающего класса. При этом имеет место полиморфизм методов – метод с одним именем может исполняться по-разному для порождаемого и порождающего классов (в порождаемый класс можно добавить новые данные).