Лекция №10.1: Адреса и указатели. Списочные структуры данных

страницы: 1 2 3 4

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

Содержание

Статически выделяемая память

Для того, чтобы лучше понять специфику динамически выделяемой памяти, рассмотрим сначала её «антипод» — память, распределяемую статически.

Такое выделение памяти используется всякий раз при объявлении «обычных» переменных в разделе var. Каждая переменная обладает двумя атрибутами: именем и описанием.

var a : Integer;

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

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

Адреса

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

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

Лучшая иллюстрация страничной организации памяти компьютера — это страничная организация любой печатной книги. Для того, чтобы найти нужную строчку, нет необходимости задавать её номер, считая от начала текста. Вместо этого можно задать сначала номер страницы (= сегмент) и только затем номер строки, считая от начала этой страницы (= смещение).

Для обращения к статически заданной переменной можно использовать как её имя, объявленное в разделе var, так и её физический адрес.

Например, «адрес» одной и той же географической точки можно записать по-разному: «49°47' северной широты и 86°36' восточной долготы» или просто «вершина пика Белуха Восточная1».

Указатели

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

Описание указателей

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

var <имя_указателя>: ^<тип_адресуемой_переменной>;

Например:

var p : ^Integer;
    q : ^Real;
    s : ^array[1 .. 10] of Byte;

Кроме того, существуют универсальные нетипизированные указатели, которые могут хранить адрес переменной любого типа:

var <имя_указателя> : Pointer;

Операции с указателями

Определение адреса

Физический адрес любой переменной можно узнать при помощи стандартной функции Addr(<имя_переменной>) : <указатель> или унарной операции @<имя_переменной>.

В зависимости от значения директивы компилятора {$T}, результатом операции @ будет либо типизированный указатель (если установлено {$T+}), тип которого будет определен в соответствии с типом использованной переменной, либо нетипизированный указатель Pointer (если установлено {$T-}).

Результат функции Addr() совместим с указателями любых типов:

p := Addr(x); {x : Real; p : ^Byte}

Разыменование

Для того, чтобы воспользоваться значением, хранящимся по некоторому адресу, необходимо его оттуда «извлечь». Унарная операция ^ называется разыменованием и записывается по следующему шаблону:

 <имя_указателя>^

Результатом операции ^ является значение, хранящееся по указанному адресу. Тип этого значения будет определяться типом (типизированного) указателя. К нетипизированным указателям операцию разыменования применять нельзя.

Из–за вольностей, допускаемых процедурой Addr(), при разыменовании порой могут возникнуть забавные ситуации. Например, в результате выполнения такой вот программы:

const a : array[1 .. 3] of Char ='ААА'; {код(А)=128 или 10000000}
var p : ^Word;
begin
  p := Addr(a);
 WriteLn(p^)
end

на экран будет выведено 32896, что в двоичной системе счисления выглядит как 10000000.10000000 (точкой помечена граница двух байтов). Иными словами, коды двух первых букв оказались слитыми в значение типа Word.

Замечание: Операции @ и ^ являются взаимно обратными, то есть для любой переменной a и для любого типизированного указателя p верны следующие равенства:

@(p^)= p и (@a)^ = a

страницы: 1 2 3 4

Примечания

  1. ^ Высочайшая вершина азиатской части России (4506 м), находится на Алтае.
Код для вставки: :: :: :: ::
Поделиться: // //