Введение
[Оглавление] [<< страница] [>>страница]


   1. Введение
 

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

Во всех таких случаях значительные объемы информации, подлежащей обработке, в некотором смысле представляют абстракцию некоторого фрагмента реального мира. Информация, поступающая в машину, состоит из определенного множества данных, относящихся к какой-то проблеме, — это именно те данные, которые считаются относящимися к данной конкретной задаче и из которых, как мы надеемся, можно получить (вывести) желанный ответ. Мы говорим о данных как об абстрактном представлении реалий, поскольку некоторые свойства и характеристики объектов при этом игнорируются. Считается, что для конкретной задачи они не являются существенными, определяющими. Поэтому абстрагирование — это упрощение фактов.

В качестве примера можно взять, скажем, список (файл) некоторых служащих. Каждый служащий в этом списке представляется (абстрагируется) как некоторое множество данных, относящихся либо к тому, что он делает, либо к процедурам, "обрабатывающим" его деятельность. Это множество может включать и некоторые идентифицирующие данные вроде его (или ее) фамилии или оклада. Однако маловероятно, что сюда будут включаться такие посторонние сведения, как цвет волос, вес или рост.

Решая любую задачу с помощью машины или без нее, необходимо выбрать уровень абстрагирования, т. е. определить множество данных, представляющих реальную ситуацию. При выборе следует руководствоваться той задачей, которую необходимо решить. Затем надлежит выбрать способ представления этой информации. Здесь уже необходимо ориентироваться на те средства, с помощью которых решается задача, т. е. учитывать возможности, предоставляемые вычислительной машиной. В большинстве случаев эти два этапа не бывают полностью независимыми.

Выбор представления данных часто является довольно трудной проблемой, ибо не определяется однозначно доступными средствами. Всегда нужно принимать во внимание и операции, которые выполняются над этими данными. Вот хороший пример: представление чисел. Они сами по себе уже абстракции некоторых свойств объектов, которые следует как-то охарактеризовать. Если единственной (или доминирующей) операцией будет сложение, то хорошим способом представить число п будет просто последовательность из п"черточек". При таком представлении правило сложения действительно и очевидно, и просто. В основу "римского" представления положен тот же принцип простоты, и правила сложения для небольших чисел столь же просты. С другой стороны, "арабское" представление чисел требует далеко не очевидных правил (даже для небольших чисел), правила требуют запоминания, выучивания наизусть. Ситуация, однако, изменяется, если речь заходит о сложении больших чисел или введении умножения и деления. Разложение таких операций на более простые оказывается значительно проще в случае арабского представления, что объясняется систематичностью представления, основанного на "позиционном весе" цифр числа.

Хорошо известно, что в основе внутреннего представления чисел в вычислительных машинах лежат двоичные цифры. Для человека такое представление не подходит: уж очень велико число таких цифр. Зато оно очень подходит для электронных схем: значения 0 и 1 можно удобно и надежно кодировать наличием или отсутствием электрического тока или магнитного поля.

На этом примере можно обнаружить, что вопросы представления часто разбиваются на несколько уровней детализации. Представьте себе, что необходимо задать положение некоторого объекта. Первое решение может привести к выбору пары вещественных чисел в прямоугольной или полярной системе координат. Второе решение — к представлению с плавающей запятой, где каждое вещественное число х состоит из пары целых чисел, обозначающих дробную часть f и показатель степени е некоторого основания (так, что х = f * 2е). Третье решение — оно основывает на знании того, как в машине хранятся данные, — может привести к двоичному, позиционному представлению для целых чисел. И последнее, двоичные цифры можно кодировать направлением магнитного поля в "магнитном запоминающем устройстве". Очевидно, что первое из решений в этой цепочке зависит главным образом от постановки задачи, а последующие все больше и больше — от используемого инструмента и методов работы с ним. Так, вряд ли можно требовать, чтобы программист решал какое следует использовать представление чисел или каковым будут характеристики запоминающего устройства. Такие решения низших уровней можно оставлять создателям самих машин, они лучше других информированы о сегодняшней технологии влияющей на выбор, который затем будет распространен на все (или почти все) приложения, связанные с использованием чисел.

В таком контексте становится очевидным значение языков программирования. Любому языку программирования соответствует некоторая абстрактная машина, способная интерпретировать понятия, используемые в этом языке. Это тоже некоторый уровень абстрагирования от реальных устройств, использованных в существующих машинах. Таким образом программист, использующий такой язык высокого уровня, освобождается (и ограждается) от вопросов представления чисел, если числа в контекст этого языка — элементарные объекты.

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

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

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

Ясно, что нам хотелось использовать привычные математические понятия чисел, множеств, последовательностей и т. п., а не присущие машинам понятия вроде строк разрядов. Столь же очевидно, что мы хотели использовать и понятия, для которых, и это уже известно, существуют эффективные трансляторы. Причем не хотелось бы как употреблять машинно-ориентированный или машинно-зависимый язык, так и описывать программы для машины в абстрактных понятиях, оставляющих открытыми вопросы представления.

[Оглавление] [<<страница] [>>страница] [В начало ]