Язык:
Русский
English
Указательные типы
Переменная указательного типа содержит адрес в памяти динамической переменной определенного типа.
Вы можете присвоить значение указательной переменной с помощью:
■ процедур New или GetMem
■ оператора @ или функции Addr
■ функции Ptr
Зарезервированное слово nil обозначает указатель, который не указывает никуда.
Указатель
Предопределённый тип Pointer обозначает нетипизированный указатель (указатель, который не указывает на какой-либо определённый тип).
PChar
Предопределённый тип PChar обозначает указатель на строку с завершающим нулём.
Type PChar = ^Char;
Borland Pascal для Windows поддерживает набор расширенных правил синтаксиса (управляемых с помощью директивы компилятора $X) для облегчения обработки строк типа PChar.
Пример
{ Объявление указательных типов }
Type BytePtr = ^Byte;
WordPtr = ^Word;
IdentPtr = ^IdentRec;
IdentRec = Record
Ident : String[15];
RefCount : Word;
Next : IdentPtr;
End;
Ада
Указательные типы называются типами доступа (access types). Типы доступа отличаются от указательных типов в других языках. Прежде всего, нужно отметить, что типы доступа, ссылающиеся на один и тот же тип, не обязательно эквивалентны. Механизмы языка Ада направлены на предотвращение образования "висячих" указателей. "Висячий" указатель (dangling pointer) - это указатель на данные, которые перестали быть доступными. Например, если взять указатель на локальную переменную процедуры, а затем выйти из неё, переменная перестаёт существовать, а указатель остаётся. Причём, если обращаться к данным по этому указателю, то поначалу может не возникать никаких проблем. Скрытые ошибки самые неприятные. Скрытая ошибка может остаться незамеченной и проявиться намного позже, когда из-за изменений в программе данные вдруг начнут затираться. Типы доступа в языке Ада - это компромисс между удобством и безопасностью. У типов доступа есть некоторая область достижимости, и переменной типа доступа нельзя присвоить указатель на менее достижимый объект. Например, переменной глобального типа доступа нельзя присвоить указатель на локальную переменную:
procedure Evil_Ptr_Demo is
type Global_Int_Ptr is access all Integer;
Global_Var : Global_Int_Ptr;
procedure Evil_Proc is
Local_Var : aliased Integer; -- без aliased нельзя взять указатель
begin
Global_Var := Local_Var'Access; -- эта строчка не скомпилируется
end Evil_Proc;
begin
Evil_Proc;
end Evil_Ptr_Demo;
Если же по каким-то причинам нужно обойти механизмы безопасности, замените 'Access на 'Unchecked_Access, и компилятор разрешит присваивание. Безопасность в Аде - это как бортик. Нельзя соскользнуть, но можно перешагнуть. На свой страх и риск, конечно :)
Тип доступа на недоопределённый тип помимо адреса содержит всю информацию, необходимую для доопределения. Например, указатель на недоопределённый массив физически содержит в себе границы массива.
Не указывающий никуда указатель обозначается зарезервированным словом null.
Аналогом Pointer в языке Ада является System.Address. Разница в том, что из адреса нельзя сделать указатель, не воспользовавшись пакетом System.Address_To_Access_Conversions. Язык Ада устроен так, что программист, имея в распоряжении все возможности системного языка программирования, не может невзначай применять их где попало. Каждый небезопасный трюк требует подключения системных пакетов и, возможно, их инстанциации. В то же время, если написание какого-то модуля требует активно использовать низкоуровневые возможности языка, не составит проблемы один раз подключить и много раз использовать.
Новые объекты создаются оператором new. У этого оператора нет парного оператора delete. Для уничтожения нужно использовать Ada.Unchecked_Deallocation. Префикс Unchecked намекает на возможное образование висячих указателей.
Как правило, использование контейнеров позволяет обойтись без указателей. Например, при написании инструментария для руссификации этого файла справки указатели вообще не использовались, за исключением нисходящих замыканий.
Типы доступа в языке Ада могут быть константными (constant) и/или ненулевыми (not null). Используя константный указатель, объект нельзя изменить. Ненулевой тип доступа не включает в себя значение null.
Для обработки строк с завершающим нулём предусмотрен специальный пакет Interfaces.C.Strings.