К. Йенсен, Н. Вирт - Паскаль - Руководство для пользователя (1109480), страница 20
Текст из файла (страница 20)
' Новый язык, безусловно, не следует создавать только ради новизны. В качестве его основы нужно использовать уже существующие языки, если они удовлетворяют упомянутым критериям и не препятствуют систематическому подходу. В этом смысле в качестве основы Паскаля был использован Алгол-60, так как он больше подходит для обучения, чем другие стандартные языки. Из Алго- 150 Описание я»»ма ла-60 были «скопированы» принципы создания сложных структур и фактически вид выражения. Однако мы не сочли возможным и целесообразным «встраивать» Алгол-60 как подмножество Паскаля: некоторые принципы его построения, особенно связанные с описаниями, оказались бы несовместимы с принципами, обеспечнваюшими естественное и удобное представление новых конструкций в Паскале.' Основные расширения языка Паскаль по сравнению с Алголом- 60 связаны с возможностями построения данных сложной структуры; отсутствие таких возможностей в Алголе-60 считается главной причиной относительной узости области его применения.
Введение записей и файлов позволило решать с помощью Паскаля задачи коммерческого типа или по крайней мере демонстрировать такие задачи в курсе программирования. 2. ОБЗОР ЯЗЫКА Любая программа для вычислительной машины состоит из двух основных частей: описания действий, которые следует выполнить, и описания данных, с которыми манипулируют эти действия. Действия задаются так называемыми операторами, а данные— описаниями и определениями. Данные представляются с помощью значений переменных. Каждая встречающаяся в некотором операторе переменная должна вводиться через описание переменной, связывающее с этой переменной имя и тип данных. Тип фактически определяет множество значений, которые может принимать переменная, и ограничивает множество операций, которые можно над нею выполнять. В Паскале тип можно либо явно определить в описании переменной, либо с помощью описания типа сопоставить с ним некоторое имя типа и затем уже ссылаться на этот тип через это имя.
Простые типы состоят из предопределенного типа Кеа) (вещественный) и различных предопределенных ординальных«типов. Каждый простой тип определяет некоторое упорядоченное множество значений. Любой же ординальный тип характеризуется взаимно однозначным отображением его значений на некоторый интервал целых чисел — так называемые ординальные номера этих значений. Основными ординальными типами являются определяемые программистом перечисляемые (епцшега1ед) типы и предопреде- и Си. сноску нн с. 24. — Примем. пер.
2. Обзор язмзо 151 ленные типы — Воо!еап (логнческий), Сваг (символьный) и!п(епег (целый). Перечисляемый тип вводит новое множество значений, причем каждое из значений обозначается некоторым именем, отличным от других имен. Значения типа С(1аг обозначаются с помощью «закавычивания» символов, а вещественные н целые значения — с помощЬю чисел (последнне синтаксически отличаются от имен).
Множества значений типа Сваг и их графическое представление варьиру1стся от реализации к реализации и зависят от множества символов, принятого на каждой конкретной машине. Ордннальные типы можно определять н как диипазоны любых основных ординальиых типов (базовых типов). Для этого нужно указать самое маленькое и самое большое значения из интервала значений, относяшихся к этому диапазону. Составные (з(гпс1цгед) типы определяются путем описания типов их компонент и указания метода объединения (компонент в единое целое. — Примеч.
пер.). Методы объединения отличаются один от другого механизмами, позволяюшнми обращаться к компонентам переменной составного типа. В Паскале существуют четыре основных метода объединения, порождающие соответственно такие структуры данных: массивы, записи, множества и файлы. В массивах все компоненты одного типа. Обращение к ним происходит с помощью вычисляемых индексов, тип которых указывается в описании самого массивового типа. Индексы должны относиться к ординальному типу. Обычно это некоторый перечисляемый тип илн диапазон из целого типа.
Если задать значение, относяшееся к типу индекса, то переменная с индексом укажет одну из компонент массива. Поэтому всякую переменную-массив можно рассматривать как некоторое отображение типа индекса в тип компонент. Время, затрачиваемое на обрашение к одной компоненте, не зависит от значения индекса. Отсюда и структуры класса «массив» называются структурами с произвольным доступом. В записях компоненты (называемые полями) не обязательно относятся к одному типу. Для того чтобы тип поля был очевиден из текста программы (не прибегая к выполнению программы), поля определяются не через вычисляемые значения, а просто с помоШью уникальных имен.
Такие имена полей указываются в описании типа. Время, необходимое для обращения к какой-либо компоненте, опять же не зависит от имени поля, и записи поэтому относятся к структурам с произвольным доступом. Можно задавать записной тип с несколькими вариантами. Это означает, что различные переменные, хотя про них и говорят, что они относятся к одному типу, могут иметь несколько отличную друг ,от друга структуру. Разница может заключаться и в числе, н в типе !52 Описание немка компонент. Вариант, к которому относится текушее значение записи, может указываться посредством поля, общего для всех вариантов и называемого полем признака.
Обычно общая для всех вариантов часть состоит из нескольких компонент, в которые включается и поле признака. Всякий множественный тип определяет множество значений, представлякицее собою множество-степень его базового типа (основания) . Базовым типом должен быть ординальный тип и обычно это бывает какой-нибудь перечисляемый тип, тип Сваг или диапазон из целых чисел. Компоненты (элементы) множества прямо не доступны, однако предусмотренные операции над множествами (включающие проверку принадлежности значения множеству) и конструкторы множеств позволяют и порождать множества, и манипулировать ими.
Структуры класса «файл» представляют собою последовательность компонент одного типа. В последовательности определен некоторый естественный порядок компонент. В любой момент непосредственно доступна только одна компонента. Ее можно либо «просматривать», либо «формировать»; одновременно делать то и другое невозможно. К остальным компонентам можно «прийти», лишь двигаясь шаг за шагом вдоль файла. Файл формируется посредством последовательных добавлений в его конец новых компонент. Поэтому определение файлового типа не задает число компонент. Описание переменной связывает с именем некоторый тип, и в момент активации блока (см, ниже), где встретилоср такое описание, порождается переменная, идентифицируемая упомянутым именем.
Переменные, описываемые такими явными описаниями, иногда называют статическими. Кроме того, переменную можно создать, выполняя некоторый оператор; такое динамическое формирование дает то, что называется ссылкой (заменяющей явное имя). Впоследствии эта ссылка используется для идентификации созданной переменной. Значение ссылки можно присваивать персменной или функции, относящимся к типу этой ссылки. Любой ссылочный тип имеет фиксированный тип области, и каждая переменная, идентифицированная некоторым ссылочным значением, относяШимся к определенному ссылочному типу, принадлежит его типу области.
Кроме таких идентифицирующих значений, в любой ссылочный тип включается и значение ш!, не указывающее ни . на какую переменную. Поскольку компоненты составных переменных могут относиться к ссылочным типам, а типы области этих ссылочных типов в свою очередь могут быть составными, то с помощью ссылок можно представлнть конечные Графы во всей их полноте.
х Об»ор ялика ' !58 Среди операторов наиболее важный — оператор присваивания. Он указывает, что значение, полученное при вычислении некоторого выражения, необходимо присвоить некоторой переменной (или ее компоненте). Выражение состоит из переменных, констант, границ индексов параметров-массивов, конструкторов множеств и операций, а также функций, примсняемых к указанным величинам и дающих новые, результирующие значения. Переменные, константы и функции либо описываются в программе, либо относятся к стандартным («предописанным») объектам. В Паскале определяется фиксированное множество операций, каждую из которых можно рассматривать как отображение типов операндов в тип результата.
Множество операций делится на следующие группы: !. Арифметические операции — сложение, вычитание, изменение знака, умножение, деление и вычисление остатка. 2. Логические операции — отрицание, объединение (ог) и конъюнкция (апд). 3. Операции над множествами — объединение, пересечение, разность. 4. Операции отногиения равенство, неравенство, упорядоченность, принадлежность к множеству и включение. Тип результата операции отношения — Воо(еап.
Оператор процедуры вызывает выполнение указанной процедуры (см. ниже). Операторы присваивания и процедуры фигурируют в качестве компонент или «строительных блоков» сложных операторов, которые задают последовательное, выборочное либо повторяюгцееся выполнение своих составляющих. Последовательное выполнение задается составным оператором, условное или выборочное — условным оператором, или оператором варианта, повторяющееся — оператором цикла с предусловием, с постусловием и с параметром (шагом).
Условный оператор выполняет (или не выполняет) оператор в зависимости от значения логического выражения, а оператор варианта позволяет в соответствии со значением ординального выражения выбрать из многих операторов один. Цикл с шагом используется для выполнения оператора- компоненты, причем каждый раз управляемой переменной (параметру цикла) присваивается очередное ординальное значение. В других же случаях используются циклы с предусловиями и постусловиями. Кроме того, в Паскале предусмотрены и операторы перехода, указывающие, что выполнение должно продолжаться с другого места программы; зто место маркируется меткой. Метка должна быть описана.
Операторы н описания меток, констант, типов, переменных, процедур и функций объединяются вместе в блоки. На метки, кон- сйс Описание иееиис станты, переменные, процедуры.и функции, описанные в некотором блоке, можно ссылаться только внутри данного блока, поэтому они называются локальными по отношению к данному блоку.
Их имена имеют смысл только в тексте программы, составляющем соответствующий блок, и называемом областью действия (зсоре) этих имен. Блок же лежит и в основе описаний програмсс, процедур и функций; в этих случаях блоку дается некоторое имя, с помощью которого можно обозначать такой блок. Так как процедуры и функции могут вкладываться одна в другую, то вложенными могут быть и области действия.