Компьютеры (или компьютерные системы) используются во всем мире, практически в любом окружении. Они применяются на предприятиях, дома, в государственных учреждениях и благотворительных организациях. Специализированные компьютеры можно встраивать в телевизоры, кассовые аппараты, акустические системы и прочие электронные устройства - их устанавливают даже в кухонной технике, например, в плитах и холодильниках, а также в автомобилях и самолетах и др.
Управление современными компьютерами осуществляется с помощью специальных программ, без которых вся техника превратилась бы в бесполезный набор металла. Сегодня компьютерной системой, как правило, управляет совокупность программ, поэтому вместо слова программа чаще используется более широкое понятие программное обеспечение (ПО, англ. Software) - совокупность компьютерных программ, соответствующей документации и данных, относящихся к функционированию компьютерной системы. В качестве синонимов часто используют понятия «программный продукт», «программный комплекс», «приложение» и т.д.
На Рисунках 1.1.1‑1.1.3 приведены примеры компьютерных систем и приложений.
Рисунок 1.1.1 - Система управления истребителя СУ-35[51]¶
Рисунок 1.1.2 - Компьютерная система на фондовой бирже [52]¶
Рисунок 1.1.3 - Система дистанционного банковского обслуживания Сбербанк.Онлайн [53]¶
В общем случае программное обеспечение делится на 2 типа: системное и прикладное (Рисунок 1.1.4).
Программное обеспечения подразделяется на три основные группы:
заказное ПО;
ПО для корпоративного потребителя;
ПО для массового потребителя.
Они появлялись друг за другом с интервалом примерно в десятилетие.
В настоящее время процесс разработки программного обеспечения включает следующие подпроцессы:
1. Анализ требований
Задачи: сбор, анализ и документирование требований к программному обеспечению.
Результат: спецификация требований: законченное описание поведения программы, которую требуется разработать.
2. Проектирование
Задачи: определение внутренних свойств системы и детализации ее внешних (видимых) свойств на основе спецификация требований.
Результат: архитектура программного обеспечения (решения по организации компонентов программного обеспечения и их взаимодействия), а также пользовательские интерфейсы (если необходимы).
3. Программирование
Задачи: создание и использование алгоритмов и структур данных в рамках архитектуры и в соответствии со спецификацией требований.
Задачи: создание проектной, технической, пользовательской и прочей документации, описывающей вопросы использования программного продукта.
Результат: документация к программному обеспечению.
5. Тестирование
Задачи: исследование продукта на соответствие спецификации требований, выявление возможных ошибок и исправление несоответствий.
Результат: доработанное программное обеспечение с учетом ошибок и исправлений.
6. Системная интеграция и Внедрение в эксплуатацию
Задачи: настройка ПО для работы в компьютерной экосистеме пользователя/заказчика, а также обучение конечных пользователей.
Результат: программное обеспечение, функционирующее и используемое целевыми пользователями.
7. Сопровождение
Задачи: оперативное реагирование на обнаруженные дефекты в работе программного обеспечения, новые требования и т.д.
Результат: материалы для запуска очередного цикла разработки.
Период времени, начинающийся с момента принятия решения о необходимости создания программного продукта и заканчивающийся в момент его полного изъятия из эксплуатации называется жизненным циклом. В процессе курса так или иначе Вы коснетесь каждого из этапов, однако этап программирования, несомненно, будет основным.
Каждый этап жизненного цикла является отдельной сложной задачей, для выполнения которой выделяется отдельный специалист или группа специалистов. На Рисунке 1.1.6. приведен возможный пример команды по разработке программного обеспечения. Как правило каждый специалист занят в нескольких этапах разработки ПО, что необходимо для разработки качественного программного обеспечения.
Рисунок 1.1.6 - Пример Agile-команды по разработке ПО [56]¶
На Видео 1.1.1 приведено обобщенное описание профессий в сфере информационных технологий.
Видео 1.1.1 - Профессии в мире информационных технологий
Независимо от роли в ИТ-проекте, знания о процессе разработки ПО и непосредственно навыки программирования являются необходимыми для успешной работы.
Насколько рассмотренные выше направления работы в ИТ-сфере являются востребованными и перспективными? В Таблице 1.1.1 и приведены ТОП-10 самых востребованных и самых высокооплачиваемых профессий в России по данным портала EduNews.
Таблица 1.1.1 - ТОП-10 профессий в России по критериям: уровень оплаты, востребованность в народном хозяйстве, перспективность работы и возможности развития сотрудника [9]¶
Востребованность
№
Профессия
1
Инженер
2
IT-специалист
3
Топ-менеджер
4
Врач
5
Пилот
6
Нефтяник
7
Эколог
8
Химик
9
Переводчик
10
Стоматолог
Краткий обзор зарплат специалистов ИТ-сферы приведен в исследовании [27] (на 2022 г.):
Примечание
Актуальную статистику зарплатных предложений можно посмотреть, например, на ресурсах Хабр Карьера или Superjob.
Компьютер создавался как устройство для выполнения двух простых операций:
численных вычислений;
сохранения результатов этих вычислений,
но даже самый примитивный компьютер справляется с этими задачами намного быстрее человека. С тех пор мало что изменилось: используете Вы ноутбук, мобильное устройство или суперкомпьютер в научно-исследовательском центре - отличаться будет только скорость осуществления и объем запоминаемых вычислений.
Изобретение компьютера было настоящей революцией, которая помогла человечеству преодолеть ограничения человеческого мозга по возможности счета и запоминания информации. Множество продуктов и услуг, без которых нельзя представить свою жизнь (от еды до сложной военной техники) во многом обязаны своим появлением этому изобретению.
В то же время человек по-прежнему определяет главное: как выполнять вычисления, предоставляя компьютеру набор инструкций, описывающих порядок действий для достижения некоторого результата. Такая последовательность инструкций традиционно называется алгоритмом. В свою очередь, алгоритм, записанный на формальном языке (языке программирования), который можно было бы «донести» до компьютера, называется программой.
Алгоритм как набор инструкций, описывающих порядок действий исполнителя для достижения результата решения задачи за конечное число действий, может быть записан в различных формах (в качестве примера приведена задача определения стоимости произвольного количества яблок):
Словесная форма: запись на естественном языке.
Для того, что узнать стоимость имеющихся яблок, необходимо:
- узнать вес имеющихся яблок в кг.;
- узнать стоимость 1 кг. яблок;
- получить ответ, перемножив полученные величины.
Графическая форма: изображения из графических символов, как правило, в специальной нотации.
В качестве простой графической нотации описания алгоритмов часто используются блок-схемы, регламентируемые ГОСТ 19.701-90 «Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения. В англоязычном ИТ-сегменте аналогом являются диаграммы Flowchart.
Псевдокоды: полуформализованные описания алгоритмов на условном алгоритмическом языке.
- завести величины X, Y, P вещественного типа;
- ввести с клавиатуры вес имеющихся яблок в кг. как X;
- ввести с клавиатуры стоимость 1 кг. яблок как Y;
- P = X * Y;
- вывести на экран P.
Программная форма: тексты на языках программирования.
Программная форма записи идет последней - каждый раз, решая какую-либо задачу, необходимо пройти путь (устно или в любой другой удобной форме) от словесного описания алгоритма к формализованному, готовому к отображению на языке программирования.
Любой алгоритм должен обладать следующими свойствами:
Дискретность: алгоритм разбивается на конечное число элементарных действий (шагов).
Понятность: каждое из этих элементарных действий является законченным и понятным.
Детерминированность: каждое действие должно пониматься в строго определенном смысле (пониматься однозначно).
Массовость: по данному алгоритму должна решаться не одна, а целый класс подобных задач.
Результативность: любой алгоритм в процессе выполнения должен приводить к определенному результату (в т.ч. отрицательному).
В качестве примера рассмотрим алгоритма кипячения воды в электрическом чайнике (с точки зрения человека), один из возможных вариантов которого мог бы выглядеть следующим образом:
Любой алгоритм (в том числе и приведенный выше) необходимо усложнять и/или разбивать на дополнительные шаги до тех пор, пока он не будет удовлетворять всем 5 свойствам для конкретного исполнителя (человека, компьютера или кого-либо еще) (Видео 1.1.2).
Выполнение определенной задачи на произвольных (изменяемых) данных
Видеоплееры, CD-проигрыватель и др.
3
Выполнение произвольной (изменяемой) задачи на произвольных (изменяемых) данных
Современные компьютеры
Все такие устройства могут считаться компьютером (англ. Computer — «вычислитель»), под которым в широком смысле понимается любое устройство или система, способное выполнять заданную четко определенную изменяемую последовательность операций (численных расчетов и манипулирования данными, операции ввода-вывода). Используемое нами в повседневной жизни понятие «компьютер» - это электронная вычислительная машина (ЭВМ) - одна из реализация компьютера, которая подразумевает использование электронных компонентов в качестве ее функциональных узлов.
Способность к выполнению произвольной программы без необходимости физической переконфигурации является фундаментальной особенностью современных компьютеров и появилась она далеко не сразу [28].
Изначально человечество шло по первому пути и вычислительные устройства были способны выполнять лишь заранее заложенные инструкции (как правило, математические вычисления), ограниченные конфигурацией самих устройств. Фундаментальный недостаток подобной архитектуры - необходимость полной физической переконфигурации для выполнения других задач.
Рисунок 1.1.7 - «Паскалина» (1642 г.) - первое реально осуществленное и получившее известность механическое цифровое вычислительное устройство, изобретенное французским ученым Блезом Паскалем. Прототип устройства суммировал и вычитал пятиразрядные десятичные числа [57]¶
Рисунок 1.1.8 - Арифмометр - вычислительная машина, предназначенная для точного умножения и деления, а также для сложения и вычитания [58]¶
Рисунок 1.1.9 - Логарифмические линейка - аналоговое вычислительное устройство, позволяющее выполнять несколько математических операций. Принцип действия основан на том, что умножение и деление чисел заменяется соответственно сложением и вычитанием их логарифмов [59]¶
Известная электронно-механическая машина Turing Bombe, созданная английским математиком, логиком и криптографом Аланом Тьюрингом, и использовавшаяся во время Второй мировой войны для расшифровки «Энигмы» (немецкой шифровальной машины) также являлась непрограммируемым устройством (Рисунок 1.1.10).
Рисунок 1.1.10 - Дешифровальная машина Bombe [60]¶
Современные электронные калькуляторы также являются устройствами данного класса - их можно использовать для счета, но не в качестве игровой консоли или средства моделирования.
Первой попыткой «программирования» устройства был ткацкий станок французского изобретателя Жозефа Мари Жаккарда (1801 г.), где вышивка определялась «динамически» - перфокартой . Перфокарта содержала информацию наличием или отсутствием отверстий в определенных позициях карты и в дальнейшем стала предшественником современных устройств ввода информации (магнитной ленты, дискет, дисков, флеш-памяти и др.) (Рисунки 1.1.11‑1.1.12).
Рисунок 1.1.11 - Ткацкий станок с управлением с помощью перфокарт [61]¶
Рисунок 1.1.12 - Заполненная перфокарта конца XX века [62]¶
К середине XIX века английский математик Чарлз Бэббидж разработал проект аналитической машины — прообраза современной ЭВМ (Рисунок 1.1.13).
В аналитической машине Бэббидж предусмотрел следующие части:
склад (хранение данных и результатов обработки);
фабрика или мельница (производит операции над данными);
управляющий элемент (control);
устройства ввода‑вывода информации.
Для создания компьютера в современном понимании оставалось лишь придумать схему с хранимой программой, что было сделано 100 лет спустя в проекте ЭНИАК.
Коллега Бэббиджа Ада Лавлейс принимала участие в создании описания машины, составила первую в мире программу для этой машины (вычисление чисел Бернулли), а также ввела в употребление термины «цикл» и «рабочая ячейка», и считается первым программистом в истории.
В конце XIX века на основе идеи Беббиджа американский инженер Герман Холлерит создает первый табулятор - электромеханическую машину, предназначенную для автоматической обработки (суммирования и категоризации) числовой и буквенной информации, записанной на перфокартах, с выдачей результатов на бумажную ленту или специальные бланки (Рисунок 1.1.14).
Идея хранение программы в памяти устройства начала зарождаться в 1936 г., когда Алан Тьюринг описал гипотетическую машину (названную им универсальной вычислительной машиной), известной сегодня как Машина Тьюринга. Машина имела бесконечное хранилище в виде ленты (память в современной терминологии), содержащее как данные, так и инструкции для манипулирования ими (в виде 0 и 1), а также имела простые инструкции для чтения/записи и перемещения этой ленты. Тезис Черча-Тьюринга гласил о том, что если какой‑либо процесс является вычисляемым, машина Тьюринга сможет его вычислить (быть запрограммирована для вычисления) [29].
Архитектура фон Неймана
Венгеро‑американский математик Джон фон Нейман, впечатленный работами Тьюринга, во время работы в Манхэттенском проекте был привлечен к работе над компьютером с хранимой в памяти программой. В это время он сформулировал идею архитектуры такого устройства, названной в последствии архитектурой фон Неймана, которая используется в виде базовой в большинстве современных ЭВМ (Рисунок 1.1.15).
Рисунок 1.1.15 - Архитектура фон Неймана (одинарные линии показывают управляющие связи, двойные — информационные) [65]¶
Основные положения:
Компьютер состоит из нескольких основных устройств (арифметико‑логическое устройство, управляющее устройство, память, внешняя память, устройства ввода и вывода).
Арифметико‑логическое устройство выполняет логические и арифметические действия, необходимые для переработки информации, хранящейся в памяти.
Управляющее устройство обеспечивает управление и контроль всех устройств компьютера (управляющие сигналы указаны пунктирными стрелками).
Инструкции (программы) и данные хранятся в одном и том же запоминающем устройстве и не должны быть «вшиты» в логику работы устройства.
Данные, которые хранятся в запоминающем устройстве, представлены в двоичной форме.
Память делится на ячейки одинакового размера (как правило, степень 2, например 8 бит), порядковый номер ячейки считается ее адресом.
Выполнение кода программы на компьютере с архитектурой фон Неймана определяет командный цикл (fetch-execute cycle) [30]. Т.к. программа находится в памяти, а выполняет ее процессор [48], необходимо каждую инструкцию предварительно скопировать из памяти в память процессора (регистр). Адрес следующей команды сохраняется в процессоре в программном счетчике.
В простом виде командный цикл выглядит следующим образом:
инициализировать программный счетчик
бесконечный цикл
получить команду, на которую указывает программный счетчик
увеличить значение программного счетчика, чтобы он указывал на следующую команду
декодировать команду
выполнить команду
конец цикла
Этап декодирования необходим для определения, какое действие необходимо выполнить. Выполнение программы завершается при обнаружении команды остановки.
Одним из первых по‑настоящему современных компьютеров, реализующим архитектуру фон Неймана, был британский Манчестерский Марк I (1949 г.) - полностью электронный компьютер с хранимой в оперативной памяти программой (Рисунок 1.1.16). Аналогичные компьютеры (на собственной элементной базе) с разницей в несколько лет появились в дальнейшем в СССР, США и других странах.
Марк I имел длину около 17 м., включал в себя 75 тысяч электронных ламп и выполнял операцию сложения за 3 с. (Видео 1.1.3).
Видео 1.1.3 - Машина Марк I
С тех пор совершенствовалась элементная база ЭВМ (изобретаются транзисторы, микропроцессоры и т.д.), компьютеры становились дешевле и доступнее массовому потребителю и спустя несколько десятилетий компьютер становится таким, каким мы знаем его сегодня.
Схематично данный процесс выглядел так, как показано на Рисунке 1.1.20.
Рисунок 1.1.20 - Схематичный процесс решения задачи на первых компьютерах¶
С ростом сложности вычислений увеличивалось количество деталей и расходных материалов устройства, поэтому очевидно, что таким способом можно было составить только небольшие программы.
С реализацией ЭВМ на основе идей фон Неймана программист мог больше не заботиться о знании всех двоичных команд устройства, оперируя командами контроллера, что положило начало развитию языков программирования.
Язык программирования - формальная знаковая система, предназначенная для записи компьютерных программ.
Со времени создания первых программируемых машин человечество придумало более 8000 языков программирования, каждый год их число увеличивается. Профессиональные программисты, как правило, владеют несколькими языками программирования.
От естественных языков язык программирования отличается тем, что предназначен для взаимодействия человека с ЭВМ, а не для общения людей между собой.
Язык программирования определяет набор правил:
лексических (словарный запас языка);
синтаксических (набор правил, описывающий комбинации символов алфавита, считающиеся правильно структурированной программой (документом) или ее фрагментом);
семантических (начальное смысловое значение операторов, основных конструкций языка и т.п.).
которые задают внешний вид программы и действия, которые выполнит исполнитель под ее управлением.
Как правило, язык программирования существует в нескольких, но существенно отличающихся видах:
стандарта языка: набора спецификаций, определяющих его синтаксис и семантику; стандарт языка может исторически развиваться;
воплощений (реализаций) стандарта: собственно программных средств, обеспечивающих работу согласно тому или иному варианту стандарта языка.
Например, язык С++ имеет официальный стандарт (ISO/IEC 14882:2014) и различные реализации: GNU C++, Microsoft Visual C++ и др.
Первым языком программирования можно считать Машинный код где каждая инструкция выполняет определенное действие:
операция с данными (например, сложение или копирование машинного слова в регистре или в памяти);
переход к другому участку кода (изменение порядка исполнения; переход может быть безусловным или условным, зависящим от результатов предыдущих инструкций)
при этом представляя несколько 0 и 1 в более удобном виде.
Любая исполнимая программа состоит из последовательности таких атомарных машинных операций. При исполнении очередной инструкции специальный блок процессора — декодер — транслирует (декодирует) ее в последовательность элементарных операций, понимаемых конкретными исполнительными устройствами.
Пример одного из вариантов программы для вывода на экран фразы «Hello, world!» на машинном коде (в шестнадцатеричном и двоичном представлении) приведен в Листинге 1.1.1.
Листинг 1.1.1 - «Hello, world!» в машинном коде (в шестнадцатеричном и двоичном представлении) [74]¶
Попытка сделать машинные команды более человекочитаемыми привели к созданию языков ассемблера (1950‑е гг.). Команды языков данного вида как правило один в один соответствуют командам процессора и, фактически, представляют собой удобную символьную форму записи (мнемокод) команд и их аргументов.
Код на языке ассемблера в конечном итоге переводится в машинный код, используя специальную программу-преобразователь (транслятор), называемую ассемблером.
Программа из Листинга 1.1.1, записанная на языке ассемблера приведена в Листинге 1.1.2.
Листинг 1.1.2 - «Hello, world!» на языке ассемблера [74]¶
1XXXX:0100 mov bx, 0111h ; поместить в bx смещение строки HW
2XXXX:0103 mov cx, 000Dh ; поместить в cx длину строки HW
3XXXX:0106 mov ah, 0Eh ; поместить в ah номер функции прерывания 10h
4XXXX:0108 mov al, [bx] ; поместить в al значение ячейки памяти, адрес которой находится в bx
5XXXX:010A inc bx ; перейти к следующему байту строки (увеличить смещение на 1)
6XXXX:010B int 10h ; вызов прерывания 10h
7XXXX:010D loop 0108 ; если cx≠0, то уменьшить cx на 1 и перейти по адресу 0108
8XXXX:010F int 20h ; прерывание 20h: завершить программу
9XXXX:0111 HW db 'Hello, World!' ; строка, которую требуется напечатать
Несомненным плюсом языков ассемблера по сегодняшний день является крайне эффективная работа программы (быстрый и компактный код).
В то же время поддержка подобной программы крайне трудоемка, код пишется для конкретного устройства, и ее перенос на другие устройства влечет за собой практически полное переписывание, что послужило причиной появления языков высокого уровня.
Примечание
Сегодня на языках ассемблера пишут программы или их фрагменты в тех случаях, когда критически важны:
объем используемой памяти (загрузочные секторы, встраиваемое программное обеспечение, программы для микроконтроллеров и процессоров с ограниченными ресурсами, вирусы, программные защиты).
Участки кода на языке ассемблера также могут встраиваться в другие языки (например, C++) для оптимизации критичных участков кода.
Машинный код и языки ассемблера традиционно относят к языкам низкого уровня - программирование на них осуществляется либо непосредственно в машинных кодах используемого реального или виртуального процессора, либо приближено к этому.
В скором времени начинает преобладать идея, что человек должен писать программы на более легком для него языке, чем машинные коды, а трудоемкий перевод в машинный код переложить на другую программу (транслятор), при этом транслятор также должен уметь в какой-либо степени делать перевод на машинный код различных устройств. Данная идея лежит в основе всех современных языков программирования.
Языки программирования, которые имеют достаточный уровень абстракции - оперируют сложными структурами данных и умеют выполнять над ними комплексные операции (что в машинном коде повлекло бы длинные и сложные цепочки кода), относят к языкам высокого уровня. Примеры таких языков - C, Pascal, Python, Java и др.
В общем случае целью создания новых языков программирования было упрощение написание программ и повышение уровня абстракции (от команд конкретной машины к языку человека).
На Рисунке 1.1.21 приведено дерево развития наиболее известных языков программирования по конец 2000-х гг. (рост идет и в настоящий момент). Еще один вариант дерева приведен тут [73].
Рисунок 1.1.21 - Дерево наиболее известных языков программирования высокого уровня [4]¶
На Видео 1.1.4 приведен краткий исторический обзор языков программирования (англ.).
Видео 1.1.4 - History Of Programming (Educational Video)
Исторически первым спроектированным языком программирования высокого уровня был Планкалкюль (нем. Plankalkül - исчисление планов), созданный немецким инженером Конрадом Цузе в 1943-45 году и впервые опубликованный в 1948 году.
Планкалкюль обладал многими возможностями, которыми обладают современные языки, однако, работа в отрыве от других специалистов Европы и США привела к тому, что лишь незначительная часть его работы стала известной, а сама разработка осталась теоретической. Полностью работа Цузе была издана лишь в 1972 году, а первая реализация языка Планкалкюль (для современных компьютеров) была создана в Свободном университете Берлина лишь в 2000 году, через пять лет после смерти Конрада Цузе.
В 50-е гг. в приоритете остаются задачи научного характера (математика, физика, искусственный интеллект). Программы на языках данного периода представляют собой последовательность команд, которые должен выполнить компьютер.
Fortran
В период 1954-1957 гг. американским ученым в области информатики Джоном Бэкусом совместно с компанией IBM разрабатывается Fortran (англ.FORmula TRANslator) - первый язык программирования общего назначения применяемый до сих пор (он совершенствуется и вбирает в себя различные нововведения, а последняя версия датируется 2010 г.), существует большое количество написанных на нем программ и библиотек подпрограмм.
Пример программы на одном из диалектов Фортрана приведен в Листинге 1.1.3.
Листинг 1.1.3 - Решение квадратного уравнения на Fortran [77]¶
В 1958 г. американский информатик Джон Маккарти изобретает язык Lisp (англ.LISt Processing language) - первый язык программирования, который до сих пор является одним из основных средств моделирования различных аспектов искусственного интеллекта.
Нововведениями Лиспа являлись:
представление программ и данных системами линейных списков символов;
автоматическое управление памятью и сборка мусора (язык самостоятельно освобождал неиспользуемую занятую ранее память компьютера).
Пример программы на одном из диалектов Лиспа приведен в Листинге 1.1.4.
Листинг 1.1.4 - Решение квадратного уравнения на Lisp [77]¶
В 1959 г. под руководством американской ученой и контр-адмирала флота США Грейс Хоппер создается язык COBOL (англ.COmmon Business Oriented Language), предназначенный, в первую очередь, для разработки бизнес-приложений.
Начиная карьеру как программист компьютера Марк I, Хоппер также вошла в историю как:
разработчик первого компилятора (транслятора, который преобразует высокоуровневый код в машинный код целевой машины) для компьютерного языка программирования;
сторонник и разработчик концепции машинно-независимых языков программирования;
популяризатор термина «отладка» (исправление сбоев в работе программы).
Кобол - стандартизованный язык практически с момента своего рождения, используемый и сегодня - еще в 2006 году Кобол считался языком программирования, на котором было написано больше всего строк кода.
Пример программы на одном из диалектов КОБОЛа приведен в Листинге 1.1.5.
Листинг 1.1.5 - Простой калькулятор (умножение и сложение) на COBOL [31]¶
1$ SET SOURCEFORMAT"FREE"
2IDENTIFICATION DIVISION.
3PROGRAM-ID. Iteration-If.
4AUTHOR. Michael Coughlan.
5 6DATA DIVISION.
7WORKING-STORAGE SECTION.
801 Num1 PIC 9 VALUE ZEROS.
901 Num2 PIC 9 VALUE ZEROS.
1001 Result PIC 99 VALUE ZEROS.
1101 Operator PIC X VALUE SPACE.
1213PROCEDURE DIVISION.
14Calculator.
15PERFORM 3 TIMES
16 DISPLAY "Enter First Number : " WITH NO ADVANCING
17 ACCEPT Num1
18 DISPLAY "Enter Second Number : " WITH NO ADVANCING
19 ACCEPT Num2
20 DISPLAY "Enter operator (+ or *) : " WITH NO ADVANCING
21 ACCEPT Operator
22 IF Operator = "+" THEN
23 ADD Num1, Num2 GIVING Result
24 END-IF
25 IF Operator = "*" THEN
26 MULTIPLY Num1 BY Num2 GIVING Result
27 END-IF
28 DISPLAY "Result is = ", Result
29END-PERFORM.
30STOP RUN.
Algol
В 1958—1960 гг. появляется Algol (англ.ALGOrithmic Language) - язык, повлиявший практически на все языки следующего десятилетия (Pascal, С и другие). Алгол был популярен в Европе, в том числе в СССР, в то время как сравнимый с ним язык Фортран был распространен в США и Канаде. Алгол является предком довольно большого числа современных языков программирования (от Си и далее).
К нововведениям Алгола стоит отнести:
вложенные блоки: код мог быть сгруппирован в блоки (например, условие внутри условия) без необходимости вынесения кода в отдельную процедуру;
понятие области видимости: блок программы мог иметь свои закрытые переменные, процедуры и функции, невидимые для внешнего кода.
Пример программы на одном из диалектов Алгола (ALGOL 68) приведен в Листинге 1.1.6.
Листинг 1.1.6 - Решение квадратного уравнения на ALGOL [32]¶
С повышением доступности компьютеров (например, в 1964 г. появляется популярная модель IBM 360) и появлением возможности работы в режиме разделения времени (time-sharing), доступ к компьютеру получили не только крупные научно-исследовательские центры, но и предприятия, образовательные учреждения, в том числе учащиеся и специалисты, не являющиеся подготовленными программистами, но нуждающиеся в решении на компьютере своих задач.
В связи с этим языки программирования продолжают совершенствоваться. В данный период также появляются основные парадигмы программирования, в рамках которых развиваются языки.
PL/I
В 1964 г. IBM разрабатывает язык PL/I (англ.Programming Language I), предназначавшийся для научных, инженерных и бизнес-ориентированных вычислений. В это время научные и бухгалтерские программы не только использовали разные компьютеры, но еще и писались на разных языках: научные — на Фортране, бухгалтерские — в основном на Коболе. Целью ПЛ/1 было создание языка, подходящего для обоих типов приложений.
Язык ввел в употребление множество нововведений, взятых на вооружение другими языками позже:
блочная структура;
большой набор встроенных типов данных;
мощный механизм итераций;
обработка исключительных ситуаций;
макросы и отладка.
Несмотря на заявленные характеристики и мощные возможности, PL/I не добился такого же успеха как Fortran или COBOL в виду сложной и неоптимальной для того времени реализации.
Пример программы на PL/I приведен в Листинге 1.1.7.
1/*PL/IPROGRAMEXAMPLE 2INPUT:ANINTEGER,LISTLEN,WHERELISTLENISLESSTHAN 3100,FOLLOWEDBYLISTLEN-INTEGERVALUES 4OUTPUT:THENUMBEROFINPUTVALUESTHATAREGREATERTHAN 5THEAVERAGEOFALLINPUTVALUES*/ 6 7PLIEX:PROCEDUREOPTIONS(MAIN); 8DECLAREINTLIST(1:99)FIXED. 9DECLARE(LISTLEN,COUNTER,SUM,AVERAGE,RESULT)FIXED;10SUM=0;11RESULT=0;12GETLIST(LISTLEN);13IF(LISTLEN>0)&(LISTLEN<100)THEN2.914DO;15/*READINPUTDATAINTOANARRAYANDCOMPUTETHESUM*/16DOCOUNTER=1TOLISTLEN;17GETLIST(INTLIST(COUNTER));18SUM=SUM+INTLIST(COUNTER);19END;20/*COMPUTETHEAVERAGE*/21AVERAGE=SUM/LISTLEN;22/*COUNTTHENUMBEROFVALUESTHATARE>AVERAGE*/23DOCOUNTER=1TOLISTLEN;24IFINTLIST(COUNTER)>AVERAGETHEN25RESULT=RESULT+1;26END;27/*PRINTRESULT*/28PUTSKIPLIST('THE NUMBER OF VALUES > AVERAGE IS:');29PUTLIST(RESULT);30END;31ELSE32PUTSKIPLIST('ERROR—INPUT LIST LENGTH IS ILLEGAL');33ENDPLIEX;
Basic
К 1964 г. появляется язык Basic (англ.Beginner’s All-purpose Symbolic Instruction Code — универсальный код символических инструкций для начинающих), создававшийся как инструмент, основной задачей которого было предоставить студентам-непрограммистам возможность после минимального обучения самостоятельно писать простейшие программы для собственных нужд, чтобы не отвлекать на эту работу специалистов. При этом подразумевалось, что на Бейсике должна быть возможность писать относительно эффективные программы, хоть и без знания принципов аппаратного обеспечения.
Несмотря на свою простоту Бейсик завоевал популярность и даже сегодня остается востребованным и используется в различных диалектах, например, в качестве встроенного языка текстового процессора Microsoft Word (VBA), или средства визуального программирования Visual Basic, а также других вариантах.
Пример программы на одном из диалектов Бейсика (QuickBASIC 4.5) приведен в Листинге 1.1.8.
Листинг 1.1.8 - Решение квадратного уравнения на Basic [77]¶
В 1970 г. известный швейцарский ученый в области информатики Никлаус Вирт создает язык Pascal - один из наиболее известных языков программирования. Основной плюс языка как в то время, так и сейчас - баланс простоты/возможностей и привитие хорошего стиля программирования - до сих пор оставляет его популярным для обучения программированию и использования в ряде коммерческих приложений.
Несмотря на угасающую популярность, язык непрерывно развивается: сегодня существует множество диалектов, поддерживающих как визуальное и объектное программирование (Delphi или Lazarus/FreePascal), так и являющихся прямыми «улучшенными» потомками (Modula, Oberon и др.).
Пример программы на Паскале приведен в Листинге 1.1.9.
Листинг 1.1.9 - Решение квадратного уравнения на Pascal [77]¶
все — объекты: строки, целые числа, логические значения, определения классов, блоки кода и т.д.;
работа программы - изменение свойств объекта и вызов действий, которые они поддерживают;
динамическая типизация: типы переменных не указываются в программе, а является ли операция правильной, определяет объект-получатель;
автоматическая сборка мусора;
выполнение кода в виртуальной машине: программы Smalltalk обычно компилируются в байткоды и выполняются виртуальной машиной, что позволяет выполнять их на любом оборудовании, для которого существует виртуальная машина (то, что сегодня делает Java).
Пример программы на одном из диалектов Smalltalk приведен в Листинге 1.1.11.
1" CpSc 428 - Example: Grades class (file grades.st)" 2 3" A grade, which is implemented as an instance of class Grade, is" 4" a pair of integers (score, weight), representing 'score' points" 5" out of a total of 'weight' possible points. " 6 7Object subclass: #Grade 8 instanceVariableNames: 'score weight' 9 classVariableNames: ''10 poolDictionaries: ''11 category: 'grades' !1213!Grade class methodsFor: 'instance creation' !1415score:sweight:w1617" Create a new instance of a Grade with score s and weight w."1819| newGrade |2021newGrade:=supernew.22newGradescore:sweight:w.23^newGrade24! !2526!Grade methodsFor: 'initialization' !2728score:sweight:w2930"Set the score and weight values for a grade."3132score:=s.33weight:=w34! !3536!Grade methodsFor: 'accessing' !3738score3940^score41!4243weight4445^weight46! !
C
В период с 1969 по 1973 г. сотрудники американской телекоммуникационной компании Bell LabsДеннис Ритчи и Кен Томпсон разрабатывают язык C - язык общего назначения, изначально предназначенный для реализации операционной системы UNIX.
Язык Си уникален с той точки зрения, что именно он стал первым языком высокого уровня, всерьез потеснившим ассемблер в разработке системного программного обеспечения (согласно дизайну языка Си, его конструкции близко сопоставляются типичным машинным инструкциям). Он остается языком, реализованным на максимальном количестве аппаратных платформ, и одним из самых популярных языков программирования, особенно в мире свободного программного обеспечения. Си послужил основой для многих современных языков программирования, в том числе визуальной разработки, а также продолжает развиваться и сам (последний стандарт датируется 2011 г.).
Пример программы на Си приведен в Листинге 1.1.12.
Листинг 1.1.12 - Решение квадратного уравнения на C [77]¶
Ada - язык, разрабатываемый в течение 70-х гг. Министерством обороны США с целью разработать единый язык программирования для встроенных систем (бортовых систем управления военными объектами - кораблями, самолетами, танками, ракетами, снарядами и т.п.), функционирующих в режиме реального времени.
Синтаксис Ады унаследован от языков типа Algol или Паскаль, но расширен, а также сделан более строгим и логичным. Для удовлетворения требованиям надежности язык построен таким образом, чтобы как можно большее количество ошибок обнаруживалось на этапе компиляции. Кроме того, одним из требований при разработке языка была максимально легкая читаемость текстов программ, даже в ущерб легкости написания. Язык используется в том числе отечественными военными (на нем, например, написана станция документальной связи МО РФ), однако в целом малопопулярен.
Пример программы на Ada приведен в Листинге 1.1.13.
Листинг 1.1.13 - Решение квадратного уравнения на Ada [77]¶
80-е гг. символизируются консолидацией идей, новые языки пытаются совместить изобретенные ранее парадигмы. Ближе к концу 80-х гг. начинают появляться скриптовые языки (языки, как правило, предназначенные для автоматизации каких-либо действий - быстрого поиска в тексте, автоматизации задач операционной системы и т.д.).
При проектировании языков программирования возросло внимание к программированию масштабируемых систем с использованием модулей (модуль - функционально законченный фрагмент программы, который можно использовать в программе). Удобство использования модульной архитектуры заключается в возможности обновления (замены) модуля, без необходимости изменения остальной системы.
Дальнейшее развитие получают идеи обобщенного программирования, заключающиеся в таком описании данных и алгоритмов, которое можно применять к различным типам данных, не меняя само это описание. В том или ином виде поддерживается разными языками программирования (до появления данной идеи, например, для сортировки целых чисел и дробных необходимо было записать 2 разные процедуры в виду различия типов).
C++
В 1983 г. программист компании Bell Бьерн Страуструп представляет язык C++ - первый язык, совместивший черты высокоуровневого языка (объектно-ориентированного, в частности), и низкоуровнего.
C++ широко используется для разработки программного обеспечения, являясь одним из самых популярных языков программирования. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также развлекательных приложений. Имеет компиляторы практически под все популярные платформы и операционные системы. Сегодня также позволяет создавать приложения с графическим интерфейсом (Microsoft Visual C++, С++Qt и др.).
Оказав огромное влияние на более современные языки Java и C#, язык постоянно развивается и представляет собой собранную воедино большую массу технологий. Последний стандарт языка, известный как C++14, датируется 2014 г.
Пример программы на C++ приведен в Листинге 1.1.14.
Листинг 1.1.14 - Пример описания классов «Транспортное средство» и его потомков на C++ [34]¶
1classVehicle{ 2public: 3explicit 4Vehicle(inttopSpeed) 5:m_topSpeed(topSpeed) 6{} 7intTopSpeed()const{ 8returnm_topSpeed; 9}1011virtualvoidSave(std::ostream&)const=0;1213private:14intm_topSpeed;15};1617classWheeledLandVehicle:publicVehicle{18public:19WheeledLandVehicle(inttopSpeed,intnumberOfWheels)20:Vehicle(topSpeed),m_numberOfWheels(numberOfWheels)21{}22intNumberOfWheels()const{23returnm_numberOfWheels;24}2526voidSave(std::ostream&)const;// is implicitly virtual2728private:29intm_numberOfWheels;30};3132classTrackedLandVehicle:publicVehicle{33public:34TrackedLandVehicle(inttopSpeed,intnumberOfTracks)35:Vehicle(topSpeed),m_numberOfTracks(numberOfTracks)36{}37intNumberOfTracks()const{38returnm_numberOfTracks;39}40voidSave(std::ostream&)const;// is implicitly virtual4142private:43intm_numberOfTracks;44};
Objective-C
В то же время 1983 г. в компании Apple под руководством Брэда Кокса разрабатывается собственный Си с классами – Objective-C, построенный на основе языка Си и идей Smalltalk.
Имеет графическую оболочку и позволяет создавать приложения с графическим интерфейсом пользователя. При этом язык используется и поддерживается только в продуктах Apple, поэтому не получил такого широкого распространения как C++.
Пример программы на Objective-C приведен в Листинге 1.1.15.
Листинг 1.1.15 - Вычисление объема с использованием классов на Objective-C [35]¶
1#import <Foundation/Foundation.h> 2 3@interfaceBox:NSObject 4{ 5doublelength;// Length of a box 6doublebreadth;// Breadth of a box 7doubleheight;// Height of a box 8} 9@property(nonatomic,readwrite)doubleheight;// Property1011-(double)volume;1213@end1415@implementationBox1617@synthesizeheight;1819-(id)init20{21self=[superinit];22length=1.0;23breadth=1.0;24returnself;25}2627-(double)volume28{29returnlength*breadth*height;30}3132@end3334intmain()35{36NSAutoreleasePool*pool=[[NSAutoreleasePoolalloc]init];37Box*box1=[[Boxalloc]init];// Create box1 object of type Box38Box*box2=[[Boxalloc]init];// Create box2 object of type Box3940doublevolume=0.0;// Store the volume of a box here4142// box 1 specification43box1.height=5.0;4445// box 2 specification46box2.height=10.0;4748// volume of box 149volume=[box1volume];50NSLog(@"Volume of Box1 : %f",volume);51// volume of box 252volume=[box2volume];53NSLog(@"Volume of Box2 : %f",volume);54[pooldrain];55return0;56}
Eiffel
В 1986 г. французский ученый в области информатики Бертран Мейер создает язык Eiffel (Эйфель) — объектно-ориентированный язык программирования с алголоподобным синтаксисом, в котором впервые был реализован метод контрактного программирования.
Метод контрактного программирования предполагает, что проектировщик должен определить формальные, точные и верифицируемые спецификации интерфейсов для компонентов системы. Данные спецификации называются «контрактами» в соответствии с концептуальной метафорой условий и ответственности в гражданско-правовых договорах.
Eiffel используется в серьезных разработках, от которых зависят жизни людей: в аэрокосмической отрасли, в банковско-финансовой сфере и др. Несмотря на это язык слабораспространен, т.к. компиляторы с Eiffel от автора языка дороги и не так распространены, как компиляторы C/C++, что, в свое время, и ограничило распространение этого языка, а свободных/бесплатных альтернатив долгое время не было.
Пример программы на Eiffel приведен в Листинге 1.1.16.
Листинг 1.1.16 - Описание класса «Банковский счет» на Eiffel [36]¶
1note 2description:"Простые банковские счета" 3 4class 5ACCOUNT 6 7create 8make 910feature{NONE}-- Инициализация11make-- Инициализировать12do13createall_deposits14end1516feature-- Доступ17balance:INTEGER18-- Текущий баланс1920deposit_count:INTEGER21-- Количество сделанных взносов с момента открытия22do23Result:=all_deposits.count24end25feature-- Изменение элемента26deposit(sum:INTEGER)27-- Добавить `sum' на счет.28require29non_negative:sum>=030do31all_deposits.extend(sum)32balance:=balance+sum33ensure34one_more_deposit:deposit_count=olddeposit_count+135updated:balance=oldbalance+sum36end3738feature{NONE}-- Реализация39all_deposits:DEPOSIT_LIST40-- Список взносов с момента открытия счета4142invariant43consistent_balance:balance=all_deposits.total44zero_if_no_deposits:all_deposits.is_emptyimplies(balance=0)45end-- класс ACCOUNT
Perl
Ларри Уолл, лингвист по образованию, в 1987 г. создает язык Perl (англ.Practical Extraction and Report Language - «практический язык для извлечения данных и составления отчетов») - язык программирования общего назначения, который был первоначально создан для манипуляций с текстом, но на данный момент используется для выполнения широкого спектра задач, включая системное администрирование, веб-разработку, сетевое программирование, игры, биоинформатику, разработку графических пользовательских интерфейсов. Язык можно охарактеризовать скорее как практичный (легкость в использовании, эффективность, полнота), чем красивый (элегантность, минималистичность).
Пример программы на Perl приведен в Листинге 1.1.17.
Листинг 1.1.17 - Программа выполняет замену в строке на основе конфигурационного файла [37]¶
В 1988 г. американский ученый в области информатики Джон Оустерхаут создает язык Tcl (англ.Tool Command Language - «командный язык инструментов») - один из первых скриптовых языков высокого уровня. Основная область применения - быстрое прототипирование, создание графических интерфейсов для консольных программ (пакетов программ), встраивание в прикладные программы, тестирование. Также Tcl применяется в веб-разработке.
Пример программы на Tcl приведен в Листинге 1.1.18.
Листинг 1.1.18 - Генерация простых чисел и сохранение в файл на Tcl [38]¶
90-е годы характеризовались распространением сети Интернет и персональных компьютеров, а также увеличением количества данных, что послужило очередным толчком для дальнейшего развития языков программирования. Многие языки, созданные в это время, являются свободными (пользователи имеют права на неограниченную установку, запуск, свободное использование, изучение, распространение и изменение (совершенствование), а также распространение копий и результатов изменения), что также явилось фактором широкого распространения ряда языков.
Можно выделить несколько тенденций и идей развития в это время:
продолжение комбинации идей предыдущих десятилетий и распространение функциональных языков;
повышение продуктивности разработки;
продолжение развития скриптовых (динамических) языков;
Желание увеличить производительность работы программиста в совокупности с сохранением проверенных временем идей привело к появлению новых языков высокого уровня, а также сред быстрой разработки (англ. Rapid Application Development - RAD), включающих кроме самого языка и транслятора интегрированную среду разработки (англ. Integrated Development Environment - IDE). Все такие языки программирования были объектно-ориентированными, а в ряде случаев IDE также позволяла выполнять графическое проектирование приложений.
Python
В 1991 г. нидерландский программист Гвидо ван Россум представляет Python — высокоуровневый мультипарадигменный язык программирования общего назначения, ориентированный на повышение производительности разработчика и читаемости кода. Синтаксис ядра Python минималистичен, в то же время стандартная библиотека включает большой объем полезных функций.
Python портирован и работает почти на всех известных платформах — от КПК до мейнфреймов. Язык используется в различных качествах: как основной язык программирования или для создания расширений и интеграции приложений. На Python реализовано большое количество проектов, также он активно используется для создания прототипов будущих программ. Python используется в основном в качестве языка веб-программирования, обработки данных и научных задач.
Пример программы на Python приведен в Листинге 1.1.19.
Листинг 1.1.19 - Решение квадратного уравнения на Python 3 [39]¶
Спустя 2 года, в 1993 г., японский разработчик Юкихиро Мацумото создает язык Ruby - высокоуровневый язык программирования для быстрого и удобного объектно-ориентированного программирования, который, по словам автора, более мощный, чем Perl, и более объектно-ориентированный, чем Python.
Ruby имеет немало оригинальных решений, редко или вообще не встречающихся в распространенных языках программирования - расширенная работа с массивами, классами и т.д.
Основные сферы применения приблизительно такие же, как и у Python.
Пример программы на Ruby приведен в Листинге 1.1.20.
1classPerson<Object# объявление класса начинается с ключевого слова class, за которым 2# следует имя, класс Person наследуется от Object 3includeComparable# подмешиваются к классу методы экземпляра 4mixMyModel# подмешивание без наложения имен 5extendMyModel# методы класса 6# и добавляет методы <, <=, ==, >=, > и between? 7# с использованием нижеопределённого 8# в классе <=> 9#10@variable# переменная экземпляра11@@count_obj=0# переменная класса для подсчёта числа созданных объектов12#13# конструктор для создания объектов с помощью new14definitialize(name,age)# name, age - параметры метода15# название переменных объекта начинается с @16@name,@age=name,age# создаём объекты и увеличиваем счётчик на 117@@count_obj+=118end1920def<=>(person)# переопределение оператора <=>21# (это даёт возможность использовать метод sort)22@age<=>person.age# из метода возвращается последнее вычисленное выражение,23end2425defto_s# для форматированного вывода информации puts26"#{@name} (#{@age})"# конструкция #{x} в 2-х кавычках замещается в Ruby значением x27end2829definspect# похож на to_s, но используется для диагностического вывода30"<#{@@count_obj}:#{to_s}>"31end32# пример метапрограммирования: добавляет методы для доступа к33# переменным объекта34attr_reader:name,:age35end36# создаём массив объектов37group=[Person.new("John",20),38Person.new("Markus",63),39Person.new("Ash",16)]40# => [<3:John (20)>, <3:Markus (63)>, <3:Ash (16)>]41# здесь при работе с irb автоматически вызывается метод inspect42# вызываем методы массива сортировка и разворачивание его в обратном порядке43putsgroup.sort.reverse# Печатает:44# Markus (63)45# John (20)46# Ash (16)47# обращаемся к функции, которая была добавлена48# автоматически (используя <=>) при включении Comparable49group[0].between?(group[2],group[1])# => true
Lua
Еще один скриптовый язык программирования Lua в 1993 г. в Бразилии разрабатывает преподаватель университета Роберто Иерусалимский совместно с коллегами.
Язык широко используется для создания тиражируемого программного обеспечения (например, на нем написан графический интерфейс пакета Adobe Lightroom). Также получил известность как язык программирования уровней и расширений во многих играх (в том числе World of Warcraft) из-за удобства встраивания, скорости исполнения кода и легкости обучения.
Пример программы на Lua приведен в Листинге 1.1.21.
Листинг 1.1.21 - Решение квадратного уравнения на Lua [77]¶
В 1993 г. также создается R - язык программирования для статистической обработки данных и работы с графикой. R широко используется как программное обеспечение для анализа данных и фактически стал стандартом для статистических программ, имеет собственные IDE.
1# В переменную a поместить список всех оценок: 2a<-c(4,3,3,3,3,4,4,4,4,4,5,4,4,4,5,5,5,5,+ 33,5,5,4,4,3,3,4,4,3,5,5,4,3,3,4,4,3,3,5,4,5,5) 4 5# В переменную n поместить количество оценок: 6length(a)->n 7 8# Средний балл: 9m<-mean(a)1011# Таблица (горизонтальная) с подсчётом количества оценок:12t<-table(a)1314# Преобразование в более удобный формат данных (вертикальную таблицу):15f<-as.data.frame(t)1617# Вычисление процентной доли и запись её в третий столбец:18mapply(function(r)r*100/n,f[,2])->f[,3]1920# Заголовки столбцов:21colnames(f)<-c("Оценка","Кол-во","%")2223# Вывод результатов:24a25n26m27f2829# Результат30# [1] 4 3 3 3 3 4 4 4 4 4 5 4 4 4 5 5 5 5 3 5 5 4 4 3 3 4 4 3 5 5 4 3 3 4 4 3 3 531# [39] 4 5 532# [1] 4133# [1] 434# Оценка Кол-во %35# 1 3 12 29.2682936# 2 4 17 41.4634111137# 3 5 12 29.26829
JavaScript
В 1995 г. набирает популярность язык JavaScript как встраиваемый язык для программного доступа к объектам приложений. Наиболее широко применяется в браузерах как язык сценариев для придания интерактивности веб-страницам.
Пример программы на JavaScript приведен в Листинге 1.1.23.
Листинг 1.1.23 - Пример кода Javascript на HTML-странице [41]¶
1<p>Image Rollover:</p> 2<scripttype="text/javascript"> 3<!-- 4// Pre load images for rollover 5if(document.images){ 6smile=newImage 7nosmile=newImage 8 9smile.src="http://www.quackit.com/pix/smile.gif"10nosmile.src="http://www.quackit.com/pix/nosmile.gif"11}121314functionswapImage(thisImage,newImage){15if(document.images){16document[thisImage].src=eval(newImage+".src")17}18}19-->20</script>21<ahref="http://www.quackit.com/javascript/image_rollovers.cfm"22onMouseOver="swapImage('jack','smile')"23onMouseOut="swapImage('jack','nosmile')">24<imgsrc="http://www.quackit.com/pix/nosmile.gif"25width="100"26height="100"27border="0"28alt="Picture of Jack"29name="jack">30</a>31<divclass="more-info">32<p>More info: <ahref="/javascript/image_rollovers.cfm">Image Rollovers</a></p>33</div>
PHP
В 1995 г. появляется PHP (англ.PHP: Hypertext Preprocessor — «PHP: препроцессор гипертекста») — скриптовый язык общего назначения, интенсивно применяемый для разработки веб-приложений. В настоящее время поддерживается подавляющим большинством хостинг-провайдеров и является одним из лидеров среди языков, применяющихся для создания динамических веб-сайтов.
Пример программы на PHP приведен в Листинге 1.1.24.
Листинг 1.1.24 - Пример кода PHP на HTML-странице для отправки почты [42]¶
1<html> 2<head> 3<title>Simple Send Mail Form</title> 4</head> 5<body> 6<h1>Mail Form</h1> 7<formname="form1"method="post"action="SimpleEmail.php"> 8<table> 9<tr><td><b>To</b></td><td><inputtype="text"name="mailto"size="35"></td></tr>10<tr><td><b>Subject</b></td>11<td><inputtype="text"name="mailsubject"size="35"></td></tr>12<tr><td><b>Message</b></td>13<td><textareaname="mailbody"cols="50"rows="7"></textarea></td>14</tr>15<tr><tdcolspan="2">16<inputtype="submit"name="Submit"value="Send">17</td>18</tr>19</table>20</form>21</body>22</html>232425<!-- SimpleEmail.php26 <?php27 if (empty ($mailto) ) {28 die ( "Recipient is blank! ") ;29 }3031 if (empty ($mailsubject) ){32 $mailsubject=" " ;33 }3435 if (empty ($mailbody) ) {36 $mailbody=" " ;37 }3839 $result = mail ($mailto, $mailsubject, $mailbody) ;4041 if ($result) {42 echo "Email sent successfully!" ;43 }else{44 echo "Email could not be sent." ;45 }46?>47-->
Java
Также в 1995 г. появляется язык Java - язык программирования, разработанный компанией Sun Microsystems (в последующем приобретенной компанией Oracle). Приложения Java обычно транслируются в специальный байт-код, поэтому они могут работать на любой компьютерной архитектуре, с помощью виртуальной Java-машины.
Достоинством подобного способа выполнения программ является полная независимость байт-кода от операционной системы и оборудования, что позволяет выполнять Java-приложения на любом устройстве, для которого существует соответствующая виртуальная машина. Другой важной особенностью технологии Java является гибкая система безопасности, в рамках которой исполнение программы полностью контролируется виртуальной машиной - любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером), вызывают немедленное прерывание.
Java-технологии используются в огромном количестве устройств (более 3 млрд.), используется как в качестве разработки настольных и мобильных приложений, так и веб-приложений; кроме того, существует множество сред визуальной разработки, поддерживающих язык Java.
Пример программы на Java приведен в Листинге 1.1.25.
Листинг 1.1.25 - Расчет площади треугольника на Java [43]¶
1/** 2 * @author: BeginnersBook.com 3 * @description: Program to Calculate area of Triangle in Java 4 * with user interaction. Program will prompt user to enter the 5 * base width and height of the triangle. 6 */ 7importjava.util.Scanner; 8classAreaTriangleDemo{ 9publicstaticvoidmain(Stringargs[]){10Scannerscanner=newScanner(System.in);1112System.out.println("Enter the width of the Triangle:");13doublebase=scanner.nextDouble();1415System.out.println("Enter the height of the Triangle:");16doubleheight=scanner.nextDouble();1718//Area = (width*height)/219doublearea=(base*height)/2;20System.out.println("Area of Triangle is: "+area);21}22}
GUI
Распространенность персональных компьютеров и мобильных устройств привело к необходимости разработки приложений, удобных для использования неподготовленным человеком - для чего необходим был графический интерфейс. Многие из языков данного периода, включая более старые языки, получили возможность создания приложений с графическим интерфейсом.
На Рисунке 1.1.22 приведен пример IDE Delphi (Object Pascal), аналогичной средой, но для языка Basic выступал Visual Basic (1991), в качестве одного из вариантов для C++ выступала графическая библиотека Qt (Рисунок 1.1.23).
Рисунок 1.1.22 - IDE Borland Delphi 1 (1995 г.) [70]¶
В 2000 г. корпорация Майкрософт под руководством Андерса Хейлсберга представляет язык C# - объектно-ориентированный язык программирования для специально созданной платформы Microsoft .NET Framework, основной идеей которой являлось обеспечение свободы разработчика за счет предоставления ему возможности создавать приложения различных типов, способные выполняться на различных типах устройств и в различных средах.
Общая схема работы языков в рамках платформы .NET приведена на Рисунке 1.1.24.
Рисунок 1.1.24 - Принцип работы языков платформы .NET [72]¶
C# относится к семье языков с C-подобным синтаксисом, из них его синтаксис наиболее близок к C++ и Java. В языке представлены практически все современные достижения «языкостроения», а реализация языка доступна в том числе на не-Windows средах (проект Mono).
Пример программы на C# приведен в Листинге 1.1.26.
Листинг 1.1.26 - Hello world на C# (консольное приложение) [47]¶
1// A Hello World! program in C#. 2usingSystem; 3namespaceHelloWorld 4{ 5classHello 6{ 7staticvoidMain() 8{ 9Console.WriteLine("Hello World!");1011// Keep the console window open in debug mode.12Console.WriteLine("Press any key to exit.");13Console.ReadKey();14}15}16}
Go
Go - компилируемый, многопоточный язык программирования, разработанный компанией Google в 2009 г. Первоначальная разработка Go началась в сентябре 2007 года, а его непосредственным проектированием занимались Роберт Гризмер, Роб Пайк и Кен Томпсон.
На данный момент его поддержка осуществляется для операционных систем: FreeBSD, OpenBSD, Linux, Mac OS X, Windows, начиная с версии 1.3 в язык Go включена экспериментальная поддержка DragonFly BSD, Plan 9 и Solaris, начиная с версии 1.4 поддержка платформы Android.
Язык Go разрабатывался как язык системного программирования для создания высокоэффективных программ, работающих на современных распределенных системах и многоядерных процессорах. Он может рассматриваться как попытка создать замену языку Си. При разработке уделялось особое внимание обеспечению высокоэффективной компиляции. Программы на Go компилируются в машинный код и не требуют для исполнения виртуальной машины.
Пример программы на Go приведен в Листинге 1.1.27.
Листинг 1.1.27 - Цикл for в Go (единственная циклическая конструкция!) [49]¶
1// `for` is Go's only looping construct. Here are 2// three basic types of `for` loops. 3 4packagemain 5 6import"fmt" 7 8funcmain(){ 910// The most basic type, with a single condition.11i:=112fori<=3{13fmt.Println(i)14i=i+115}1617// A classic initial/condition/after `for` loop.18forj:=7;j<=9;j++{19fmt.Println(j)20}2122// `for` without a condition will loop repeatedly23// until you `break` out of the loop or `return` from24// the enclosing function.25for{26fmt.Println("loop")27break28}29}
Rust
Rust (англ. Rust - ржавчина) - мультипарадигменнй компилируемый язык программирования общего назначения, спонсируемый Mozilla Research, поддерживающий функциональное программирование, модель акторов (один из подходов к распараллеливанию программ, где одновременно выполняющиеся процессы передают друг другу сообщения), процедурное программирование, объектно-ориентированное программирование.
Rust - системный язык программирования, внимание которого сосредоточено на трех задачах: безопасность, скорость и параллелизм. Он сопоставим по скорости и возможностям с C++, однако, дает большую безопасность при работе с памятью, что обеспечивается механизмами ограничения. Rust также направлен на достижение «абстракции с нулевой стоимостью».
После нескольких лет активной разработки первая стабильная версия (1.0) вышла 15 мая 2015 года, после чего новые версии выходят раз в 6 недель. Программы, написанные на ранних стабильных версиях языка будут собираться и на более новых стабильных версиях.
Пример программы на Rust приведен в Листинге 1.1.28.
1#![allow(unreachable_code)] 2 3fnmain(){ 4'outer: loop{ 5println!("Entered the outer loop"); 6 7'inner: loop{ 8println!("Entered the inner loop"); 910// This would break only the inner loop11//break;1213// This breaks the outer loop14break'outer;15}1617println!("This point will never be reached");18}1920println!("Exited the outer loop");21}
Машинный код и языки ассемблера традиционно относят к языкам низкого уровня - программирование на них осуществляется либо непосредственно в машинных кодах используемого реального или виртуального процессора, либо приближено к этому.
Языки программирования, которые имеют достаточный уровень абстракции - оперируют сложными структурами данных и умеют выполнять над ними комплексные операции (что в машинном коде повлекло бы длинные и сложные цепочки кода), относят к языкам высокого уровня. Примеры таких языков - C, Pascal, Python, Java и др.
Как и в случае с языками ассемблера, любой язык программирования должен пройти процесс перевода на машинный код для того, чтобы компьютер понял какие инструкции ему дают в рамках того, что он умеет.
Программа, предназначенная для перевода кода с языка программирования в машинный код называется транслятором. На сегодняшний день выделяется 3 типа трансляторов: компиляторы, интерпретаторы и гибриды.
Компиляторы однократно осуществляют перевод всего кода в машинный код. Результатом процесса компиляции является исполняемый модуль (например, EXE-файл для ОС Windows).
Интерпретаторы анализируют и тут же выполняют программу покомандно, по мере поступления ее исходного кода на вход интерпретатора.
Схематично сравнительная работа компилятора и интерпретатора приведена на Рисунке 1.1.25.
Рисунок 1.1.25 - Сравнительная схема работы компилятора и интерпретатора¶
Каждый из вариантов имеет свои плюсы и минусы (Таблица 1.1.2).
Таблица 1.1.2 - Преимущества и недостатки компиляторов и интерпретаторов¶
№
Характеристика
Компилятор
Интерпретатор
1
Быстродействие
(+) Обеспечивают максимальную производительность
(-) Дополнительный слой интерпретатора замедляет выполнение программы и может требовать больше ресурсов
2
Переносимость
(-) Исполняемый файл привязан к платформе компиляции
(+) Программа может быть легко перенесена на другую платформу, для которой имеется интерпретатор
Гибриды пытаются совместить плюсы компиляторов и интерпретаторов. Наиболее известные представители - язык Java и платформа .NET Framework.
Практически все современные языки относительно «размывают» границы данной классификации и в той или иной степени являются гибридными.
Языки высокого уровня работают не с битами и байтами, а с более абстрактными структурами данных - типами, поэтому эти языки принято считать типизированными.
1. Сильная (строгая): не позволяет смешивать в выражениях различные типы и не выполняет автоматические неявные преобразования
Примеры: Java, Python.
a=5b=a+"строка"# Ошибка в Python
2. Слабая (нестрогая): множество неявных преобразований происходит автоматически, даже если может произойти потеря точности или преобразование неоднозначно.
Примеры: C, JavaScript, Visual Basic, PHP.
a=5b=a+"строка"' Visual Basic (5 преобразуется в строку и результат равен "5строка")
Все виды типизации пересекаются, например, язык C имеет [явную, статическую, слабую] типизацию, а язык Python — [неявную, динамическую, сильную].
За время своего развития языки программирования создавались под влиянием определенных идей, которые определяли возможности языка и стиль написания программ. Совокупность таких идей и понятий называется парадигмой программирования.
Выделяют 4 парадигмы программирования:
Императивная (процедурная).
Функциональная.
Логическая.
Объектно-ориентированная.
Языки программирования могут поддерживать одну или несколько парадигм и, соответственно, называться императивными, объектно-ориентированными и т.д.
1. Императивная (процедурная).
Наиболее известная парадигма.
Программа состоит из последовательно выполняемых команд и вызовов процедур, которые обрабатывают данные и изменяют значения переменных программы. Переменные при этом рассматриваются как некоторые контейнеры для данных, подобно ячейкам памяти компьютера. Процедурная парадигма расширяет императивную, позволяя оформлять участки кода в виде отдельных блоков - процедур.
Выполнение программы заключается в последовательном выполнении команд.
Программа состоит из набора взаимосвязанных и, как правило, рекурсивных функций. Каждая функция определяется выражением, которое задает правило вычисления ее значения в зависимости от значений ее аргументов.
Выполнение функциональной программы заключается в последовательном вычислении значений функциональных вызовов.
3. Логическая.
Программа рассматривается как множество логических формул: аксиом (фактов и правил), описывающих свойства некоторых объектов, и теоремы, которые необходимо доказать.
Выполнение программы – доказательство теоремы, в ходе которого строится объект с описанными свойствами.
4. Объектно-ориентированная.
Позволяет программе описывать структуру и поведение через классы и их взаимодействие.
Объект содержит некоторые данные (свойства, состояние объекта) и операции над этими данными (методы), описывающие поведение объекта. Классы представляют шаблоны объектов со схожей структурой и схожим поведением. Обычно описание классов имеет иерархическую структуру.
Выполнение объектно-ориентированной программы представляет собой обмен сообщениями между объектами, в результате которого они меняют свои состояния.
-- НАЧАЛО --
-- описание объектов --
Чайник
Свойства
- объем_налитой_воды
Методы
- достаточно_воды_для_заваривания_чая? (да/нет)
- закипел? (да/нет)
- подключить_к_сети(Розетка)
- включить
Кран
Методы
- открыть
- закрыть
Человек
Методы
- прочитать_новость_в_Интернете
- посмотреть_в_окно
- посмотреть_уровень_воды_в_чайнике(Чайник)
Розетка
Свойства
- свободна?
Методы
- освободить
-- основной алгоритм --
Чайник1 = Чайник()
Человек1 = Человек()
Кран1 = Кран()
Розетка1 = Розетка()
ЕСЛИ НЕ Чайник1.достаточно_воды_для_заваривания_чая?
Кран1.открыть
ПОКА НЕ Чайник1.достаточно_воды_для_заваривания_чая?
Человек1.посмотреть_уровень_воды_в_чайнике(Чайник1)
Кран1.закрыть
ЕСЛИ Розетка1.свободна?
Розетка1.освободить
Чайник1.подключить_к_сети(Розетка1)
Чайник1.включить
ПОКА НЕ Чайник1.закипел?
Человек1.прочитать_новость_в_Интернете
Человек1.посмотреть_в_окно
-- КОНЕЦ --
Выбор языка программирования для выполнения какого-либо проекта - ответственное дело и зависит от многих факторов.
Примечание
Следует отметить, что все языки высокого уровня общего назначения обладают полнотой по Тьюрингу, т.е. на них можно реализовать любую вычислимую функцию. С практической точки зрения это означает, что программа на одном тьюринг-полном языке программирования может быть записана на другом тьюринг-полном языке программирования, что делает «пустыми» «священные войны» в стиле «на языке X это сделать можно, а на языке Y нельзя», однако, несомненно, некоторые языки позволяют решить ту или иную задачу эффективнее.
Одной из наиболее важных представляется экосистема языка программирования, в которую обычно входят:
1. Средства разработки (IDE).
Позволяет удобно и эффективно писать, и отлаживать код.
2. Библиотеки и Фреймворки.
Расширяют базовые возможности языка (графический интерфейс, тестирование, сетевое программирование, графика и т.д.).
3. Системы пакетирования и развертывания.
Доставляют программное обеспечение до конечного потребителя (средства создания установочных пакетов, загрузки на сайт и т.д.).
4. Сообщество (коммьюнити).
Оказывают официальную (техническая поддержка) и неофициальную (форумы, чаты и др.) помощь по языку программирования и средствам выше; чем больше и отзывчивее сообщество, тем лучше.
Многие из языков программирования создавались для более эффективного решения задач конкретного класса. В связи с этим, в индустрии разработки ПО сложились определенные тренды, какие языки и в какой области применять более целесообразно (Рисунок 1.1.26).
Рисунок 1.1.26 - Комплексный рейтинг популярности с указанием их типовой применимости по данным IEEE (Институт инженеров электротехники и электроники) [76]¶
В мире существуют различные рейтинги для определения популярности языков. Популярность влияет на распространенность языка, вероятность найти помощь в интернете, наличие необходимых библиотек и т.д. (Рисунок 1.1.27, 1.1.28)
Рисунок 1.1.27 - Самые популярные языки программирования в мире в разные годы по Индексу TIOBE[75]¶
Рисунок 1.1.28 - Исторический рейтинг языков программирования в мире по Индексу TIOBE [75]¶
Примечание
Главное правило - выбирать язык под задачу, с учетом сформировавшегося опыта индустрии и команды!