Работа с динамической памятью и указателями в системе Turbo Pascal. Мирецкий И.Ю - 8 стр.

UptoLike

Составители: 

P := @F; {присвоить значение указателя из F в P}
N := F(N); {вызов функции через F}
N := Func(P)(N); {вызов функции через P}
Адресный оператор @, примененный к процедурной переменной может использоваться в левой
части присваивания. Заметим также, что приведение типа в последней строке вызывает функцию через
переменную-указатель.
6. Константы с типом указатель
В дополнение к обычным константным выражениям значение типизированной
константы можно
задать, используя константное адресное выражение. Константное адресное выражение - это выражение,
которое включает получение адреса, смещения или сегмента глобальной переменной, типизированной
константы, процедуры или функции. Константное адресное выражение не может ссылаться к локальным
переменным или динамическим (в куче) переменным, поскольку их адреса нельзя вычислить во время
компиляции.
Объявление константы
типа указатель обычно использует константное адресное выражение для
указания значения. Приведем несколько примеров:
type
Direction = (Left, Right, Up, Down);
StringPrt = ^String;
NodePtr = ^Node;
Node = record
Next : NodePtr;
Symbol : StringPrt;
Value : Direction;
end;
const
S1: string[4] = 'DOWN';
S2: string[2] = 'UP';
S3: string[5] = 'RIGHT';
S4: string[4] = 'LEFT';
N1: Node = (Next: nil; Symbol:#S1; Value: Down);
N2: Node = (Next: @N1; Symbol:#S2; Value: Up);
N3: Node = (Next: @N2; Symbol:#S3; Value: Right);
N4: Node = (Next: @N3; Symbol:#S4; Value: Left); DirectionTable: NodePtr = @N4;
7. Сравнение указателей
Для сравнения операндов типа указатель совместимых типов могут использоваться операторы = и
<>. Два указателя равны только в том случае, если они ссылаются на один и тот же объект.
При сравнении указателей в Turbo Pascal сравниваются
сегменты и смещения. В соответствии со
схемой размещения сегментов процессоров 80х86 два логически различных указателя могут фактически
указывать на одну и ту же физическую ячейку памяти. Например, Ptr($0040, $0049) и Ptr($0000, $0049)
являются указателями с одинаковыми адресами. Указатели, возвращаемые стандартными процедурами
New и GetMem, всегда нормализованы (смещение находится в диапазоне от $0000 до $000F) и, таким
образом, всегда
будут сравниваться корректно. При создании указателей с помощью стандартной функции
Ptr и последующем сравнении таких указателей нужно соблюдать особую осторожность.
8. Монитор кучи
Куча имеет стековую структуру, растущую от нижних адресов памяти в сегменте кучи. Нижняя
граница кучи хранится в переменной HeapOrg, а вершина кучи, соответствующая нижней границе сво-
бодной памяти, хранится
в переменной HeapPtr. Каждый раз, когда динамическая переменная распределя-
ется в куче (через New или GetMem), монитор кучи передвигает HeapPtr вверх на размер этой перемен-
ной, ставя динамические переменные одну за другой.
       P := @F;        {присвоить значение указателя из F в P}
       N := F(N);       {вызов функции через F}
       N := Func(P)(N); {вызов функции через P}

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


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

        Объявление константы типа указатель обычно использует константное адресное выражение для
указания значения. Приведем несколько примеров:

       type
               Direction = (Left, Right, Up, Down);
               StringPrt = ^String;
               NodePtr = ^Node;
               Node = record
                    Next : NodePtr;
                    Symbol : StringPrt;
                    Value : Direction;
               end;
       const
               S1: string[4] = 'DOWN';
               S2: string[2] = 'UP';
               S3: string[5] = 'RIGHT';
               S4: string[4] = 'LEFT';
               N1: Node = (Next: nil; Symbol:#S1; Value: Down);
               N2: Node = (Next: @N1; Symbol:#S2; Value: Up);
               N3: Node = (Next: @N2; Symbol:#S3; Value: Right);
               N4: Node = (Next: @N3; Symbol:#S4; Value: Left); DirectionTable: NodePtr = @N4;

                                        7. Сравнение указателей
         Для сравнения операндов типа указатель совместимых типов могут использоваться операторы = и
<>. Два указателя равны только в том случае, если они ссылаются на один и тот же объект.
         При сравнении указателей в Turbo Pascal сравниваются сегменты и смещения. В соответствии со
схемой размещения сегментов процессоров 80х86 два логически различных указателя могут фактически
указывать на одну и ту же физическую ячейку памяти. Например, Ptr($0040, $0049) и Ptr($0000, $0049)
являются указателями с одинаковыми адресами. Указатели, возвращаемые стандартными процедурами
New и GetMem, всегда нормализованы (смещение находится в диапазоне от $0000 до $000F) и, таким
образом, всегда будут сравниваться корректно. При создании указателей с помощью стандартной функции
Ptr и последующем сравнении таких указателей нужно соблюдать особую осторожность.

                                          8. Монитор кучи
        Куча имеет стековую структуру, растущую от нижних адресов памяти в сегменте кучи. Нижняя
граница кучи хранится в переменной HeapOrg, а вершина кучи, соответствующая нижней границе сво-
бодной памяти, хранится в переменной HeapPtr. Каждый раз, когда динамическая переменная распределя-
ется в куче (через New или GetMem), монитор кучи передвигает HeapPtr вверх на размер этой перемен-
ной, ставя динамические переменные одну за другой.