Операции с указателями
Определение адреса Физический адрес любой переменной можно узнать при помощи стандартной функции addr(<имя_переменной>):<указатель> или унарной операции @<имя_переменной>. В зависимости от значения директивы компилятора {$T}, результатом операции @ будет либо типизированный указатель (если установлено {$T+}), тип которого будет определен в соответствии с типом использованной переменной, либо нетипизированный указатель pointer (если установлено {$T-}). Результат функции addr() совместим с указателями любых типов: p:= addr(x); {x: real; p: ^byte) Разыменование Для того чтобы воспользоваться значением, хранящимся по некоторому адресу, необходимо его оттуда "извлечь". Унарная операция ^ называется разыменованием и записывается по следующему шаблону: <имя_указателя>^ Результатом операции ^ является значение, хранящееся по указанному адресу. Тип этого значения будет определяться типом (типизированного) указателя. К нетипизированным указателям операцию разыменования применять нельзя. Из-за вольностей, допускаемых процедурой addr(), при разыменовании порой могут возникнуть забавные ситуации. Например, в результате выполнения такой вот программы: const a: array[1..3] of char ='ААА'; {код(А)=128 или 01000000} var p: ^word; begin p:= addr(a); writeln(p^) end. на экран будет выведено 32896, что в двоичной системе счисления выглядит как 01000000.01000000 (точкой помечена граница двух байтов). Иными словами, коды двух первых букв оказались слитыми в значение типа word. Замечание: Операции @ и ^ являются взаимно обратными, то есть для любой переменной a и для любого типизированного указателя p верны следующие равенства: @(p^)= p и (@a)^ = a Присваивания Для указателей действуют гораздо более жесткие правила совместимости типов, чем для обычных переменных. В операции присваивания могут фигурировать только указатели, адресующие переменные одинаковых типов данных. Нельзя, скажем, записать
Обойти эти ограничения позволяет универсальность нетипизированного указателя pointer, совместимого с указателями любых типов: {p:= ^integer; q: ^byte; t: pointer}t:= q;p:= t;У указателей также существует свой "ноль", который означает, что указатель не указывает никуда: p:= nil;Замечание: Если указатель не хранит конкретного адреса (его значение не определено), то это вовсе не означает, что он никуда не указывает. Скорее всего, он все-таки указывает, но только в какую-нибудь неожиданную (хорошо, если не системную) область памяти. Сравнения Для указателей определены две операции сравнения: = и <>. Две переменные, описанные как указатели на один и тот же тип данных, считаются совпадающими, если они указывают на одну и ту же область памяти. Для разнотипных указателей сравнения невозможны: попытка записать if p = q then writeln('yes'); {p: ^byte; q: ^integer}вызовет ошибку уже на этапе компиляции. Однако сравнивать типизированный и нетипизированный указатели можно.
Читайте также: I. Исходя из сущности операции. Воспользуйтесь поиском по сайту: ©2015 - 2025 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|