logo search
Языки программирования

Глава 1

Что такое

языки программирования

1.1. Некорректный вопрос

Первый вопрос, который обычно задает человек, впервые сталкивающийся с новым языком программирования:

Что этот язык может «делать»?

Неявно мы сравниваем новый язык с другими. Ответ очень прост: все язы­ки могут «делать» одно и то же — производить вычисления! В разделе 1.8 объ­яснена правомерность такого ответа. Однако, если все они могут выполнять одно и то же — вычисления — то, несомненно, причины существования сотен языков программирования должны быть в чем-то другом.

Позвольте начать с нескольких определений:

Программа — это последовательность символов, определяющая вычисление.

Язык программирования — это набор правил, определяющих, какие по­следовательности символов составляют программу и какое вычисление описывает программа.

Вас может удивить, что в определении не упоминается слово «компьютер»! Программы и языки могут быть определены как сугубо формальные матема­тические объекты. Однако люди больше интересуются программами, чем другими математическими объектами типа групп, именно потому, что про­грамму — последовательность символов — можно использовать для управле­ния работой компьютера. Хотя мы настоятельно рекомендуем изучение тео­рии программирования, здесь ограничимся, в основном, изучением того, как программы выполняются на компьютере.

Эти определения следует понимать в самом широком смысле. Например, сложные текстовые процессоры обычно имеют средство, которое позволяет запоминать последовательность нажатий клавиш и сохранять их как макрос, чтобы всю последовательность можно было выполнять с помощью единственного нажатия клавиши. Несомненно, это — программа, поскольку после­довательность нажатий клавиш определяет вычисление, и в сопроводи­тельной документации обязательно будет определен макроязык: как инициа­лизировать, завершать и называть макроопределение.

Чтобы ответить на вопрос, вынесенный в название главы, вернемся к пер­вым цифровым компьютерам, очень похожим на простые калькуляторы, ка­кими сегодня пользуются для расчетов в магазине. Они работали по «жест­кой» программе, которую нельзя изменить.

Наиболее значительным из первых шагов в усовершенствовании компью­теров была идея (автором которой считается Джон фон Нейман) о том, что описание вычисления (программу) можно хранить в памяти компьютера так же, как данные. Компьютер с запоминаемой программой, таким образом, стано­вится универсальной вычислительной машиной, а программу можно изме­нять, только заменяя коммутационную доску, вводя перфокарты, вставляя дискету или подключаясь к телефонной линии.

Поскольку компьютеры — двоичные машины, распознающие только нули и единицы, то хранить программы в компьютере технически просто, но прак­тически неудобно: каждая команда должна быть записана в виде двоичных цифр (битов), которые можно представить механически или электрически. Одним из первых программных средств был символический ассемблер. Ассемб­лер берет программу, написанную на языке ассемблера (каждая команда пред­ставлена в нем в символьном виде), и транслирует символы в двоичное пред­ставление, пригодное для выполнения на компьютере. Например, команду

load R3,54

означающую «загрузить в регистр 3 данные из ячейки памяти 54», намного легче прочитать, чем эквивалентную последовательность битов. Трудно пове­рить, но термин «автоматическое программирование» первоначально отно­сился к ассемблерам, так как они автоматически выбирали правильную по­следовательность битов для каждого символа. Известные языки программи­рования, такие как С и Pascal, сложнее ассемблерных языков, потому что они «автоматически» выбирают адреса и регистры и даже «автоматически» выби­рают последовательности команд для организации циклов и вычисления арифметических выражений.

Теперь мы готовы ответить на вопрос из названия этой главы.

Язык программирования — это механизм абстрагирования. Он дает воз­можность программисту описать вычисления абстрактно и в то же вре­мя позволяет программе (обычно называемой ассемблером, компилято­ром или интерпретатором) перевести это описание в детализированную форму, необходимую для выполнения на компьютере.

Теперь понятно, почему существуют сотни языков программирования: для двух разных классов задач скорее всего потребуются различные уровни абстракции, и у разных программистов будут различные представления о том, какими должны быть эти абстракции. Программист, работающий на С, впол­не доволен работой на уровне абстракции, требующем определения вычисле­ний с помощью массивов и индексов, в то время как составитель отчета отда­ет предпочтение «программе» на языке, содержащем функции текстовой об­работки.

Уровни абстракции легко различить в компьютерных аппаратных средст­вах. Первоначально монтажные соединения непосредственно связывали дис­кретные компоненты, такие как транзисторы и резисторы. Затем стали ис­пользоваться стандартные подсоединяемые с помощью разъемов модули, за которыми последовали небольшие интегральные схемы. Сегодня компьюте­ры целиком собираются из горстки чипов, каждый из которых содержит сот­ни тысяч компонентов. Никакой компьютерщик не рискнул бы разрабаты­вать «оптимальную» схему из индивидуальных компонентов, если существует набор подходящих чипов, которые выполняют нужные функции.

Из концепции абстракции вытекает общее правило:

Чем выше уровень абстракции, тем больше деталей исчезает.

Если вы пишете программу на С, то теряете возможность задать распреде­ление регистров, которая есть в языке ассемблера; если вы пишете на языке Prolog, то теряете имеющуюся в С возможность определить произвольные связанные структуры с помощью указателей. Существует естественное проти­воречие между стремлением к краткому, ясному и надежному выражению вы­числения на высокоабстрактном уровне и стремлением к гибкости подробно­го описания вычисления. Абстракция никогда не может быть такой же точной или оптимальной, как описание низкого уровня.

В этом учебнике вы изучите языки трех уровней абстракции. Опуская ас­семблер, мы начнем с «обычных» языков программирования, таких как Fortran, С, Pascal и Pascal-подобные конструкции языка Ada. Затем в части 4 мы обсудим языки типа Ada и С ++, которые позволяют программисту созда­вать абстракции более высокого уровня из операторов обычных языков. В за­ключение мы опишем языки функционального и логического программиро­вания, работающие на еще более высоком уровне абстракций.