Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование - 11 - Указатели.doc
Скачиваний:
8
Добавлен:
09.03.2016
Размер:
207.36 Кб
Скачать

11.2 Адреса

Память компьютера представляет собой совокупность элементарных ячеек для хранения информации — байтов, каждый из которых имеет собственный номер или адрес, что позволяет обращаться к любому байту памяти. Адреса задаются совокупностью двух шестнадцатиразрядных слов, которые называются сегментом и смещением. Сегмент — это участок памяти, имеющий длину 64К и начинающийся с физического адреса, кратного 16 (т.е. 0, 16, 32, 48 и т.д.). Смещение указывает, сколько байт от начала сегмента необходимо пропустить, чтобы обратиться к нужному адресу.

Адресное пространство компьютера составляет 1М. Для адресации в этих пределах нужно 20 двоичных разрядов, которые получаются из двух шестнадцатиразрядных слов (сегмента и смещения) следующим образом: содержимое сегмента смещается влево на 4 разряда, освободившиеся правые разряды заполняются нулями, результат складывается с содержимым смещения.

Физический адрес = Сегмент + Смещение

11.3 Указатели

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

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

Указатели могут быть типизованными и нетипизованными.

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

Форматописания типа:

Type

имя_типа_указателя = ^базовый_тип ;

Пример:

Type

PInt = ^Integer ;

PCh = ^Char ;

В качестве базового типа указателя может быть использован идентификатор, который еще не определен, но он должен быть определен в этом же разделе описаний, в той же секции Type:

Пример:

Type

PRec = ^Rec ;

Rec = Record

. . .

end ;

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

Форматописания переменной:

1-ый способ:

Type

имя_типа_указателя = ^базовый_тип ;

Var

имя_переменной_указателя : имя_типа_указат ;

2-ой способ:

Var

имя_переменной_указателя : ^базовый_тип ;

Пример:

Var

PI1, PI2 : PInt ; { идентификаторы типов определены в предыдущих примерах }

PC1, PC2 : PCh ;

PR1, PR2 : PRec ;

или без раздела Type:

Var

PI1, PI2 : ^Integer ;

PC1, PC2 : ^Char ;

PR1, PR2 : ^Rec ;

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

Var

имя_переменной_указателя : Pointer ;

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

Пример:

Var

PP : Pointer ;

Копировать (использовать в операторах присваивания) можно только значения указателей одного и того же типа: присваивания

PI1 := PI2 ; PC1 := PC2 ; PR1 := PR2 ;

допустимы, а, например,

PI1 := PC2 ;

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

PP := PC2 ; PR1 := PP ;

Переменной-указателю можно присвоить значение (адрес) с помощью процедур New, GetMem, операции определения адреса @ или функции Ptr. Если указатель не указывает ни на какую переменную, то его значение равно Nil (пусто). Таким образом, значением переменной-указателя может быть либо Nil, либо адрес некоторой переменой (обычно, динамической).

Для обращения к переменным базового типа (т.е. к самим значениям динамических переменных) служит

имя_переменной_указателя^:

PI1^,PI2^,PC1^ и т.д.,

могут быть и такие случаи:

A^[i], A . B^, A[i] . B^ и т.п.,

PI1^ := 105 ;

PI2^ := PI1^ ;

PC1^ := S ;

WriteLn ( PI2 ) ; { вывод шестнадцатеричного адреса переменной }

WriteLn ( PI2^ ) ; { вывод значения переменной по заданному указателю }