Понимание и использование указателей в Delphi

Хотя указатели не так важны в Delphi как они есть в C или C ++они настолько "основной" инструмент, что почти все, что связано с программирование должен иметь дело с указателями в некотором роде.

По этой причине вы можете прочитать о том, что строка или объект на самом деле является просто указателем, или что обработчик события, такой как OnClick, на самом деле является указателем на процедуру.

Указатель на тип данных

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

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

В большинстве случаев указатели в Delphi указывают на определенный тип:

вар
iValue, j: целое число; pIntValue: ^ целое число;
начать
iValue: = 2001; pIntValue: = @iValue;... j: = pIntValue ^;
конец
;

синтаксис чтобы объявить тип данных указателя использует каретка (^). В приведенном выше коде iValue является переменной целочисленного типа, а pIntValue является указателем целочисленного типа. Поскольку указатель является не чем иным, как адресом в памяти, мы должны присвоить ему местоположение (адрес) значения, хранящегося в целочисленной переменной iValue.

instagram viewer

@ оператор возвращает адрес переменной (или функции или процедуры, как будет показано ниже). Эквивалент оператора @ Функция Addr. Обратите внимание, что значение pIntValue не 2001.

В этом примере кода pIntValue является типизированным целочисленным указателем. Хороший стиль программирования - использовать как можно больше типизированных указателей. Тип данных Pointer является общим типом указателя; он представляет указатель на любые данные.

Обратите внимание, что когда «^» появляется после переменной указателя, она отменяет ссылку на указатель; то есть возвращает значение, хранящееся по адресу памяти, удерживаемому указателем. В этом примере переменная j имеет то же значение, что и iValue. Может показаться, что это не имеет смысла, когда мы можем просто назначить iValue для j, но этот фрагмент кода лежит в основе большинства вызовов Win API.

NILing Указатели

Неназначенные указатели опасны. Поскольку указатели позволяют нам работать непосредственно с памятью компьютера, если мы попытаемся (по ошибке) записать в защищенное место в памяти, мы можем получить ошибку нарушения доступа. По этой причине мы всегда должны инициализировать указатель на NIL.

NIL - это специальная константа, которая может быть назначена любому указателю. Когда nil назначается указателю, указатель не ссылается ни на что. Delphi представляет, например, пустой динамический массив или длинная строка в виде нулевого указателя.

Указатели персонажей

Фундаментальные типы PAnsiChar и PWideChar представляют указатели на значения AnsiChar и WideChar. Универсальный PChar представляет указатель на переменную Char.

Эти символьные указатели используются для манипулирования нулевым символом в конце строки. Думайте о PChar как о указателе на завершенную нулем строку или на массив, который представляет один.

Указатели на записи

Когда мы определяем запись или другой тип данных, обычной практикой также является определение указателя на этот тип. Это позволяет легко манипулировать экземплярами типа без копирования больших блоков памяти.

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

тип
pNextItem = ^ TLinkedListItem
TLinkedListItem = записьsName: String; iValue: целое число; NextItem: pNextItem;
конец
;

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

Указатели на записи также могут использоваться, например, при хранении пользовательских данных для каждого элемента дерева.

Процедурные и методические указатели

Другая важная концепция указателя в Delphi - это указатели на процедуры и методы.

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

Указатель метода - это указатель, который содержит информацию об имени и вызываемом объекте.

Указатели и Windows API

Наиболее распространенное использование указателей в Delphi - это взаимодействие с кодом C и C ++, что включает доступ к API Windows.

Windows Функции API используют ряд типов данных, которые могут быть незнакомы программисту Delphi. Большинство параметров в вызывающих функциях API являются указателями на некоторый тип данных. Как указано выше, мы используем строки с нулевым символом в конце в Delphi при вызове функций Windows API.

Во многих случаях, когда вызов API возвращает значение в буфере или указатель на структуру данных, эти буферы и структуры данных должны быть выделены приложением до выполнения вызова API. Функция Windows API SHBrowseForFolder является одним из примеров.

Распределение указателя и памяти

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

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

процедура GetTextFromHandle (hWND: THandle);
вар
pText: PChar; // указатель на символ (см. выше)TextLen: целое число;
начать

{получить длину текста}
TextLen: = GetWindowTextLength (hWND);
{выделить память}

GetMem (pText, TextLen); // берет указатель
{получить текст элемента управления}
GetWindowText (hWND, pText, TextLen + 1);
{отобразить текст}
ShowMessage (String (pText))
{освободить память}
FreeMem (pText);
конец
;
instagram story viewer