Текст книги "Программное обеспечение и его разработка"
Автор книги: Джозеф Фокс
Жанр:
Базы данных
сообщить о нарушении
Текущая страница: 12 (всего у книги 21 страниц)
Известно, что обмен сложными идеями и концепциями является основной трудностью при управлении сложными системами, поэтому мы должны быть благодарны за любую помощь, которая оказывается нам в этой области. Большинство новых методов очень полезно именно в данном отношении, поэтому мы рекомендуем всем их использовать.
Трудности нововведений
Как и всякая новая человеческая деятельность, новые методы проектирования оказываются тоже очень трудными для введения. Изменениям сопротивляются; правила раздражают; строгости кажутся бесполезными. Но это бывает только в начале. Как и многие другие полезные новые методы, эти методы в конце концов признаются «единственно возможными», а на все старые при этом начинают смотреть с изумлением и весьма критически.
Это происходит со всеми новыми методами – как мы уже видели, не было исключением и структурное программирование. Человеку нужна по крайней мере неделя, а обычно даже две недели формального изучения и затем несколько месяцев тренировок, чтобы окончательно признать новый метод. Тут нужны контроль и принуждение. Весь наш персонал, занятый в информационных системах – программисты, аналитики и другие, – нуждается в таком «вдалбливании».
Если группа разработки и внедрения информационной системы состоит из нескольких сотен человек, цикл обучения получится весьма дорогостоящим. Его, однако, необходимо провести. Результаты настолько значительны, что пренебрегать новыми методами нельзя.
Написание программ – программирование
Мы приступаем к изучению деятельности, которую многие ошибочно считают разработкой программного обеспечения, а именно к изучению процесса написания программ. Это всего лишь часть общего процесса разработки программ. В больших системах эта часть является самой простой из всех шести частей разработки. В небольших проектах эта часть требует наибольшей доли времени.
В какой-то момент проектирование доходит до такого низкого уровня, что для того, чтобы заставить вычислительную машину выполнить то, что задумал проектировщик, достаточно написать соответствующие команды.
Для очень маленьких программ, которые пишутся одним, двумя программистами, единственной загвоздкой тут является выбор инструмента, т. е. языка, на котором следует писать. А при программировании больших программ этот вопрос также является одним из ключевых.
Наше изучение процесса написания команд мы разделим на три части – выбор языка программирования, процесс доведения программы до выполнения и управление этими двумя процессами. Мы ограничимся только изучением деятельности по написанию маленьких программ. Написание небольшой программы (до 10 тыс. строк текста программы) не так уж сильно отличается от написания программы в 1 млн. строк; различия скорее находятся в других частях процесса их разработки. Поскольку различия в написании невелики, мы будем обсуждать проблемы, не уделяя внимания дополнительным обязанностям, имеющимся у программистов при программировании программ в 1 млн. строк. Конечно, различия все-таки есть, все дополнительные обязанности мы обсудим в следующем разделе, посвященном компоновке. Дополнительная нагрузка на программиста обычно заключается в некоторых ограничениях и устанавливает определения данных, констант и интерфейсов.
После того как программист выяснил алгоритм и структуру программы, он начинает писать команды.
Написание программы обычно выглядит как акт записи команд на листке бумаги, которые, возможно, будут переданы на машину. После того как команды будут записаны, их надо перенести на какой-нибудь носитель информации, с которого их сможет считать машина и с которого они могут быть загружены в вычислительную машину, чтобы проверить, выполняет ли программа то, что от нее требовали. Сотни тысяч программистов водят карандашом по бумаге и пишут команды. Они занимаются «кодированием». В настоящее время все большее число программистов вводят в машину команды, пользуясь терминалами, но большинство делают это, уже имея готовый текст.
Важнейшие моменты, связанные с написанием текста программ, таковы:
1. Ясность того, что нужно сделать – это мы уже обсуждали.
2. Язык, который будет использоваться, и стандарты, которым необходимо следовать.
3. Процесс управления преобразованием программ с языка программирования на машинный язык.
4. Инструментарий для реализации пп. 2 и 3.
Языки
Лингвисты, занимающиеся семантикой языков, до сих пор продолжают открывать в языках новые свойства. Все еще продолжаются дебаты по вопросу, что важнее – разговорный язык или язык письменный. В книге «Введение в теоретическую лингвистику» Джон Лайонс[20]20
J. Lyons. Introduction to Theoretical Linguistics. (London: Cambridge University Press, 1972).
[Закрыть] отмечает, что язык – это не просто свод правил, лингв, это и не собрание всех возможных устных и письменных форм слов, но и то и другое вместе. Даже неправильно произнесенное, синтаксически неправильное выражение может быть понято. Это происходит потому, что слушатель заполняет пропуски и исправляет ошибки. К сожалению, вычислительная машина и ее транслирующая программа (ассемблер или транслятор) делают только то, что им приказывают. Даже самые хорошие трансляторы имеют весьма ограниченный интеллект. Для языков вычислительных машин синтаксические правила приобретают решающее значение.
Наверное, не очень очевиден тот факт, что процесс получения команд основывается на трех важнейших положениях:
1. Вы должны понимать процесс, для выполнения которого пишутся команды.
2. Вы должны уметь сформулировать (выразить словами) последовательность команд.
3. Вы должны выбирать такие слова, которые будут поняты вашими собеседниками.
Мы часто предполагаем, что п.1 выполняется; что это не так, мы видели в разделе, посвященном определению требований. Мы также предполагаем, что человек, который может «выполнить процесс», может и облечь его в словесную форму, – это тоже не всегда так.
Теперь обратимся к третьему пункту – написание команд для конкретного исполнителя. В нашем случае исполнителем оказывается вычислительная машина, но, прежде чем переходить к командам для вычислительных машин, я хотел бы обсудить некоторую аналогию.
Если бы я был великим нейрохирургом, я мог бы сформулировать инструкции для разрабатываемой новейшей хирургической техники, у меня не было бы трудностей по выдаче таких инструкций другим нейрохирургам. Введите в мою аудиторию обычных хирургов, и моя задача сразу усложнится. Добавьте туда студентов-первокурсников медицинского института, и я не уверен, что вообще смогу выполнить свою задачу. И так далее.
Так же и с вычислительной машиной. Словарный запас ее крайне примитивен. Заставить ее что-то сделать, сказать это на ее родном языке, называемом машинным языком, исключительно трудно. И все же мы должны осуществлять сложные логические построения именно с таким словарным запасом, поскольку только на такие слова машина и может реагировать.
Самые первые пользователи вычислительных машин сразу поняли, что вести дела таким образом невозможно, поэтому и «наняли переводчиков».
Возвращаясь к аналогии с нейрохирургией, заметим, что этот процесс выглядит так – выдающийся хирург будет теперь передавать инструкции посреднику, который переведет их на язык, доступный студентам-первокурсникам медицинских институтов.
Так же обстоит дело и с вычислительными машинами. Мы больше не заставляем программистов пользоваться машинным языком, а переводим их на работу с языком высокого уровня. Мы нанимаем в качестве переводчика ту же самую вычислительную машину, которая будет выполнять процесс после его перевода (или трансляции), и помещаем в нее программу, которая будет осуществлять перевод: либо ассемблер, либо транслятор, либо и то и другое вместе (рис. 5.31).
Рис. 5.31. Процесс перевода (трансляции).
Для того чтобы машина могла выполнить перевод, в нее должны быть введены программы ассемблера или транслятора.
Транслятор воспринимает операторы языков высокого уровня, т. е. Фортрана, Кобола, Паскаля, Бейсика, и «заставляет» вычислительную машину преобразовать эти операторы в команды на машинном языке, которые затем можно будет в свою очередь поместить в машину и выполнить с целью решить реальную задачу – например напечатать платежную ведомость.
Такой процесс выполняется по крайней мере в два этапа. В нем присутствуют этап трансляции и этап использования. Пока никто даже не приступил к созданию машины, которая могла бы сразу понимать языки высокого уровня[21]21
Это утверждение не совсем верно. Коммерческих машин такого типа еще нет, но экспериментальные уже есть. – Прим. ред.
[Закрыть].
Можно отметить, что в аналогии с выдающимся нейрохирургом он теперь не должен мучиться, объясняя свои операции на языке новичков. Так же и программисты. Языки высокого уровня позволяют им писать ближе к собственному уровню.
Мощность языка и связанные с ней трудности
Чем мощнее язык, тем труднее его изучить, так же как трудно выучить медицинскую терминологию и трудно заучивать слова с многозначной семантикой.
Рис. 5.32. Зависимость легкости обучения от мощности языка.
Если пытаться построить график зависимости легкости производства хорошего программного обеспечения от легкости обучения языку, получится нечто вроде того, что представлено на рис. 5.32.
Под хорошим программным обеспечением я подразумеваю хорошо скомпонованные, легко просматриваемые, хорошо документированные программы. Значит ли это, что нам никогда не следует пользоваться Бейсиком? Конечно, нет. Мы иногда пишем и такие программы, для которых не нужна ни легкость модификации, ни легкость расчленения.
Рис. 5.33. Третье измерение – процедурно-ориентированные языки.
Итак, выбор языка зависит от того, что мы собираемся писать. На графике не отмечены языки APL и LISP. Эти языки применяются не для построения сложного программного обеспечения, а для решения задач. Программы на машинных языках, получающиеся после трансляции с данных языков, не имеют большого значения[22]22
Более того, часто такие программы вообще отсутствуют, ибо эти языки, как правило, интерпретируются. – Прим. ред.
[Закрыть]; в большинстве случаев их даже не видят и не сохраняют. Я просто не могу себе представить, чтобы на APL кто-нибудь решился строить большую систему программного обеспечения. На рис. 5.33 изображены процедурно-ориентированные языки.
ПОЯ – другой тип языков. ПОЯ означает проблемно-ориентированный язык, или, иначе, процедурно-ориентированный язык[23]23
В традиционной литературе принято различать эти два понятия. На процедурно-ориентированном языке описывается процедура получения решения любой задачи. Это универсальные языки высокого уровня. На проблемно-ориентированном языке формулируется сама задача. Естественно, что такой язык универсальным быть не может. – Прим. ред.
[Закрыть]. Эти языки также находятся на более высоком уровне абстракции, чем машинные языки. Их проектируют специально для решения какой-нибудь задачи или выполнения конкретной процедуры. Эти языки, следовательно, хорошо подходят именно для такого использования и не очень хорошо для других целей.
Среди этих языков заслуживают упоминания:
APL – решение задач
LISP – обработка списков
GPSS – универсальное моделирование
SIMSCRIPT – обработка текстов
ATLAS – язык министерства обороны США, применяемый в тестовом оборудовании
Целью этих языков является сокращение времени разработки программ. Делается это путем облегчения средств, с помощью которых создатель программы доводит программу до выполнения на машине. В этом смысле эти языки нельзя называть универсальными. Они реже используются при разработке регулярно используемых программ, чем при разработке программ, выполняемых либо единожды, либо очень редко.
Именно поэтому мы не будем уделять этим языкам чересчур много внимания.
Каждый язык представляет собой объединение словаря и синтаксиса. Словарь – это список слов, которые понятны транслятору. Синтаксис – это список правил расположения элементов словаря – порядок следования, знаки препинания, допустимые комбинации.
Когда вычислительная машина совместно с транслирующей программой воспринимает оператор языка высокого уровня, происходит сразу много разных действий. Начинается трансляция, а вместе с ней расширение. Когда я говорю своему помощнику: «Пойдите в библиотеку и принесите мне копию X», остается много не уточненных подробностей.
Помощник сам восполняет недостающие детали: какая библиотека, когда, как туда добраться, где находится X, как получить его и т. д.
Человек способен сам провести подобное расширение команды, поскольку он достаточно умен и хорошо осведомлен. Даже если он никогда не бывал в этом городе, он легко сможет выяснить, куда надо пойти, но мне говорить об этом все равно не было бы необходимости. Это же относится и к языкам машины и трансляторам, которые с ними работают. Многие трансляторы допускают использование неописанных переменных.
Многие языки программирования пытаются добиться эффективности в одной или в нескольких областях применения. Они могут облегчить человеку выражение глобальной идеи или сделать так, чтобы окончательный вариант программы исполнялся на машине как можно быстрее. Приспособлен ли язык к данной проблеме? К общению с человеком? С машиной? Или какой-нибудь комбинации этих свойств? Что нужно знать человеку для постановки задачи, ее решения, выполнения искомого процесса? Как думают люди? Как они общаются? Работают? Пишут? Ошибаются? Что может заставить машину работать более продуктивно? Всякую машину? А эту машину?
Вот потому-то десятки миллионов тратятся каждый год на проектирование и разработку новых языков программирования. Вот потому-то люди занимаются всю свою жизнь исследованиями в области языков для вычислительных машин.
Рост числа языков
К счастью для программистов, разработка языков программирования началась практически одновременно с появлением вычислительных машин. К сожалению, языков для них образовалось великое множество. В министерстве обороны США было подсчитано, что в его организациях используется около тысячи разных языков! Почему? Потому что программисты создают себе собственные языки программирования! И еще потому, что нет хорошего способа определить, какая версия лучше, а какая хуже, даже при использовании. И еще потому, что до сих пор языки оставляют желать лучшего.
В то же время наметилась некоторая стабилизация. Министерство обороны выбрало семь языков (инструкция 5000.31), на которых будут писаться все новые «встроенные» системы реального времени (Имеются в виду языки: Фортран, Кобол, Джовиал, CMS-2, SPS, TACPOL и TOS).
После длительного и глубокого изучения министерство обороны представило новый язык Ада, основанный на некотором расширении Паскаля, разработанного Н. Виртом. Если Ада докажет свою полезность, она будет включена в список инструкции 5000.31. Это очень мощный, очень сложный язык.
Однако программисты предпочитают старые языки. Сообщество программистов непоколебимо отказывается переходить на работу с новыми языками программирования. Подавляющее большинство программистов продолжают писать на Коболе и Фортране, несмотря на то что оба этих языка в настоящее время считаются устаревшими.
Почему же все старые языки продолжают существовать и остаются столь популярными? Они были изучены первыми! Тони Хоар в своем письменном докладе военно-морскому флоту констатировал следующее:
Привязанность программистов к существующим языкам сильнейшим образом контрастирует с энтузиазмом различных комитетов, утверждающих, что языки не отвечают поставленным требованиям. Причина? …затрачено огромное количество времени на овладение языком, новый же язык представляет в этом отношении серьезную угрозу, или, что еще хуже, новый язык может оказаться даже более простым для изучения и более эффективен в использовании, что может совершенно подорвать с огромным трудом завоеванное положение эксперта по старому языку…
Таким образом, может получиться и так, что более легкий язык будет побежден сложным. Программисты из Советского Союза рассказывают аналогичные истории. По-видимому, одним из первых полученных ими языков был Кобол – англоязычный COBOL. Видимо, первые вычислительные машины попали туда из Соединенных Штатов[24]24
Это утверждение не соответствует реальному положению дел и лишний раз доказывает, сколь мало знают в США о нашей стране. – Прим. ред.
[Закрыть] и программисты должны были учить английский язык, для того чтобы воспользоваться оператором PRINT. Англоязычный COBOL выжил! Потому что старики были настроены против русскоязычного Кобола. «Пусть новички помучаются». Англоязычной версией Кобола пользуются до сих пор и в Германии.
После того как уже написано большое количество программ, перейти на новый язык трудно. Как говорят юристы, владение имуществом почти равносильно праву на него. Желание не расставаться с накопленным багажом неистребимо.
Язык и мышление
Язык, которым мы пользуемся, очень сильно воздействует на методику нашей работы. Многие утверждают, что язык формирует мышление. В книге, посвященной стилю письма и коротко названной «Стиль» Ф. Л. Лукас[25]25
Lucas F. L. Style, (New York: Collier Books, 1962.)
[Закрыть] пишет:
Вот прекрасная история о человеке, зашедшем в кафе для иностранцев, в котором уже сидели группы англичан, французов и немцев. Человек этот обратил внимание на то, что англичане в полном молчании сидели вокруг своего столика, французы говорили все разом, а немцы слушали друг друга по очереди с таким напряженным вниманием, что на мгновение поразили нашего героя. Потом он понял – они ждали конца фразы, чтобы услышать глагол (или его отрицание).
Это же можно отнести и на счет языков программирования. Выбор языка оказывает на весь дальнейший процесс глубокое воздействие. Почему Вирт предложил Паскаль? Потому что ему надоело учить студентов языкам, которые «слишком часто нельзя было логически объяснить».
Нотация, или система обозначений, помогает процессу мышления. Уайтхед и Рассел («Principia Mathematica», 1910) объяснили, что хорошая система обозначений способна освобождать мозг от излишних деталей и переключать его на обдумывание других вещей. Мощные языки типа APL дают возможность программисту заставить машину выполнить огромную работу с помощью весьма немногих команд.
Конструкция языка ограничивает возможности мышления. В лекции, прочитанной при вручении ему премии Тьюринга, Э. Дейкстра рассказал историю одного проведенного им эксперимента. Он разослал нескольким своим корреспондентам условие одной задачи и попросил их прислать ему алгоритм ее решения. Все они прошли мимо самого очевидного и элегантного решения, сказал Дейкстра, поскольку их понятие о повторных вычислениях было слишком тесно связано с представлением об управляющей переменной цикла и ее пошаговом изменении.
Ограничения, накладываемые языками
Уже с давних пор мы тщетно бьемся над созданием современного языка. Приведу обширную цитату из статьи Якоба Броновски «Логика ума» в сборнике «Чувство будущего»[26]26
Bronowski J. A. Sense of the Future: Essays in Natural Philosophy (Cambridge, Mass, and London, England, The MIT Press, 1977). Selected and edited by Pierro E. Ariotto in collaboration with Rita Bronowski.
[Закрыть].
Проблема принятия решения … такой поразительный вопрос сформулировал Давид Гильберт: очевидно ли, что … все математические утверждения, имеющие смысл, будут рано или поздно отнесены либо к истинным, либо к ложным…
В 1931 г. … Курт Гёдель доказал две замечательные и встреченные крайне недоброжелательно теоремы. В первой говорилось, что … любая не слишком простая логическая система может заключать в себе истинные утверждения, которые тем не менее не могут быть выведены из ее аксиом. Вторая теорема утверждала, что … про аксиомы такой системы … нельзя заранее сказать, что они свободны от внутренних противоречий. Коротко это можно сформулировать так – более или менее богатая логическая система никогда не может быть полной, и в то же время нельзя гарантировать ее непротиворечивость…
А. М. Тьюринг в Англии, а Алонсо Чёрч в Америке показали, что нельзя построить механическую процедуру, позволяющую проверить все утверждения логической системы и за конечное число шагов установить их истинность или ложность…
Тарский показал, что нельзя построить точный язык с универсальными свойствами; всякий формальный язык, который по крайней мере так же богат, как арифметика, содержит правильно построенные предложения, про которые нельзя сказать, истинны они или ложны…
Нельзя построить аксиоматическую систему, которая бы производила описание окружающего нас мира в полном соответствии с действительностью, причем каждой точке мира соответствует точка описания; в некоторых точках будут оставаться пробелы, которые невозможно заполнить с помощью дедукции; в других же точках может оказаться возможным прийти к противоположным выводам…
И наконец, теория Тарского продемонстрировала, и я думаю, что окончательно, что универсальное описание природы на едином замкнутом, непротиворечивом языке построить нельзя…
Это основной момент: язык, которым мы пользуемся для описания природы, предписывает (классификацией своих определений и аксиом) как форму, так и ограничения на открываемые нами законы…
Особенностью человеческих языков является то, что они построены на основе старых метафор и аналогий, которые служат благодатной почвой для изучения двусмысленностей и обнаружения скрытого сходства..
Многие логические проблемы вырастают из этого общего корня, а именно система значений для любого разумно богатого языка непременно включает в себя объекты самого языка. Это создает бесконечный спуск, бесконечный зал с отражающимися друг в друге зеркалами. Этот спуск попадает в фокус всех парадоксов логики, которые в каком-то смысле сродни классическому противоречию, известному еще грекам: они называли его критским парадоксом (или «парадоксом лжеца»)…
Бертран Рассел (совместно с Альфредом Нортом Уайтхедом в их общей книге «Principia Mathematica») попытался развязать узел парадоксов этого типа и положить конец нескончаемому потоку утверждений об утверждениях, построив теорию типов. Она предназначалась для того, чтобы удержать нас от использования того же самого языка для обсуждения вещей, которые этот язык обозначает, и для обсуждения фактов самого языка. Человеческий язык богат потому, что мы думаем о самих себе. Мы не можем исключить из человеческих языков ссылки на самого себя и при этом не превратить его из подлинно информационного языка в язык машинных команд…
Всякое размышление о мышлении обязательно включает ссылки на самого себя: первое же положение в философии Декарта, «Cogito, ergo sum», содержит такую ссылку. …Никакая логическая машина не может разрешить все трудности и парадоксы, создаваемые ссылками на себя…
Машина не является природным объектом, это человеческий артефакт, который подражает нам и пользуется нашим представлением о природе.
«СТРАННЫЕ ПЕТЛИ», о которых пишет Дуглас Хофстедтер в книге «Гёдель, Эшер, Бах: Вечная золотая лента»[27]27
Hofstadter D. «Godel, Escher, Bach: An Eternal Golden Braid» (New York: Basic Books, Inc., 1979).
[Закрыть], являются расширением этих идей.
А в своем письме-докладе ВМФ США Хоар писал:
…а те, кто должен внедрять только что спроектированные языки высокого уровня, сталкиваются с множеством невероятно сложных частных случаев, неоднозначностями и противоречиями. Нужно создавать комитеты по стандартизации … на это уходит не меньше 6 лет. Такая работа «разбивает души», ведь очевидно, что «правильного» разрешения всех неточностей начального проекта не существует…
От возникновения языка до его «успешной стандартизации» проходит 10 лет…
Это относится к Фортрану, Алголу и PL/1. Паскаль не стандартизован до сих пор.
Почему? Из-за необычных, сложных и неожиданных взаимовлияний одних разделов языка на другие.
Паскаль имеет слишком высокий уровень, чтобы можно было с удобствами проводить (например) двоичный ввод/вывод; этот язык имеет недостаточно высокий уровень для того, чтобы обеспечить полную гарантию безопасности при работе с записями. Включение в язык элементов как высокого, так и низкого уровня является очень сложной проблемой.
Поскольку вред наносят именно эффекты взаимодействия, нужно изучать весь язык, чтобы понять, что следует исключить из него.
Основная заслуга языка высокого уровня в том, что он помогает разуму при проектировании и документировании программ для вычислительных машин; помощь, оказываемая им при непосредственном кодировании, может иметь второстепенное значение[28]28
Отнесение помощи при кодировании на второй план несколько симптоматично; может, языки высокого уровня и не так уж ускоряют этот процесс? – Прим. ред.
[Закрыть].
В недавнем докладе (1978) военно-морскому флоту исследователи насчитали более 2570 различных возможностей или свойств, которые можно выделить в языках программирования. 2570!!
Какими же богатыми оказываются наш мозг и наши языки!!
Кроме сформулированных Броновски естественных сложностей богатых языков, существуют еще и проблемы, связанные с оптимизацией, возникающие при построении и языков, и трансляторов с них. При оптимизации одной из 12 характеристик невольно ущемляются интересы остальных.
Написав транслятор, который проводит трансляцию очень быстро, мы плохо повлияем на скорость выполнения рабочей программы. И наоборот.
Процесс написания программы
Процесс написания программы представляет собой итеративный процесс, состоящий из собственно написания, исполнения и исправления. Исправления потому, что редко какая программа с самого начала не имеет ошибок. В зависимости от задачи и от самого программиста эти три шага могут повторяться несколько, иногда очень много, раз. Программист пишет команды транслятору, который в свою очередь переписывает их на язык – более детальный – вычислительной машины. Но транслятор это не человек. Он не понимает полутонов, жестов, тонких намеков, интонаций, выражений лица и еще множества символов, присутствующих в общении человека-переводчика и говорящего или пишущего. Вычислительная машина плюс транслятор абсолютно педантичны. Необходимо, чтобы были правильными все запятые, пробелы, тире, а также их места – все, как определяется языком.
Когда программист представляет свою программу на трансляцию, первое, что делает транслирующая программа, – это проверяет все синтаксические ошибки, а если таковые находятся, исходная программа отвергается; это сопровождается напечатанными сообщениями о том, что в такой-то и такой-то точке программы найдены ошибки такого-то и такого-то типов. Пропущена скобка. Целое число умножается на число с плавающей точкой (в некоторых языках это запрещено).
Рис. 5.34. Итеративный процесс отладки программы.
Дж. Вейнберг[29]29
Weinberg G. Psychology of Computer Programming (New York: Van Nostrand Reinhold Company, 1971).
[Закрыть] указывает, что «типичный программист» в своей деятельности по доведению программы до выполнения на машине, проходит два этапа. Сначала он стремится добиться первой безошибочной компиляции. Компиляция – эта трансляция и расширение (добавление нужных программ). «Безошибочность» заключается в отсутствии синтаксических и очевидных логических ошибок, поскольку первый шаг состоит в получении «семантически правильной» программы. Для получения такой программы программист всякий раз при перезапуске программы на машине изменяет в ней несколько операторов.
Через некоторое время предпринимается и второй шаг. Команды на машинном языке загружаются в вычислительную машину и исполняются обычно с использованием тех значений данных, которые программист задал наряду с командами. Результаты выводятся на печать и возвращаются программисту. Программист изучает их с целью определить, правильна ли логика работы программы, причем обычно оказывается, что она неправильна. Он исправляет логику процесса и снова перезапускает программу. Когда выясняется, что программа работает правильно, она либо наконец вычисляет то, что нужно, если это отдельная программа, либо передается кому-то другому, кто будет включать ее в более крупную программу. Процесс этот выглядит так, как это изображено на рис. 5.34. Проверка синтаксиса трансляторами – это весьма полезный процесс, помогающий программистам находить не только ошибки в пунктуации, но также и некоторые логические ошибки.
Если, например, программист написал программу, в которой управление передается подпрограмме по имени СЛЕД, но ни одну из особых подпрограмм этим именем не назвал, транслятор отметит этот логический промах.
Кросс-транслятор
Язык высокого уровня типа Фортрана может использоваться в качестве входного языка на самых разных вычислительных машинах, имеющих свои собственные транслирующие (компилирующие) программы. Язык стандартизован, каждая машина имеет свою транслирующую программу и создает рабочую программу именно для себя.
Логическим шагом в использовании этих транслирующих программ является использование машины и некоторого транслятора для перевода с исходного языка на язык другой машины.
Это называется кросс-трансляцией. Ее обычно применяют в тех случаях, когда машина, на которой будет выполняться рабочая программа, очень мала (по памяти, устройствам ввода/вывода или возможностям центрального процессора). Пускать трансляторы на маленьких, медленных машинах не очень эффективно.
Использование кросс-трансляции машины выглядит так. Программа пишется на входном языке; она переводится на большой машине транслятором, который выдает программу на языке второй машины. Затем на этой второй машине выполняется полученная рабочая программа. Вторая, маленькая машина обычно имеет систему команд, совершенно отличную от той, которая имеется на большой машине.
Этот процесс является логическим следствием преимуществ машинной независимости языков высокого уровня. Машинная независимость позволяет нам передавать программу, написанную на стандартном языке, на машину любого типа и модели, если только на ней имеется транслятор, который может переводить программу с языка высокого уровня на машинный язык. Схема процесса приведена на рис. 5.35.
Изменения и исправления в программу обычно вносятся на входном языке, с тем чтобы после этого вновь ретранслировать ее кросс-транслятором. На маленькой машине может транслятора вообще не быть.
Рис. 5.35. Кросс-трансляция.
Этот процесс значительно ускоряет программирование. Очевидно, что его недостатком является необходимость иметь большую машину.
Не так очевидно то, что указанный транслятор должен быть доступен группе, фактически продолжающей разработку. Случается, что разработчики программ при создании программы пользуются частными трансляторами, а затем возвращают их владельцам. В результате группа сопровождения лишается возможности транслировать исправляемые программы. Отвратительная ситуация. На создание «новых» трансляторов были затрачены миллионы!
Множество форм одной программы
Частую путаницу вносит тот факт, что программа одновременно может существовать во многих формах сразу. Причем именно этого мы и хотим. Нам нужна «версия» программы на языке рабочей машины (для исполнения) и версия на входном языке (для модификации). Подробнее мы обсудим это позднее, а сейчас давайте посмотрим, какие формы может принимать программа. Сначала посмотрим на простое деловое письмо.
«Где мое письмо?»
«Ваша рукописная копия лежит на вашем письменном столе; отпечатанная копия находится на столе у начальника; имеются версия, хранимая в системе обработки текстов, и версия, передаваемая по телефонным проводам во Флориду, кроме того, одна копия передается через спутник связи в ФРГ». (См. рис. 5.36.) Некоторые из этих форм писем могут быть прочитаны людьми: некоторые могут читаться только вычислительными машинами.
Такое же бывает и с программами. На рис. 5.37 изображено всего пять различных форм, в которых может существовать программа печати платежной ведомости.
Вычислительные машины для трансляции
Часто забывают о том, что для перевода нам нужен не только транслятор, но и вычислительная машина. Это кажется очевидным, но при моей работе над тремя проектами больших программных систем, в которых именно для трансляции не хватало вычислительной мощности, это привело к потрясающему росту затрат на разработку систем.