Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LECPAS42.DOC
Скачиваний:
15
Добавлен:
20.04.2015
Размер:
662.53 Кб
Скачать

3.4. Адресный тип данных

Память компьютера можно рассматривать как последователь­ность байтов, номера которых (О, 1, 2,...) называются адресами. Каждая переменная в памяти занимает в зависимости от ее типа некоторое количество последовательных байтов. Например, пере­менные типаchar- 1 байт, а большие массивы - тысячи байтов.

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

программы. Все возможные адреса данных какого-либо типа Т образуют носитель типа адресов,который обозначается выражением ^Т.

Пример ^integerобозначает мно­жество адресов целых,

^array[1. .50]ofchar- множество адресов массивов, образованных из 50 символов,

^recordpole1,pole2 :real end- множество адресов записей из двух действитель­ных переменных.

Типом Tможет быть произвольный тип, кроме типа файла. Тип, обозначенный как ^T, называетсяадресным,а типT- базовымдля него.

Для обозначения адреса переменной xв языкеPascalопределена операция @, которая записывается как @х, Имяnilобозначает адрес 0, принадлежащий всем возможным типам ^Т. Этот адрес не может быть

адресом ни одной переменной, т.е. является "ничейным", фиктивным, который ни на что не указывает.

К однотипным адресам применимы опера­ции сравнения на равенство = и неравенство <>.

Обычно переменная хранит некоторые данные. Помимо таких переменных

с

Переменная -

указатель

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

Такие переменные называются указателями. Это можно изобразить графически

Обычная

переменная

Переменная - указатель

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

Имя :^T

Где Имя – имя переменной указателя;

T– тип переменной на которую указывает указатель

В языке Pascalупотребляютсятипизированные указатели - переменные типа ^Т.Они еще называютсяуказателями типа Т.Им можно присваивать адреса переменных только типа Т илиnil. Когда адрес переменной присваивается указателю, то говорят, что онустанавливается на переменную.

Пример 3.16.Описание переменных - указателей.

p:^real;

s:^integer;

Переменная типа p– это указатель на переменную типаreal,s– на переменную типаinteger.

В начале работы программы переменная – указатель ни на что не указывает, т.е. указатель пустой и имеет адрес 0 (NIL).

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

Пример Операция присвоения указателю q2 значения указателяq1

q2:=q1;

q2 иq1 указывают на одну переменную.

К указателям применима операция разыменова­ниясо знаком "^".

Если р - указатель типа ^T, то выражение р^ задает переменную типа Т,на которую установлен р.

Если указатель р установлен на переменную х, то выражения х и р^ эквива­лентны.

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

в результате выполнения инструкции

s^:=45;

значение переменной kбудет равно 45.

Пример 3.18.Применение операции разыменования для задания значений элементам массива. при

type

mas = array [1..10] of integer;

var

x : mas;

p : ^mas;

В примере 17.1 элемент массива с индексом iможно задать как х[i], так и как р^[i], т.е. вместо присваивания х[1]:=4 можно написать р^ [1]: =4 или вместо х[2] :=sqr(х[1]) - присваивание р^[2 ]: =sqr(р^ [1]).

Примечание

Разыменование никуда не установленного указателя или указателя

со значением nil приводит к аварийному завершению программы.

В большинстве компьютеров адреса занимают 4 байта и количество адресов памяти в связи с этим будет равно 232.

Для хранения адреса требуются два слова (4 байта), одно из них определяет сегмент, второе - смещение.

Основным применением указателей является работа со свобод­ной памятью.Память процесса выполнения программы делится на несколько частей:

память для операторов программы;

статическая память - для глобальных и статических перемен­ных программы и модулей;

автоматическая память, или программный стек - для локаль­ных переменных во время выполнения вызовов подпрограмм;

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

динамических переменных называется управлением кучи.

Указатель может быть как автоматической или статической переменной , так и динамической.

Операция @. Cпомощью операции @ можно создать указатель на переменную (определить адрес). В табл показаны операнд и типы результата.

Таблица 6.9 Операция создания указателя

Операции

действие

Тип операнда

Тип результата

@

Получение указателя

Ссылка на переменную, процедуру или идентификатор функции

Указатель

Операция @ является унарной операцией, в качестве операнда которой используется ссылка на переменную, процедура или идентификатор функции

и операнду возвращается указатель. Тип этого значения является таким же, как тип указателя nil, и, таким образом, его можно присвоить любому указателю-переменной.

Примечание:

При использовании операции @ с процедурными переменными

используются специальные правила.

Использование операции @ для переменной.Использование операции @ для обычной переменной (не параметра) не вызывает никаких сложностей.

Пример Введем описания:

type

TChar = array[0..1] of char;

var

int: integer;

TCharPtr: ^TChar;

тогда оператор:

TCharPtr := @Int;

приводит к тому, что TCharPtr для получения ссылки на TCharr^ становится повторной интерпретацией значения Int, как если бы оно было символьным массивом array[0..1].

Использование операции @ для параметра-значения. Использование операции @ для формального параметра-значения приводит к тому, что будет построен указатель, указывающий на ячейку стека, в которой содержится фактическое значение параметра. Предположим, что F является формальным параметром-значением процедуры, а FРtr^ является указателем-переменной. Если в процедуре выполняется операция:

FPtr := @F;

то FРtr^ будет ссылкой на значение F. Однако, FРtr^ не указывает на сам параметр F, поскольку он указывает на значение F, которое было взято из F и сохранено в стеке.

Использование операции @ для параметра-переменной.Применение операции @ к параметру-переменной приведет к тому, что будет сформирован указатель на фактический параметр (указатель берется из

стека). Предположим, что Оn - параметр-переменная процедуры, Tw - переменная, передаваемая в процедуру в качестве фактического параметра- переменной Оnе, а ОnеPtr является указателем на переменную. Если в процедуре выполняется оператор:

OnePtr := @One;

то ОnеРtr является указателем на переменную Twо, а ОnеPtr^ - ссылка на саму переменную Twо.

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

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

Приоритет операций. Приоритет определяет очередность выполнения операций. Значения приоритетов указаны в табл.

Операция

Приоритет

Вид операции

@, NOT

*,/,DIV,MOD,AND

+,-,OR,XOR

=,<>,<,><=,>=,IN

Первый (высший)

Второй

Третий

Четвертый(низший)

Унарная операция

Операции типа умножения

Операции типа сложения

Операции отношения

Приоритет операций определяется следующими правилами:

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

2. Операция, находящаяся между двумя операциями с разными приоритетами, связывается с той операцией, которая находится слева.

3. Выражение в скобках вычисляется как отдельный операнд.

4. Операции с равным приоритетом выполняются слева направо.

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