Файл: Обзор языков программирования высокого уровня (Теоретические основы языков программирования).pdf
Добавлен: 28.03.2023
Просмотров: 145
Скачиваний: 2
Подобные языки получили название высокоуровневых языков программирования. Программы, составляемые на таких языках, представляют собой последовательности операторов, структурированные согласно правилам рассматривания языка(задачи, сегменты, блоки и т.д.). Операторы языка описывают действия, которые должна выполнять система после трансляции программы на МЯ.
Таким образ ом, к омандные п ослед овательн ости (пр оцедуры, п одпр ограммы), част о исп ользуемые в машинных пр ограммах, представлены в высокоур овневых языках отдельными операт орами. Пр ограммист п олучил в озможн ость не расписывать в деталях вычислительный пр оцесс на ур овне машинных к оманд, а с осред от очиться на осн овных ос обенн остях алг оритма.
С расширением областей применения вычислительн ой техники в озникла не обх одим ость ф ормализ овать представление п остан овки и решение н овых класс ов задач. Не обх одим о был о с оздать такие языки пр ограммир ования, которые, исп ользуя в данн ой области об означения и термин ол огию, п озв олили бы описывать требуемые алг оритмы решения для п оставленных задач, ими стали пр облемн о - ориентир ованные языки. Эти языки, ориентир ованные на решение определенных пр облем, д олжны обеспечить пр ограммиста средствами, п озв оляющими к ор отк о и четк о ф ормулир овать задачу и п олучать результаты в требуем ой ф орме.
Универсальные языки были с озданы для шир ок ог о круга задач: к оммерческих, научных, м оделир ования и т.д. Первый универсальный язык был разраб отан фирм ой IBM. Он п озв оляет раб отать с симв олами, разрядами, числами с фиксир ованн ой и плавающей запят ой. Язык учитывает включенные во мн огие машины в озм ожн ости прерывания и имеет с о ответствующие операт оры. Предусм отрена в озм ожн ость параллельн ог о вып олнения участк ов пр ограмм.
П оявление н овых технических в озм ожн остей п оставил о задачу перед системными программистами - с оздать пр ограммные средства, обеспечивающие оперативн ое взаим одействие чел овека с ЭВМ их назвали диал оговыми языками[3].
Эти раб оты велись в двух направлениях. С оздавались специальные управляющие языки для обеспечения оперативн ог о в оздействия на пр охождение задач, к от орые с оставлялись на любых раннее неразраб отанных (не диал ог овых) языках.
Разрабатывались также языки, к от орые кр оме целей управления обеспечивали бы описание алг оритм ов решения задач.
Непр оцедурные языки с оставляют группу язык ов, описывающих организацию данных, обрабатываемых п о фиксир ованным алг оритмам (табличные языки и генерат оры отчет ов), и язык ов связи с операци онными системами.
П озв оляя четк о описывать как задачу, так и не обх одимые для её решения действия, таблицы решений дают в озм ожн ость в наглядн ой ф орме определить, какие усл овия д олжны быть вып олнены, прежде чем перех одить к как ому-либ о действию. Одна таблица решений, описывающая нек от орую ситуацию, с одержит все в озм ожные бл ок-схемы реализаций алг оритм ов решения.
Программы, с оставленные на табличн ом языке, удобно описывают сложные ситуации, в озникающие при системн ом анализе.
1.3 К вопросу об эволюционных проблемах языков программирования
Уже на протяжении более чем полувека информационные технологии видоизменяют принципы взаимодействия и работы других сфер общества. Если в начале пути компьютер воспринимался, как вычислительное устройство, способное лишь ускорить вычисления для специалистов, то сейчас тысячи людей по всему миру, в чьи обязанности не входит проведение каких бы то ни было расчётов не только используют различные компьютеризированные устройства каждый день, но зависят от них тем или иным образом.
С момента появления персонального компьютера прошло всего несколько десятилетий, но произошедшие изменения коренным образом изменили не только то, как люди работают, но и то, как они общаются, взаимодействуют и размышляют. В самой же индустрии эти изменения также происходили, и проследить их можно через историю развития главного средства программиста — языка программирования , так как фактически язык программирования является не только набором правил, позволяющим выразить алгоритмическую составляющую задачи для компьютера, но и средством формирования мышления самого программиста.
Условно историю развития языков программирования можно разделить на шесть основных этапов или поколений, где первым будет этап специализированных машин. В этом поколении программирование не существовало, как таковое, однако программы уже существовали. Для каждой конкретной задачи строилась отдельная машина, которая умела исполнять только одну задачу, например, решать систему линейных уравнений заданного вида.
Машина проводила вычисления и выдавала результат, однако, логика её работы, программа по сути, была обусловлена внутренней уникальной схемой, что не позволяло проводить различные вычисления на этой же машине. Важно заметить, что для программирования тогда использовались именно электротехнические элементы, то есть, программист-инженер по сути создавал программу посредством соединения непосредственно устройств, исполнявших операции.
Уникальность, и как следствие дороговизна, привели к тому, что было разработано новое поколение машин — эти устройства, по своей сути, стали первыми программируемыми в полном смысле слова. Языком программирования для этих машин в начале служила коммутационная панель, на которой, соединяя гнёзда различных устройств, программист мог задавать последовательность действий для машины — что уже было достаточно большим различием в синтаксисе языка . Если раньше программист исполнял роль инженера-схемотехника и применял сами компоненты для создания программы, то теперь при программировании он мог использовать универсальные блоки — заранее объединенные группы компонент, имеющие необходимые свойства и умеющие выполнять необходимые операции.
В дальнейшем в связи с развитием оборудования панель была заменена на перфокарты, перфоленты, магнитные ленты и барабаны — однако, программирование всё ещё сводилось к формированию последовательности единиц и нулей. Несмотря на то, что процесс программирования для этих машины был долгим, трудоёмким и дорогостоящим — модифицируемость программ привела к стремительному изменению подхода — больше не было потребности в разработке новой машины для каждой задачи.
Также необходимо обратить внимание на зарождение тенденции к повышению абстракции на этом этапе — ведь программист уже не занимался непосредственно разработкой схемы машины, его задачей стало именно выстраивание программы из уже существующих блоков. Продолжившееся постепенное удешевление компьютеров и повышение производительности привело к кризису программирования. Индустрия могла производить новые компьютеры в некоторых случаях быстрее, чем группа инженеров успевала разработать и отладить достаточно сложную программу для прошлого поколения[4].
Для решения данной проблемы был разработан язык программирования низкого уровня — ассемблер. Ассемблер позволил программисту использовать мнемонические команды, вместо машинных команд, что в значительной степени ускорило работу программистов. Однако, несмотря на наличие мнемонических команд, программа всё ещё являлась прямым указанием последовательности действий для машины, а не средством выражения алгоритма. Этот этап стал большим прорывом, так как сама программа перестала быть для программиста последовательностью нулей и единиц, а превратилась в набор команд.
Однако, стоит отметить, что любая команда ассемблера является лишь обёрткой над набором нулей и единиц, то есть, по сути, позволяет абстрагироваться программисту от некоторой командной последовательности, заменив её мнемонической командой. На смену низкоуровневому ассемблеру пришли алгоритмические языки программирования высокого уровня. Эти языки программирования уже были достаточно далеки от конкретной аппаратной реализации, так как программирование велось в терминах, близких человеку[5].
Целью появления этих языков стало формирование ещё одного уровня абстракции, программист теперь был свободен от решения задач переноса данных внутри машины и мог больше внимания уделять самому алгоритму программы. Именно на этом этапе языки программирования получили программы — компиляторы и интерпретаторы. Оба эти класса программ необходимы для перевода и трансформации текстового представления программы, которое удобно для программиста и построено согласно правилам языка в машинное представление — при этом управляющие команды в большей степени являются средствами языка и не привязаны к аппаратной реализации машины. Важным моментом здесь является то, что язык ассемблер не имеет компилятора, а использует ассемблер (утилита, проводящая сборку бинарной программы для машины из исходного кода, на языке ассемблера называется также) — программу, которая лишь ставит в соответствие мнемоническим символам бинарные последовательности, но не трансформирует программу.
Эти изменения привели к значительному ускорению разработки и удешевлению программ, однако создание больших программ всё ещё оставалось трудоёмким. Одной из основных проблем стала не сложность программирования , а сложность самих программ. Большие программные продукты было очень трудно контролировать, так как не было единого стиля мышления и программирования . Решением этой проблемы занялся ряд выдающихся учёных , в котором особо необходимо отметить имена Эдсгера Дейкстры, Коррады Бёма и Джузеппе Якопини.
За несколько лет в результате работы многих учёных и практиков был сформирован базис структурного подхода к программированию. Отличительной особенностью стало выявление трёх базовых элементов любой программы: последовательность, ветвление и цикл[6].
Такая систематизация не позволяла программе превратиться в разрозненный набор команд, что в свою очередь в значительной мере повысило качество программ и скорость их разработки. Конечно же, формирование правил программирования мгновенно отразилось и на том, как о программе размышлял программист. Если на прошлом этапе программист был избавлен от необходимости думать непосредственно в командах машины и стал вести разработку с помощью команд языка, следя лишь за ходом программы, то теперь программа больше не воспринималась как набор приказов машине, она стала ещё более абстрактной, превратившись в укрупнённые блоки с хорошо видимой структурой, что позволило программистам сконцентрироваться на непосредственных алгоритмах, а не на отслеживании переходов между командами в памяти.
Косвенным подтверждением можно считать резкое увеличение производительности алгоритмов и ряд открытий новых алгоритмов. Однако задачи, которые решались с помощью компьютеров становились всё сложнее, а набор предметных областей — шире. По этой причине на рубеже 70-х годов возникла потребность вновь переработать подход к программированию.
В результате на свет появилась новая концепция — объектно-ориентированный подход.
Отличительной чертой данного подхода является возможность для программиста думать о программе, как о наборе объектов, которые могут взаимодействовать между собой и имеют собственное состояние. Такой подход упрощает восприятие и структуру программы, так как сводит многие трудные для понимания вещи к вещам из реального мира, думать о которых на этапе разработки проще. Стоит отметить, что объектно-ориентированный подход является именно подходом, а не самостоятельным языком. Объектно-ориентированный подход есть не что иное, как способ повышения уровня абстракции при работе над программой, а точнее, способ размышления о предметной области — то есть, полностью свести размышление о программе к абстрактным сущностям.
Именно такой подход является наиболее популярным, хотя и подвергается множественной критике и имеет ряд недостатков. Так, например, с каждым повышением уровня абстракции возникает дополнительная нагрузка, с которой приходится справляться вычислителю, что снижает эффективность программ. С другой стороны, повышение уровня абстракции позволяет избегать многих ошибок, так как программист избавлен от необходимости прямо указывать действия машине. Краткое рассмотрение истории развития языков программирования позволяет очень чётко выделить общую тенденцию. Языки программирования с самого своего зарождения развиваются по направлению повышения абстрактности при программировании, что является упрощением взаимодействия между программистом и машиной[7].
Таким образом, история развития языков программирования наглядно демонстрирует, что главной проблемой при программировании является наличие ошибок в программе, а не её вычислительная сложность. Действительно, с проблемой снижения эффективности можно бороться путём увеличения производительности самих машин, но подобный подход не позволяет бороться с ошибками в программах. Любая ошибка в программе стоит гораздо дороже, чем дополнительная память или процессорное время, так как сводит полезность программы к нулю. Однако, подход наращения производительности был крайне эффективен в 90-х годах.