A mutatók megértése és használata a Delphiben

Annak ellenére, hogy a mutatók nem olyan fontosak a Delphi a C vagy a C helyzetben vannak C ++, olyan "alapvető" eszköz, amelyhez szinte bármi köze van programozás valamilyen módon foglalkoznia kell a mutatókkal.

Ez az oka annak, hogy elolvashatja arról, hogy egy karakterlánc vagy objektum valójában csak egy mutató, vagy hogy egy eseménykezelő, például az OnClick, valójában egy eljárás mutatója.

Mutató az adattípushoz

Egyszerűen fogalmazva: a mutató olyan változó, amely bármi címét tárolja a memóriában.

A meghatározás pontosítása érdekében ne feledje, hogy egy alkalmazás által használt minden tárolódik a számítógép memóriájában. Mivel a mutató egy másik változó címét tárolja, azt kell mondani, hogy erre a változóra mutat.

A Delphi-ben található mutatók általában egy adott típusra mutatnak:

var
iValue, j: egész szám; pIntValue: ^ egész szám;
kezdődik
iValue: = 2001; pIntValue: = @iValue;... j: = pIntValue ^;
vég
;

Az szintaxis egy mutató adattípusának deklarálásához használja a caret (^). A fenti kódban az iValue egy egész típusú változó, a pIntValue pedig egy egész típusú mutató. Mivel a mutató nem más, mint egy cím a memóriában, hozzá kell rendelnünk az iValue egész számváltozóban tárolt érték helyét (címét).

instagram viewer

Az @ operátor visszaadja a változó címét (vagy egy függvényt vagy eljárást, amint az alább látható). A @ operátorral egyenértékű Addr funkció. Vegye figyelembe, hogy a pIntValue értéke nem 2001.

Ebben a példakódban a pIntValue egy beírt egész szám mutató. A jó programozási stílus az, hogy amennyire csak tudsz, gépelt mutatókat használj. A Pointer adattípus egy általános mutató típus; bármilyen adat mutatója.

Vegye figyelembe, hogy amikor a "^" megjelenik egy mutatóváltozó után, akkor a mutatóra hivatkozást levon; vagyis visszaadja a mutató által tárolt memória címen tárolt értéket. Ebben a példában a j változó értéke megegyezik az iValue értékével. Úgy tűnik, hogy ennek nincs értelme, ha egyszerűen csak hozzárendelhetjük az iValue értéket j-hez, de ez a kóddarab a legtöbb Win API-hívás mögött rejlik.

NILING mutatók

A nem kiosztott mutatók veszélyesek. Mivel a mutatók lehetővé teszik, hogy közvetlenül a számítógép memóriájával dolgozzunk, ha (véletlenül) megpróbálunk védett helyre írni a memóriában, hozzáférés-megsértési hibát kaphatunk. Ez az oka annak, hogy mindig indítsuk a mutatót NIL-re.

A NIL egy speciális állandó, amelyet bármilyen mutatóhoz hozzá lehet rendelni. Ha a mutatóhoz null értéket rendelnek, akkor a mutató nem utal semmire. Delphi például egy üreset mutat be dinamikus tömb vagy egy hosszú húr, mint nulla mutató.

Karaktermutatók

A PAnsiChar és PWideChar alaptípusok mutatják az AnsiChar és a WideChar értékeket. Az általános PChar egy Char változó mutatóját jelöli.

Ezeket a karaktermutatókat a null-terminált manipulálására használják húrok. Gondolj egy PChar-ra, mint mutatóra egy null-végû karakterláncra vagy a tömbre, amely azt képviseli.

Mutatók a lemezekhez

Ha meghatározunk egy rekordot vagy más adattípust, az a gyakorlat, hogy meghatározunk egy mutatót ehhez a típushoz. Ez megkönnyíti a típusú példányok manipulálását nagy memóriatömbök másolása nélkül.

Az a képesség, hogy mutatókkal rendelkezik a rekordokra (és tömbökre), megkönnyíti a bonyolult adatstruktúrák összekapcsolását összekapcsolt listák és fákként.

típus
pNextItem = ^ TLinkedListItem
TLinkedListItem = rekordsName: String; iValue: egész szám; NextItem: pNextItem;
vég
;

A kapcsolt listák mögött az a lehetőség van, hogy lehetőséget adjunk arra, hogy a NextItem rekordmezőben a következő kapcsolt elem címét tároljuk egy listában.

A rekordokra mutató mutatók akkor is használhatók, amikor például minden fa nézethez egyedi adatokat tárolnak.

Eljárási és módszertani mutatók

A Delphi-ben egy másik fontos mutatókoncepció az eljárás- és módszermutatók.

Azokat az mutatókat, amelyek egy eljárás vagy funkció címére mutatnak, eljárási mutatóknak nevezzük. A módszer mutatók hasonlóak az eljárás mutatókhoz. Ahelyett, hogy önálló eljárásokra mutatnának, az osztálymódszerekre kell mutatniuk.

A módszermutató egy olyan mutató, amely információkat tartalmaz mind a meghívott névről, mind az objektumról.

Mutatók és a Windows API

A Delphi-ben a mutatók leggyakoribb használata a C és a C ++ kód illesztése, amely magában foglalja a Windows API elérését.

ablakok Az API funkciók számos olyan adattípust használnak, amelyek ismeretlenek lehetnek a Delphi programozó számára. Az API függvények meghívásának paraméterei a legtöbb adatot mutatnak. Mint fentebb említettük, null-végű karakterláncokat használunk a Delphi-ben, amikor a Windows API-funkciókat hívjuk meg.

Sok esetben, amikor egy API-hívás egy pufferben vagy mutatóban ad vissza egy értéket az adatszerkezethez, ezeket az puffereket és az adatstruktúrákat az alkalmazásnak el kell osztania az API-hívás kezdete előtt. Az SHBrowseForFolder Windows API funkció egy példa.

Mutató és memória allokáció

A mutatók valódi ereje abból adódik, hogy a program végrehajtása közben memóriát lehet félretenni.

Ennek a kóddarabnak elegendőnek kell lennie annak bizonyításához, hogy a mutatókkal való munka nem olyan nehéz, mint az elsőre tűnhet. A vezérlő szövegének (feliratozásának) megváltoztatására szolgál a mellékelt fogantyúval.

eljárás GetTextFromHandle (hWND: THandle);
var
pText: PChar; // mutató a char-hoz (lásd fent)TextLen: egész szám;
kezdődik

{a szöveg hosszát kapja}
TextLen: = GetWindowTextLength (hWND);
{alocate memória}

GetMem (pText, TextLen); // egy mutatót vesz
{kapja meg a vezérlő szövegét}
GetWindowText (hWND, pText, TextLen + 1);
{a szöveg megjelenítése}
ShowMessage (karakterlánc (pText))
{szabadítsd fel a memóriát}
FreeMem (pText);
vég
;