Разбиране и използване на указатели в Delphi

click fraud protection

Въпреки че показалците не са толкова важни за Delphi както са в С или C ++, те са такъв "основен" инструмент, с който има почти нищо общо програмиране трябва да се справят с указатели по някакъв начин.

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

Указател към тип данни

Просто казано, показалец е променлива, която държи адреса на нещо в паметта.

За да конкретизираме това определение, имайте предвид, че всичко, използвано от приложение, се съхранява някъде в паметта на компютъра. Тъй като показалец съдържа адреса на друга променлива, се казва, че сочи към тази променлива.

През повечето време указателите в Delphi сочат към конкретен тип:

Var
iValue, j: цяло число; pIntValue: ^ цяло число;
започвам
iValue: = 2001; pIntValue: = @iValue;... j: = pIntValue ^;
край
;

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

instagram viewer

Най- @ оператор връща адреса на променлива (или функция или процедура, както ще видите по-долу). Еквивалент на @ оператора е Addr функция. Имайте предвид, че стойността на pIntValue не е 2001 година.

В този примерен код, pIntValue е въведен цяло число. Добрият стил на програмиране е да използвате въведени указатели, колкото можете. Типът данни на показалеца е общ тип показалец; тя представлява указател към всякакви данни.

Обърнете внимание, че когато "^" се появява след променлива на указател, той де-препраща към показалеца; това означава, че връща стойността, съхранена на адреса на паметта, държан от показалеца. В този пример променлива j има същата стойност като iValue. Може да изглежда, че това няма никаква цел, когато можем просто да присвоим iValue на j, но това парче код се крие зад повечето обаждания към Win API.

NILing указатели

Неназначените указатели са опасни. Тъй като указателите ни позволяват да работим директно с паметта на компютъра, ако се опитаме (по погрешка) да запишем на защитено място в паметта, бихме могли да получим грешка при нарушаване на достъпа. Това е причината винаги да инициализираме указател към 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 ++ код, който включва достъп до Windows API.

Windows Функциите на API използват редица типове данни, които може да не са познати на програмиста на Delphi. Повечето от параметрите при извикване на API функции са указатели към някакъв тип данни. Както беше посочено по-горе, ние използваме нулево завършени низове в Delphi, когато извикваме функциите на API на Windows.

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

Разпределение на показалец и памет

Истинската сила на указателите идва от възможността да се отделя памет, докато програмата се изпълнява.

Това парче код трябва да е достатъчно, за да докаже, че работата с указатели не е толкова трудна, колкото може да изглежда в началото. Използва се за промяна на текста (надпис) на контрола с предоставената дръжка.

процедура GetTextFromHandle (hWND: THandle);
Var
pText: PChar; // указател към char (виж по-горе)TextLen: цяло число;
започвам

{получете дължината на текста}
TextLen: = GetWindowTextLength (hWND);
{alocate memory}

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