Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Для работы с динамическими программными объектами в Паскале предусмотрен ссылочный тип или тип указателей. В переменной ссылочного типа хранится ссылка на программный объект (адрес объекта). Указатель состоит из сегмента и смещения. По правилам Паскаля указатели на разные типы данных имеют различные типы, причем эти типы несовместимы, т.е. указатели на разные типы данных не могут ссылаться на один объект.
Чтобы связать ссылочный тип с определенным типом данных, используется символ ^, помещаемый перед именем типа. Например, имеется тип массив:
Type
A = Array[1..100] of integer;
Тип указателя на такой объект:
Type
tA = ^A;
Переменные ссылочного типа могут определяться как статические, при этом по общим правилам объявления переменных возможна запись с явным и неявным определением ссылочного типа.
Type
A = Array[1..100] of integer; {Тип массив из 100 целых чисел}
tA = ^A; {Тип указатель на тип А}
Var
B: tA; {Указатель на тип А}
C: ^A; {Указатель на тип А}
Для получения данных, соответствующих указателю, символ "^" приводится после имени указателя. Действия с элементами массива типа А могут быть описаны через действия над указателями В и С.
B^[i]:= i; {i-му элементу массива, на который указывает В, присвоить значение i}
C^[i]:= B^[i]; {i-му элементу массива, на который указывает С, присвоить значение i-го элемента массива, на который указывает В}
После выполнения этого кода i-е элементы массивов, на которые указывают В и С, будут равны.
Указатели могут ссылаться на любой тип данных, кроме файлового.
Разберем простой пример, обратив еще раз внимание на синтаксис:
Var
P: ^integer; {Указатель на целое}
P^ - переменная целого типа, на которую ссылается Р, она может стоять как в левой, так и в правой части выражений:
P^:=16;
x:= x+P^;
Первый оператор присваивает целочисленной переменной, на которую ссылается Р, значение 16, второй прибавляет к значению переменной х значение 16, второй прибавляет к значению переменной х значение 16. Аналогично определяются и используются указатели на переменные любого типа, в том числе и определенного пользователем.
Обратите внимание, что указатель является обычной статической переменной, а переменная, на которую он указывает - динамической.
Схематически можно представить себе указатель так:
Указательная переменная Р может быть в трех состояниях.
1. Содержать адрес какой-либо переменной, память под которую уже выделена.
2. Содержать специальный пустой адрес Nil.
3. Находиться в неопределенном состоянии.
В неопределенном состоянии указатель бывает в начале работы программы до первого присваивания ему или конкретного адреса, или пустого адреса Nil, а также после освобождения области памяти на которую он указывает.
Схематически различия между состоянием Nil и неопределенным состоянием можно изобразить так:
Использование имени указателя в программе означает обращение к адресу ячейки памяти, на которую он указывает. Чтобы обратиться к содержимому ячейки, на которую указывает указатель, требуется после его идентификатора поставить символ ^. Эта операция еще называется разыменованием.
Для представления указателя на строку с завершающим нулем в Паскале имеется предопределенный тип PChar. В модуле System этот тип описывается следующим образом:
Type
PChar = ^char;
Паскаль поддерживает набор расширенных правил, позволяющих работать со строками с завершающим нулем, используя тип PChar.
Иногда связи между ссылкой и переменной не существует по смыслу задачи, в этом случае с указателем нельзя связать никакой объект, а ссылка должна быть пустой. Зарезервированное слово Nil обозначает константу со значением указателя, который ни на что не указывает. После присвоения
P:= Nil;
указатель не будет указывать ни на какой объект. Значение Nil совместимо с любым ссылочным типом.
Операции "=" и "<>" могут использоваться для сравнения операндов типа указатель. Два указателя равны только в том случае, если они ссылаются на один и тот же объект.
Присвоение значений указателю. Оператор @ с переменной. Оператор @ с параметром процедуры, переданным по значению. Оператор @ с параметром процедуры, переданным по ссылке.
Переменной-указателю можно присвоисть значение другого указателя того же типа. В языке существует универсальный тип указателя, его имя - pointer. Используя тип pointer как промежуточный, можно присвоить значение одного указателя другому и при несовпадении их типов.
Для инициализации указателей в Паскале предусмотрены специальные процедуры и функции.
Переменной-указателю можно присвоить значение с помощью процедуры new, операции @ или функции Ptr.
Процедура new отводит блок памяти в области для динамических переменных и сохраняет адрес этого блока в указателе.
Операция @ ориентирует переменную-указатель на область памяти, содержащую уже существующую переменную. Ее можно применять к статическим переменным, динамическим переменным, процедурам и функциям.
Функция Ptr ориетирует переменную-указатель на определенный адрес в памяти. Тип результата - указатель того же типа, что и Nil, т.е. он может быть назначен любой переменной-указателю.
@ - это унарный оператор. Тип значения указателя управляется через директуву компилятора $T. Если переключателшь отключен, то результатом является нетипизированный указатель, если включен, - то тип указателя соответствует типу объекта. Если оператор @ применяется к процедуре, функции или методу, то результатом всегда будет указатель типа pointer, независимо от состояния опции $T.
Оператор @ с переменной
Использование @ с обычной переменной (не параметром процедуры) несложно.
Например, можно задать декларацию
Type
A = Array [0..99] of char; {Тип массива символов}
Var
X: Array [0..49] of integer; {Массив целых чисел}
pA: ^A; {Указатель на массив символов}
Объявлены переменные двух разных типов: массива целых из 50 элементов и ссылочного на тип А (массив из 100 символов). Чтобы указатель рА указывал на массив Х, надо присвоить ему адрес Х:
рА:= @Х; {Указатель на массив целых чисел}
Теперь pA^ ссылается на массив целых, но по своей природе он указатель на массив символов, поэтому при обращении pA^[i] мы получаем содержимое отдельных байтов массива Х в символьной форме.
Дата публикования: 2015-02-03; Прочитано: 427 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!