Программу на языке ассемблера достаточно сложно выполнить на другой машине, поскольку для этого ее нужно переписать
с учетом новой конфигурации регистров и набора команд.
Кроссплатформенное программное обеспечение. При решении многих задач типичная прикладная программа вынуж-
дена полагаться на операционную систему. Например, она может обратиться к диспетчеру окна для организации взаимодей-
ствия с пользователем или диспетчеру файлов для считывания данных с устройств массовой памяти. К сожалению, различ-
ные операционные системы выполняют такие запросы по-разному. Поэтому если программа предназначена для рассылки и
выполнения в сети, объединяющей машины разного типа, которые имеют различные операционные системы, то она должна
быть независимой как от операционных систем, так и от типа используемых машин. Чтобы отметить этот уровень независи-
мости, используется термин кроссплатформенное программное обеспечение. Иными словами, кроссплатформенное про-
граммное обеспечение – это программы, которые не зависят ни от операционной системы, ни от аппаратного обеспечения, а
значит, могут выполняться на разных компьютерах, объединенных в сеть.
Кроме того, хотя программист и не обязан больше кодировать программу с помощью нулей и единиц, он все еще выну-
жден мыслить в терминах пошагового выполнения команд машинного языка. Это аналогично проектированию дома из до-
сок, гвоздей, кирпичей и других материалов. Конечно, реальная конструкция дома состоит именно из этих элементарных
вещей, но проектировать его все же легче, имея дело с комнатами, окнами, дверьми и прочими подобными понятиями.
Короче говоря, элементарные примитивы, из которых в конечном счете должен быть сконструирован продукт, вовсе не
обязательно должны использоваться и при разработке проекта этого продукта. При проектировании удобнее пользоваться
примитивами более высокого уровня, каждый из которых представляет концепцию, связанную с некоторой функцией конеч-
ного продукта достаточно высокого уровня. По окончании проектирования эти примитивы могут быть выражены с помо-
щью концепций более низкого уровня, относящихся к деталям их реализации.
Следуя такому подходу, специалисты по компьютерам стали разрабатывать языки программирования, которые больше
подходили для целей разработки программного обеспечения, чем низкоуровневые языки ассемблера. В результате появились
языки программирования третьего поколения, которые отличались от предыдущих поколений тем, что их языковые конст-
рукции имели более высокий уровень и были машинно-независимыми. Наиболее известными примерами ранних языков
третьего поколения являются FORTRAN (FORmula TRANslator – переводчик формул), который был предназначен для научных
и инженерных расчетов, и COBOL (COmmon Business-Oriented Language – язык общего назначения деловой ориентации), разра-
ботанный специалистами военного морского флота США для решения экономических задач.
В общем случае язык программирования третьего поколения представляет собой определенный набор языковых конст-
рукций достаточно высокого уровня, предназначенный для разработки программного обеспечения. По существу, точно так
же был разработан и наш псевдокод, описанный в главе 4. Каждая из языковых конструкций была разработана так, чтобы ее
можно было реализовать в виде последовательности низкоуровневых примитивов, существующих в машинных языках. Рас-
смотрим следующий оператор:
Total ← Price + Tax
Он представляет собой выражение высокого уровня, в котором совершенно отсутствуют указания, как именно опреде-
ленная машина должна выполнять поставленную задачу. Однако этот оператор вполне можно реализовать в виде последова-
тельности машинных команд, которые мы обсуждали выше. Таким образом, показанная ниже структура потенциально явля-
ется языковой конструкцией высокого уровня:
идентификатор ← выражение
После того как необходимый набор примитивов высокого уровня будет определен, пишется программа, называемая
транслятором (translator – переводчик). Она предназначена для перевода программ, записанных с использованием примити-
вов языка высокого уровня, на машинный язык. Подобный транслятор похож на программу-ассемблер второго поколения, за
исключением того, что ему часто приходится объединять (или компилировать, от англ. compile) несколько машинных инст-
рукций в короткие последовательности команд, предназначенные для имитации выполнения отдельных примитивов высоко-
го уровня. Именно поэтому подобные программы-переводчики часто называют компиляторами. Разработку первого компи-
лятора приписывают Грейс Хоппер (Grace Hopper), которая играла ведущую роль в продвижении концепции языков про-
граммирования высокого уровня. Действительно, идея писать программы в форме, близкой к естественному языку, была
настолько революционной, что многие руководители поначалу отвергали ее.
Популярной альтернативой трансляторам являются интерпретаторы (interpreters), предложенные как еще один способ
выполнения программ, написанных на языках программирования третьего поколения. Эти программы подобны транслято-
рам, однако они выполняют команды программы непосредственно после их перевода, а не записывают, подобно транслято-
рам, переведенный код в виде выполняемого модуля, предназначенного для последующего использования. Это означает, что
вместо создания копии программы на машинном языке, которую необходимо будет выполнить позже, интерпретатор немед-
ленно выполняет все переведенные им инструкции.
Машинная независимость. С появлением языков программирования третьего поколения цель обеспечения машинной
независимости программ была в основном достигнута. Поскольку операторы в языках третьего поколения не привязаны к
особенностям какой-то конкретной машины, они легко могут быть скомпилированы на любом компьютере. Теоретически
программа, написанная на языке третьего поколения, может быть выполнена на любой машине за счет использования соот-
ветствующего компилятора.
В действительности не все так просто. При разработке самого компилятора приходится учитывать определенные огра-
ничения, накладываемые той машиной, для которой он предназначен. В результате эти ограничения отражаются на языке
программирования, который подлежит переводу на машинный язык. Например, размер машинных регистров и ячеек памяти
влияет на максимальный размер значений целых переменных, которыми может непосредственно оперировать программа.
Такие ограничения приводят к тому, что один и тот же язык программирования на разных машинах имеет свои особенности,
или диалекты. Вследствие этого программистам часто приходится выполнять, как минимум, легкую модификацию про-
граммы при переносе ее с одной машины на другую.