История развития языков и технологии программирования
Если рассматривать историю языков программирования с точки зрения историка, она предстанет перед нами в виде длинного списка дат, плотно расположенных, начиная с 1950-х годов по настоящее время. В рамках настоящего пособия наиболее интересна история языков как процесса, растянутого во времени и зависящего от развития компьютерной техники и задач, ставящихся пред программистами конкретного периода.
Итак, условно процесс развития языков программирования можно разбить на несколько основных этапов (поколений). На заре развития языков программирования в 1954-1958 гг. компьютерная техника представляла собой огромные машины, занимающие целые залы в вычислительных центрах, для которых задавались в основном задачи на численные вычисления. Заказчик либо ставил задачу перед программистом ВЦ и получал только ленту с результатом вычислений, либо сам вынужден был становиться разработчиком ПО чтобы получить нужные результаты (то есть он одновременно должен был быть экспертом в предметной области). Для решения этих задач было достаточно так называемой хаотической концепции программирования (Fortran, Algol-58). Для программ того времени была характерна неконтролируемая последовательность передач управления (в основном через оператор goto), отсутствие подпрограмм и требований к обязательному объявлению данных. Все эти свойства характерны для языков первого поколения [2].
Языки второго поколения появились в 1959-1961 гг. (Fortran2, Algol-60, Lisp, Cobol). В них уже реализуются описание данных, разделение программы на подпрограммы. В то же время еще нет передачи данных через параметры функций, реализованы лишь глобальные переменные. Эти изменения потребовались потому, что задачи, стоящие перед программистами в этот период, усложнились, стало сложно решать их при помощи единого блока. К тому же к этому времени накопились базы уже написанных вычислительных программ, которые можно было использовать вместо того, чтобы писать программу «с нуля». Однако из-за использования перекрестных ссылок и глобальных переменных подобные программы часто вызывали путаницу и были сложно структурированными. Используя языки первого и второго поколений, программисты могли писать программы, не превышающие по объему кода нескольких тысяч строк.
Языки третьего поколения возникли для преодоления возникшего барьера и позволили писать программы до 50 000 строк. Причём программу уже писал не один программист, как раньше, а группа программистов. Появление языков третьего поколения датируют 1962-1970 гг. (Algol-68, PL/1, Pascal, Simula, C). Им уже присущи такие неотъемлемые атрибуты современных программ как структурное программирование (реализация отдельных функций со своим набором данных), модульное программирование (отдельно-компилируемые файлы, возможно разных авторов, впоследствии собираемые в один программный продукт), передача данных в подпрограмму при помощи параметров. К тому же добавилась возможность описывать новые типы данных. Последнее связано с тем, что вычислительные задачи уступают место задачам обработки данных. Языки второго и третьего поколений принято называть процедурно-ориентированными языками.
Однако и они оказались неэффективными, когда программы стали ещё больше. К тому же на данном этапе развития вычислительной техники изменился жизненный цикл программ. На предыдущих этапах развития вычислительной техники заказчику в основном требовались результаты вычислений, при этом акцент делался на возможность неоднократного их получения с изменением начальных значений. Программный код мог вообще не интересовать заказчика, либо он создавался и эксплуатировался всю свою жизнь на одной ЭВМ. В 70-80 годах на первое место выходит последний этап жизненного цикла программы – поддержка ее функционирования на компьютере заказчика, причем работать с программой приходится уже не ее разработчику, а совсем другому человеку. К тому же заказчику все чаще требуется модернизировать разработанное ПО, причем достаточно быстро и без лишних дополнительных затрат. Все это привело к тому, что в это время появились языки четвертого поколения (Object Pascal, C++, ADA). Они получили название объектно-ориентированных языков.
Основным элементом в объектно-ориентированных языках служит модуль, состоящий из логически связанных классов и объектов, а не подпрограмма. Класс содержит описание данных и методы обработки этих данных. Этим достигается легкость модернизации кода и гарантированная корректность обработки данных. К тому же принцип наследования свойств и данных уже разработанных классов дает возможность программисту писать Windows-ориентированные приложения, не тратя время на прописывание свойств создаваемых окон. Объектно-ориентированное программирование позволяет программисту оперировать с гораздо большими по объему программами и пользоваться гораздо большим числом уже написанных библиотек для решения стандартных задач программирования. А в результате все это ведет к снижению стоимости программной разработки и ее обслуживания.
На современном этапе развития вычислительной техники перед автоматизированными системами ставятся самые разнообразные задачи. ПК используются практически во всех сферах науки и отраслях хозяйства. Таким образом, перед программистом ставится достаточно широкий круг задач. Именно поэтому перед решением задачи программисту требуется квалифицированная помощь эксперта по предметной области, так как все чаще программист не является специалистом узкого профиля, как этого требуют задачи. Современную ситуацию можно рассматривать как частичный возврат к 50-м годам 20 века, когда специалист сам ставил для себя задачу и решал ее с помощью ЭВМ. Так некоторые современные языки (например, язык программирования и моделирования ДРАКОН) ориентированы в основном не на программиста, а на специалиста в предметной области. А также многие распространенные сейчас языки программирования имеют более простой и понятный синтаксис, не используют функций для работы с битами и указателями, не позволяют разработчику самому выделять и удалять динамическую память, т. е. рассчитаны не только на программиста высокой квалификации, но и предполагают, что программирование – это не профессия, а навык, необходимый каждому. Однако это совершенно не означает, что профессия программиста скоро прекратит своё существование.
Я зык С
Среди современных языков программирования язык С является одним из наиболее распространенных. С одной стороны язык С универсален, как с точки зрения решаемых задач, так и с точки зрения аппаратного обеспечения и ОС, на которых может работать программа, написанная на языке С. Причина тому существование довольно большого количества компиляторов языка С, работающих под любой из распространенных (функционирующих) в настоящее время ОС, и переносимость программ, написанных на языке С, на другие ПК. С другой стороны, язык С особенно эффективен для задач системного программирования (разработка трансляторов, ОС, инструментальных средств и оконных интерфейсов). Поскольку язык С хорошо зарекомендовал себя эффективностью, логической стройностью, лаконичностью, скоростью работы программ (во многих случаях её можно сравнить со скоростью выполнения программ, написанных на языке Ассемблер), то вполне естественно, что язык С со времени своего появления до современного уровня вынужден приспосабливаться к изменившимся задачам, стоящим перед современными программистами. В настоящее время современными модификациями языка С являются С++ и С#, но, т.к. перед авторами не стояла задача рассмотрения языка С#, под словосочетанием «язык С» в дальнейшем в учебном пособии будет подразумеваться именно язык С++.
Язык С обладает рядом особенностей, присущих только ему. Это связано с тем, что изначально перед разработчиками языка стояла задача обеспечить системных программистов языком высокого уровня, позволяющим заменить собой Ассемблер. Поэтому язык С и по сей день не утратил необычайной лёгкости доступа к аппаратным средствам компьютера. С одной стороны, как язык высокого уровня, С поддерживает полный набор конструкций структурного и объектно-ориентированного программирования, модульность и раздельную компиляцию. С другой, язык С имеет ряд низкоуровневых свойств. Так, например, в языке С реализованы побитовые операции, существуют типы данных, соответствующие типам данных в Ассемблере (байты, машинные слова). Работа с указателями позволяет оперировать адресами в памяти компьютера с той же лёгкостью, что и в Ассемблере, но поскольку это требует высокой квалификации программиста, то в современных системах программирования (например, Microsoft Visual Studio 2008) встроены элементы защиты от неверного обращения к адресам памяти. Таким образом современные среды разработки программ практически уже не поддерживают заложенный изначально в язык С принцип полного доверия к программисту.
Коснемся немного истории развития языка С. Он был разработан в США в 70-х годах 20 века. Тогда же он был использован для написания ОС UNIX (всем хорошо известна ее модификация – LINUX). Из-за хорошей переносимости язык С стал очень распространён, что привело к возникновению огромного количества «диалектов» языка С и создавало некоторою путаницу в работе программ, а также снижало переносимость. Поэтому в 1989 г. в Американском Национальном Институте Стандартов (ANSI) была принята окончательная редакция стандарта языка С. Впоследствии к этому стандарту была добавлена объектно-ориентированная версия языка С – С++. Стандарт языка С ISO / ANSI определен в стандарте ISO/IEC 14882, опубликованном Американским национальным институтом стандартизации ANSI (International Standards Organization/American National Standards Institute).
Стандарт ISO/ANSI C++ описывает устойчивую версию C++, которая существует с 1998 г. и поддерживается компиляторами большинства аппаратных компьютерных платформ и операционных систем. Стандарт C++ ISO/ANSI – это главный инструмент, который выбирают профессиональные разработчики программ, поскольку он широко поддерживается и на сегодняшний день является одним из наиболее мощных и доступных языков программирования.
Следующая модификация языка С – C ++/CLI – версия C++, расширяющая стандарт C++ ISO/ANSI в целях лучшей поддержки общей инфраструктуры языка, определенной в стандарте ЕСМА355. Первый набросок этого стандарта появился в 2003 г. и был разработан на основе технических спецификаций, представленных Microsoft для поддержки программ C++ в среде .NET Framework. To есть, как CLI вообще, так и C ++/CLI в частности, родились в Microsoft и предназначены для поддержки .NET Framework.
В начале XXI века появляется ещё одна версия языка – С#, который стандартизирован в ECMA-334 (2006 г.) и ISO/IEC 23270 (2003 г.). Эта версия ориентирована на создание сетевых Windows-приложений. Но, как и любая версия языка, она содержит в себе определённые в стандарте основные конструкции языка, и достаточно легко позволяет писать консольные приложения, использующие стандарт ISO/ANSI C++.