Chiar dacă indicatorii nu sunt la fel de importanți în Delphi ca în C sau C ++, sunt un instrument atât de „de bază” încât aproape orice lucru care are legătură cu programarea trebuie să se ocupe cu indicatorii într-o anumită modă.
Din acest motiv, s-ar putea să citiți despre cum un șir sau un obiect este într-adevăr doar un indicator, sau că un gestionar de evenimente, cum ar fi OnClick, este de fapt un indicator către o procedură.
Mai simplu spus, un pointer este o variabilă care deține adresa oricărui lucru în memorie.
Pentru a concretiza această definiție, rețineți că tot ceea ce folosește o aplicație este stocat undeva în memoria computerului. Deoarece un pointer deține adresa altei variabile, se spune că indică acea variabilă.
De cele mai multe ori, indicatoarele din Delphi indică un tip specific:
var
iValue, j: întreg; pIntValue: ^ număr întreg;
începeiValue: = 2001; pIntValue: = @iValue; ... j: = pIntValue ^;
Sfârșit;
Sintaxa pentru a declara un tip de date pointer utilizează a caret (^). În codul de mai sus, iValue este o variabilă de tip întreg și pIntValue este un indicator de tip întreg. Deoarece un pointer nu este altceva decât o adresă în memorie, trebuie să îi atribuim locația (adresa) a valorii stocate în variabila integră iValue.
@ operator returnează adresa unei variabile (sau a unei funcții sau proceduri așa cum se va vedea mai jos). Echivalent cu operatorul @ este Funcție addr. Rețineți că valoarea pIntValue nu este 2001.
În acest cod de eșantion, pIntValue este un indicator întreg tastat. Un stil de programare bun este să folosiți indicatoarele tastate cât puteți. Tipul de date Pointer este un tip de indicator generic; reprezintă un indicator pentru orice date.
Rețineți că, atunci când "^" apare după o variabilă pointer, acesta face referire la pointer; adică returnează valoarea stocată la adresa de memorie deținută de indicatorul. În acest exemplu, variabila j are aceeași valoare ca iValue. S-ar putea părea că acest lucru nu are niciun scop atunci când putem atribui iValue la j, dar acest cod de cod se află în spatele majorității apelurilor către Win API.
Punctele neatribuite sunt periculoase. Deoarece pointerii ne permit să lucrăm direct cu memoria computerului, dacă încercăm (din greșeală) să scriem într-o locație protejată în memorie, am putea primi o eroare de încălcare a accesului. Acesta este motivul pentru care ar trebui să inițializăm întotdeauna un indicator către NIL.
NIL este o constantă specială care poate fi atribuită oricărui indicator. Când nil este atribuit unui indicator, indicatorul nu face referire la nimic. Delphi prezintă, de exemplu, un tablou dinamic gol sau un șir lung ca un pointer nil.
Tipurile fundamentale PAnsiChar și PWideChar reprezintă indicii la valorile AnsiChar și WideChar. PChar-ul generic reprezintă un pointer către o variabilă Char.
Acești indicatori de caractere sunt folosiți pentru a manipula șiruri cu terminare nulă. Gândiți-vă la un PChar ca la indicatorul către un șir cu terminare nulă sau la tabloul care reprezintă unul.
Când definim o înregistrare sau un alt tip de date, este o practică obișnuită să definim și un indicator către acel tip. Acest lucru face ușor să manipulați instanțele de tip fără a copia blocuri mari de memorie.
Abilitatea de a avea indicatoare pentru înregistrări (și tablouri) face mult mai ușoară configurarea structurilor de date complicate ca liste și arbori legați.
tip
pNextItem = ^ TLinkedListItem
TLinkedListItem = recordsName: String; iValue: Integer; NextItem: pNextItem;
Sfârșit;
Ideea din spatele listelor legate este să ne ofere posibilitatea de a stoca adresa următorului articol legat dintr-o listă din câmpul de înregistrare NextItem.
Indicatoarele pentru înregistrări pot fi, de asemenea, utilizate la stocarea datelor personalizate pentru fiecare articol vizualizat în arbore, de exemplu.
Un alt concept de pointer important în Delphi este indicatorii de procedură și metodă.
Pointerii care indică adresa unei proceduri sau a unei funcții sunt numiți indicatori de procedură. Indicatorii de metodă sunt similari cu indicii de procedură. Cu toate acestea, în loc să indice spre proceduri de sine stătătoare, trebuie să indice metodele de clasă.
Method pointer este un pointer care conține informații atât despre nume, cât și despre obiectul care este invocat.
Cea mai obișnuită utilizare pentru indicatoare în Delphi este interfațarea la codul C și C ++, care include accesarea API-ului Windows.
Funcțiile API API Windows folosesc o serie de tipuri de date care ar putea fi necunoscute programatorului Delphi. Majoritatea parametrilor în apelarea funcțiilor API sunt indicatoare către un tip de date. După cum s-a menționat mai sus, folosim șiruri cu terminare nulă în Delphi atunci când apelăm la funcțiile API Windows.
În multe cazuri, atunci când un apel API returnează o valoare dintr-un tampon sau pointer la o structură de date, aceste buffere și structuri de date trebuie alocate de aplicație înainte de efectuarea apelului API. Funcția API SHBrowseForFolder Windows este un exemplu.
Puterea reală a indicatoarelor vine din capacitatea de a pune deoparte memoria în timpul executării programului.
Această bucată de cod ar trebui să fie suficientă pentru a demonstra că lucrul cu indicatoare nu este atât de greu pe cât ar putea părea la început. Este folosit pentru a schimba textul (legendă) al controlului cu mânerul furnizat.
procedură GetTextFromHandle (hWND: Thandle);
var pText: PChar; // un pointer pentru char (vezi mai sus)TextLen: număr întreg;
începe
obțineți lungimea textuluiTextLen: = GetWindowTextLength (hWND);
alocare memorie
GetMem (pText, TextLen); // ia un indicator
obțineți textul controluluiGetWindowText (hWND, pText, TextLen + 1);
afiseaza textulShowMessage (String (pText))
libera memoriaFreeMem (pText);
Sfârșit;