Unë i konsideroj deklaratat e caktimeve dhe ndryshoret e tipit pointer si ndër "thesaret më të vlefshme" të shkencës kompjuterike.

Donald Knuth, Programim i Strukturuar, me shkoni te Deklaratat

shkencën kompjuterike, një pointer është një objekt në shumë gjuhë programimi që ruan një adresë të kujtesës . Kjo mund të jetë ajo e një vlere tjetër të vendosur në kujtesën e kompjuterit, ose në disa raste, ajo e harduerit kompjuterik të hartuar me kujtesë . Një pointer referon një vendndodhje në memorie dhe marrja e vlerës së ruajtur në atë vendndodhje njihet si dereferencimi i treguesit. Si një analogji, një numër faqeje në indeksin e një libri mund të konsiderohet si një tregues për në faqen përkatëse; dereferencimi i një treguesi të tillë do të bëhej duke rrëshqitur në faqen me numrin e dhënë të faqes dhe duke lexuar tekstin që gjendet në atë faqe. Formati dhe përmbajtja aktuale e një ndryshoreje treguese varet nga arkitektura bazë e kompjuterit .

Një pointer a që tregon adresën e kujtesës të lidhur me një ndryshore b, dmth. a përmban adresën 1008 në kujtesë, atë të ndryshores b . Në këtë diagram, arkitektura kompjuterike përdor të njëjtën hapësirë adresash dhe primitivë të të dhënave si për treguesit ashtu edhe për ato jo-pointerët; kjo nevojë nuk duhet të jetë rasti.

Përdorimi i pointerave përmirëson ndjeshëm performancën për operacionet e përsëritura, si bredhja e strukturave të përsëritura të të dhënave (p.sh. vargjet, tabelat e kërkimit, tabelat e kontrollit dhe strukturat pemë ). Në veçanti, shpesh është shumë më e lirë në kohë dhe hapësirë për të kopjuar dhe dereferencuar treguesit sesa për të kopjuar dhe aksesuar të dhënat në të cilat tregojnë treguesit.

Një tregues është një zbatim i thjeshtë, më konkret i llojit të të dhënave më abstrakte, të referencës . Disa gjuhë, veçanërisht gjuhët e nivelit të ulët, mbështesin një lloj pointeri, megjithëse disa kanë më shumë kufizime në përdorimin e tyre se të tjerat. Ndërsa fjala "pointer" është përdorur për t'iu referuar referencave në përgjithësi, ai zbatohet më mirë për strukturat e të dhënave, ndërfaqja e të cilave lejon në mënyrë eksplicite që pointeri të manipulohet (aritmetikisht nëpërmjet  ) si një adresë memorie, në krahasim me një cookie magjike ose aftësi që nuk e lejon këtë. [ citim i nevojshëm ] Për shkak se pointerat lejojnë qasje të mbrojtur dhe të pambrojtur në adresat e memories, ka rreziqe që lidhen me përdorimin e tyre, veçanërisht në rastin e fundit. Pointerat primitivë shpesh ruhen në një format të ngjashëm me një numër të plotë ; megjithatë, përpjekja për të dereferencuar ose "kërkuar" një tregues të tillë, vlera e të cilit nuk është një adresë e vlefshme memorie, mund të shkaktojë që një program të përplaset (ose të përmbajë të dhëna të pavlefshme). Për të zbutur këtë problem të mundshëm, për sa i përket sigurisë së tipit, pointerat konsiderohen si një lloj i veçantë i parametrizuar nga lloji i të dhënave ku ata shënojnë, edhe nëse paraqitja bazë është një numër i plotë. Mund të merren gjithashtu masa të tjera (si verifikimi dhe kontrolli i kufijve ), për të verifikuar që ndryshorja e treguesit përmban një vlerë që është njëkohësisht një adresë e vlefshme memorie dhe brenda intervalit numerik që procesori është në gjendje të adresojë.

Pointerat në C

Redakto

Sintaksa bazë për të përcaktuar një pointer është: [1]

int *ptr;

Kjo deklaron ptr si identifikues të një objekti të llojit të mëposhtëm:

  • pointer që shënon një objekt të tipit int

Për shkak se gjuha C nuk specifikon një nistim të nënkuptuar për objektet me kohëzgjatje automatike të ruajtjes, [2] shpesh duhet pasur kujdes për të siguruar që adresa në të cilën shënon ptr është e vlefshme; kjo është arsyeja pse nganjëherë sugjerohet që një pointer të nistohet në mënyrë eksplicite në vlerën e pointer null, i cili tradicionalisht specifikohet në C me makro të standardizuar NULL : [3]

int *ptr = NULL;

Dereferencimi i një treguesi null në C prodhon sjellje të papërcaktuar, [4] e cila mund të jetë katastrofike. Megjithatë, shumica e zbatimeve thjesht ndaloni ekzekutimin e programit në fjalë, zakonisht me një gabim segmentimi . Në çdo rast, pasi të jetë deklaruar një pointer, hapi tjetër logjik është që ai të shënojë diçka:

int a = 5;
int *ptr = NULL;

ptr = &a;

Kjo cakton vlerën e adresës së aptr . Për shembull, nëse a ruhet në vendndodhjen e memories 0x8130, atëherë vlera e ptr do të jetë 0x8130 pas caktimit. Për të mosreferencuar pointerin, përdoret përsëri një yll:

*ptr = 8;
  1. ^ ISO/IEC 9899, clause 6.7.5.1, paragraph 1.
  2. ^ ISO/IEC 9899, clause 6.7.8, paragraph 10.
  3. ^ ISO/IEC 9899, clause 7.17, paragraph 3: NULL...
  4. ^ ISO/IEC 9899, clause 6.5.3.2, paragraph 4, footnote 87: If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined...