Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

3345

.pdf
Скачиваний:
2
Добавлен:
15.11.2022
Размер:
4.34 Mб
Скачать

String фиксированной длины, заданной в декларации (без дескриптора)

String переменной длины, предел задан в дек- ла-рации (с дескриптором)

слово

 

 

 

 

 

 

 

R

E

L

A

 

 

 

 

 

 

 

 

T

J

V

J

 

 

 

 

 

 

 

 

T

V

-

-

 

 

 

 

 

 

 

 

 

 

 

 

Максимальная длина

 

 

 

 

 

Текущая длина

 

 

 

 

 

 

 

10

8

E

J

 

 

 

 

 

 

 

 

N

S

T

E

 

 

 

 

 

 

 

 

J

N

 

 

 

 

 

 

 

 

 

не используется

Текущая длина

String неограниченной длины (связанное представление с использованием указателей)

8

E J

N S

TE

J N

8-битные коды литер, упакованные по 4 в слово, и пробелы, дополняющие цепочку до фиксированной длины в 12 литер

8-битные коды литер, упакованные по 4 в слове, без дополнения пробелами

8-битные коды литер, упакованные по 2 в слово вместе с указателем на следующее слово

Рис. 3.4. Структуры памяти121для представления цепочек литер

3.2.3. Булевы значения и цепочки битов В большинстве ЯзПр в том или ином виде используются

ДВОИЧНЫЕ ДАННЫЕ: либо простые одиночные биты (true - false), либо данные типа bit string - цепочка битов. Одиночные биты обычно называются данными типа Boolean - логический ("булевский") тип данных.

Такие двоичные данные имеют очевидное представление в памяти ЭВМ - аппаратные цепочки битов (последовательность двоичных машинных разрядов). По существу одним из основных доводов в пользу включения в языки цепочки битов как типа данных, является получение прямого доступа к аппаратным цепочкам битов.

Цепочки битов имеют фиксированную или ограниченную длину, задаваемую в декларациях. Естественными операциями над цепочками битов являются поразрядные логические операции, реализуемые аппаратно: логические сумма, произведение и дополнение.

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

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

3.2.5. Указатели (адреса (чего-то), стрелки, ссылки, позиции адреса)

С данными типа "символ" тесно связаны данные типа pointer - указатель, называемый также данными типа ссылка или адрес. В ЯзПр Ада указатель называется «переменная типа ссылки».

Основное назначение указателей состоит в представлении программисту гибких средств для создания своих собственных

122

структур данных и манипулирования ими. С помощью указателей организуется связь одного элемента с другим. Введение связей с другими элементами - чрезвычайно важная идея в программировании; это ключ к представлению структур любой сложности. Указатели отличаются от символов тем, что указатели "указывают" на другие элементы данных, в то время как символы существуют сами по себе. Указатели обычно генерируются динамически и не имеют внешних представлений в виде цепочки литер. И символы, и указатели представляются в памяти как указатели. Однако, возможны висячие указатели, указывающие на уже уничтоженные структуры данных - среда размножения вирусов. В этом состоит основная опасность использования указателей.

Компьютерная программа манипулирует данными, такими как числа, символы и т.д., рассмотренными выше. В ЯзПр для идентификации и хранения данных используются такие элементы (структуры данных), как переменные. Понятие переменной – это основа программирования и с ней надо разобраться.

Переменная в ЯзПр подобна маленьким школьным доскам, на которых можно записывать некоторые числа. Число или другая информация, которую содержит переменная в данный момент, называется значением переменной. В машинном (аппаратном) представлении переменная представляет собой участок памяти. Он отводится каждой переменной (и только! переменной) в ходе компиляции для хранения ее значения. Участок находится по имени переменной, которое называется идентификатором. Правильно выбранные имена помогут сделать программу самодокументированной.

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

Значение переменной может меняться. Наиболее явный способ изменения значения переменной заключается в использовании оператора присваивания. До тех пор, пока программа не присвоит

123

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

3.3.Однородные массивы фиксированного размера (форма представления в памяти, операции обращения с ними)

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

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

124

Данные, определяемые

 

 

Данные, определяемые

программистом

 

 

 

системой

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Позитивные

Негативные: мусор,

 

 

 

висячие ссылки

 

 

 

 

 

 

 

Определяемые

 

 

 

 

 

 

Определяемые

прозрачно

 

 

 

 

скрытно

 

 

 

Доступные по частям -

 

 

Доступные целиком -

 

 

Абстрактный тип данных

 

 

структурированные

простые типы данных

 

 

типы данных

(задаются только операции)

 

 

 

 

 

Линейный однородный

Неоднородный

Массивы переменного

 

массив фиксированного

массив фиксированного

Множества

размера

размера

размера

 

 

 

С декларацией

 

 

Без декларации

 

 

 

 

 

 

 

 

 

 

 

Многомерное расширение массивов

 

 

I

 

 

III-V

 

VI

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

I. Числа, литеры, логические значения,

II. Любой реальный объект, заданный

 

 

 

 

символы, указатели.

набором операций.

II

 

 

 

 

 

 

 

 

III. Одномерные массивы (векторы),

IV. Записи.

 

многомерные массивы (векторы векторов).

V.Стеки, очереди, списки, деревья, таблицы, структуры, направленные графы

VI. Множества

Рис.3.5. Классификация структур данных

125

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

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

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

Объявление одномерного массива - вектора на АЛГОЛЕ выглядит так:

real array x[-1:1] integer array i[1:n]

integer array ЛЕНТА[1:N].

Всоответствии с концепцией умолчания, если в описании массива не указан тип, то подразумевается тип real. То есть объявление массива имеет следующий синтаксис: имя_типа (обозначе-

ние массива array) имя_массива [размер массива];.

Вдругих ЯзПр, например в С++, задание массива еще более лаконичное:

int score [59]; - то есть индикатором массива являются только квадратные скобки [ ].

При этом нельзя путать два вида использования квадратных скобок с именем массива. Если квадратные скобки используются при объявлении: int score [59]; то число в квадратных скобках указывает, сколько элементов имеет массив, то есть является объявленным размером массива. Во всех остальных случаях число в квадратных скобках указывает конкретный элемент массива. Например, score [0], score [1], …, score [58] являются нулевым, первым, …, 58-м элементами массива. Примечание. Синтаксис ссылки на элемент линейного массива в зависимости от ЯзПр: А[1], A<1>, (CARA), FIRST OF A, A.FIRST, …(!). А реализация ссылки – един-

ственная.

126

Индексы внутри квадратных скобок не обязательно должны быть целой константой. В квадратных скобках может находиться любое выражение, значением которого являются числа от 0 и до числа, на единицу меньше размера массива. Например, при выполнении следующего фрагмента программы значение 99 будет присвоено переменной score [2] и выведено на экран:

int student; student=2;

score [student]=99;

cout<<score [student]<< “ ” << score [2];

Поскольку значение переменной student=2, то, несмотря на различие в записи, переменные score[student] и score[2] являются одним и тем же элементом массива.

При использовании массивов употребляется много различных терминов, которые не всегда согласованы между собой. Ниже приведены наиболее часто употребляемые термины.

имя массива

индекс

(также называется

 

переменной массива)

 

 

score [ n

3 ]

индексная переменная или элемент массива

score [n+3] = 5 значение элемента массива (или просто элемент).

Обратите внимание на то, что термин элемент может использоваться для обозначения переменной – элемента массива, а также для обозначения значения переменной – элемента массива. Это путаница, но таких случаев в жизни очень много.

Индивидуальные элементы данных, входящие в последовательность элементов (в состав) массива могут заменяться новыми (такого же типа!) с помощью операции присваивания, но число

127

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

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

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

Удобно простое последовательное представление вектора, при котором битовые цепочки, изображающие индивидуальные элементы вектора, хранятся в памяти последовательно. При этом целые индексы вектора дают не только доступ к его индивидуальным элементам в произвольном порядке, но и позволяют удобную последовательную обработку всего вектора (например, организацией цикла "for i:=1 step 1 until N do"), используя в качестве указателя целую переменную, то есть индекс элемента массива. В начале переменная устанавливается так, что указывает на первый элемент вектора, а затем, увеличиваясь в процессе обработки, перебирает все элементы вектора.

В дескрипторе вектора должна содержаться следующая ин-

128

формация: (1) тип данных - вектор (одномерный массив), (2) число элементов или диапазон изменения индекса и (3) дескриптор для элементов (рис. 3.5, с. 72).

 

 

 

 

 

 

 

 

 

 

 

 

Вектор

 

 

 

 

 

 

 

 

 

 

Тип данных

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Нижняя граница диапазона

 

 

 

 

LB

 

 

 

изменения индекса

 

 

 

 

 

 

 

 

 

Дескрип-

 

 

 

 

 

Верхняя граница диапазо-

 

 

UB

 

 

 

 

 

 

 

 

на изменения индекса

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Тип элемента вектора

 

 

 

 

Целый

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Длина элемента

 

 

 

 

 

 

 

 

 

 

 

 

 

Е

 

 

 

 

 

 

 

 

 

 

 

 

 

Адрес, используемый для указания

 

 

 

 

 

 

 

 

местоположения вектора

 

 

 

 

 

Битовая цепочка, представляющая

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Битовая цепочка, представляющая

 

 

 

 

 

 

 

 

 

Битовая цепочка

.

.

.

Битовая цепочка, представляющая A[UB]

Рис. 3.6. Структура памяти для вектора А с полным дескриптором

Доступ. Доступ к элементам вектора управляется индексом, значение которого вычисляется во время выполнения программы. Если А - имя массива (вектора), то А[I] означает элемент массива, позиция которого определяется значением индекса I, вычисляемого во время выполнения программы.

Ситуация осложняется произвольностью нижней границы диапазона изменения индекса. Например, для вектора А из десяти элементов диапазон изменения индекса может быть определен от 0 до 9 или от -4 до 5, и тогда А[3] означает 4-й или 8-й элемент вектора.

Однородность и последовательное хранение элементов век-

129

тора позволяет использовать для вычисления адреса I-го элемента вектора простую формулу доступа:

адр А[I] = + (I - LB) E,

где I - индекс элемента, к которому осуществляется доступ; - адрес начала цепочки битов, представляющей вектор;

LB - индекс первого (нижнего) элемента вектора; Е - длина элемента вектора.

Различные элементы данных, необходимые для вычисления адреса А[I], поступают из разных источников: индекс I - это входной параметр операции доступа; - результат выполнения операции ссылки на вектора; Е и LB задаются дескриптором вектора.

В формуле доступа каждая из переменных , LB и Е фиксируется при создании вектора (то есть при компиляции, осуществляемой раньше момента вычисления) и остается неизменной. Поэтому доступ можно значительно ускорить, если вычислить член a ' = a - LBґ E во время создания вектора (то есть, записав в программу, которую оттранслируют) и хранить его в дескрипторе. Тогда формула доступа упрощается

адр А[I] = ' + I E.

3.3.1. Матрицы и однородные массивы более высокой размерности

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

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

Представление матрицы в памяти ЭВМ будет более понят-

130

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]