Hoewel pointers niet zo belangrijk zijn in Delphi als in C of C ++, zijn ze zo'n "basis" tool dat bijna alles wat met programmeren te maken heeft op een of andere manier met pointers te maken heeft..
Het is om die reden dat je misschien leest hoe een string of object eigenlijk alleen maar een pointer is, of dat een event handler zoals OnClick eigenlijk een pointer is naar een procedure.
Simpel gezegd, een pointer is een variabele die het adres van alles in het geheugen bevat.
Om deze definitie te concretiseren, moet u er rekening mee houden dat alles wat een toepassing gebruikt, ergens in het geheugen van de computer is opgeslagen. Omdat een aanwijzer het adres van een andere variabele bevat, wordt gezegd dat die naar die variabele verwijst.
Meestal wijzen wijzers in Delphi op een specifiek type:
var
iValue, j: geheel getal; pIntValue: ^ geheel getal;
beginneniValue: = 2001; pIntValue: = @iValue;… j: = pIntValue ^;
einde;
De syntaxis om een gegevenstype van de aanwijzer te declareren gebruikt een caret (^). In de bovenstaande code is iValue een variabele van het type geheel getal en pIntValue is een aanwijzer van het type geheel getal. Aangezien een pointer niets meer is dan een adres in het geheugen, moeten we hieraan de locatie (adres) toewijzen van de waarde die is opgeslagen in de variabele variabel iValue.
De @ operator geeft het adres van een variabele terug (of een functie of procedure zoals hieronder te zien is). Gelijk aan de operator @ is Addr-functie. Merk op dat de waarde van pIntValue niet 2001 is.
In deze voorbeeldcode is pIntValue een getypte integer-aanwijzer. Een goede programmeerstijl is om getypte wijzers zoveel mogelijk te gebruiken. Het gegevenstype Pointer is een generiek pointertype; het vertegenwoordigt een pointer naar alle gegevens.
Merk op dat wanneer "^" wordt weergegeven na een pointervariabele, de verwijzing naar de pointer wordt verwijderd; dat wil zeggen, het retourneert de waarde die is opgeslagen op het geheugenadres van de aanwijzer. In dit voorbeeld heeft variabele j dezelfde waarde als iValue. Het lijkt erop dat dit geen doel heeft wanneer we iValue eenvoudig aan j kunnen toewijzen, maar dit stukje code ligt achter de meeste aanroepen naar Win API.
Niet-toegewezen aanwijzingen zijn gevaarlijk. Omdat pointers ons rechtstreeks met het computergeheugen laten werken, kunnen we een fout bij toegangsfout krijgen als we proberen (per ongeluk) naar een beveiligde locatie in het geheugen te schrijven. Dit is de reden dat we altijd een pointer naar NIL moeten initialiseren.
NIL is een speciale constante die aan elke aanwijzer kan worden toegewezen. Wanneer nul aan een aanwijzer is toegewezen, verwijst de aanwijzer niets. Delphi presenteert bijvoorbeeld een lege dynamische array of een lange reeks als nulwijzer.
De fundamentele typen PAnsiChar en PWideChar zijn verwijzingen naar AnsiChar- en WideChar-waarden. De generieke PChar vertegenwoordigt een pointer naar een Char-variabele.
Deze tekenaanwijzers worden gebruikt om tekenreeksen met nulpunt-beëindiging te manipuleren. Zie een PChar als een pointer naar een string met nulstand of naar de array die er een vertegenwoordigt.
Wanneer we een record of ander gegevenstype definiëren, is het gebruikelijk om ook een pointer naar dat type te definiëren. Dit maakt het gemakkelijk om instanties van het type te manipuleren zonder grote blokken geheugen te kopiëren.
De mogelijkheid om verwijzingen naar records (en arrays) te hebben, maakt het veel eenvoudiger om gecompliceerde gegevensstructuren op te zetten als gekoppelde lijsten en bomen.
type
pNextItem = ^ TLinkedListItem
TLinkedListItem = VermeldingsName: String; iValue: Integer; NextItem: pNextItem;
einde;
Het idee achter gekoppelde lijsten is om ons de mogelijkheid te geven het adres op te slaan voor het volgende gekoppelde item in een lijst in een NextItem-recordveld.
Verwijzingen naar records kunnen ook worden gebruikt bij het opslaan van aangepaste gegevens voor bijvoorbeeld elk boomweergave-item.
Een ander belangrijk pointerconcept in Delphi zijn procedure- en methode-pointers.
Aanwijzers die naar het adres van een procedure of functie verwijzen, worden procedurele verwijzingen genoemd. Methode pointers zijn vergelijkbaar met procedure pointers. In plaats van te wijzen op zelfstandige procedures, moeten ze echter wijzen op klassemethoden.
Method pointer is een pointer die informatie bevat over zowel de naam als het object dat wordt aangeroepen.
Het meest voorkomende gebruik voor pointers in Delphi is een interface met C- en C ++ -code, inclusief toegang tot de Windows API.
Windows API-functies gebruiken een aantal gegevenstypen die mogelijk onbekend zijn bij de Delphi-programmeur. De meeste parameters bij het aanroepen van API-functies zijn verwijzingen naar een bepaald gegevenstype. Zoals hierboven vermeld, gebruiken we null-beëindigde tekenreeksen in Delphi bij het aanroepen van Windows API-functies.
In veel gevallen, wanneer een API-aanroep een waarde in een buffer of aanwijzer naar een gegevensstructuur retourneert, moeten deze buffers en gegevensstructuren door de toepassing worden toegewezen voordat de API-aanroep wordt gedaan. De SHBrowseForFolder Windows API-functie is een voorbeeld.
De echte kracht van pointers komt van de mogelijkheid om geheugen opzij te zetten terwijl het programma wordt uitgevoerd.
Dit stukje code zou genoeg moeten zijn om te bewijzen dat werken met pointers niet zo moeilijk is als het op het eerste gezicht lijkt. Het wordt gebruikt om de tekst (het bijschrift) van het besturingselement te wijzigen met de meegeleverde handgreep.
procedure GetTextFromHandle (hWND: THandle);
var pText: PChar; // een pointer naar char (zie hierboven)TextLen: geheel getal;
beginnen
haal de lengte van de tekst opTextLen: = GetWindowTextLength (hWND);
geheugen toewijzen
GetMem (pText, TextLen); // neemt een wijzer
de tekst van het besturingselement ophalenGetWindowText (hWND, pText, TextLen + 1);
toon de tekstShowMessage (String (pText))
geheugen vrijmakenFreeMem (pText);
einde;