Informatika2-2012/Eloadas04

A MathWikiből
A lap korábbi változatát látod, amilyen Ador (vitalap | szerkesztései) 2012. február 28., 23:51-kor történt szerkesztése után volt.
(eltér) ←Régebbi változat | Aktuális változat (eltér) | Újabb változat→ (eltér)

Tartalomjegyzék

Mutatók (pointer-ek)

Mi is egy mutató?

A mutató (angolul pointer) típusú adat egy másik adat címét tárolja, vagyis azt, hogy hol van tárolva az adat a számítógép memóriájában. (Első kép innen.)

Minden mutatót ugyanolyan belső ábrázolással tárolunk (hiszen mindegyik egy cím egy memóriaterületre, egész pontosan a terület "kezdőpontjára"), mégis van "típusa", ami hivatkozott objektum típusát határozza meg. Ebből tudja majd a program futás közben, a mutató által mutatott objektum használatakor, hogy "mekkora" az objeltum maga, vagyis mekkora az az adatterület a memóriában, ami a mutatott változóhoz tartozik.


Mire jók a mutatók?

Első ránézésre a mutatók csak bonyolítják a dolgokat. Programozóként miért kell tudnunk egy változó címét? A Python jól el tudta rejteni előlünk azt, hogy a változók hogyan és hol is léteznek fizikailag a memóriában (sőt még a változók típusát is elrejti nagyjából), és ez eléggé kényelmes volt.

A C egy alacsonyabb szintű nyelv, itt "gépközelibb" eszközökkel kell dolgoznunk. Ez egyrészt kényelmetlen lehet, másrészt viszont lehetőséget ad olyan optimalizálásokra, olyan hatékony programok írására, ami egy magasabb szintű nyelven nehézkes vagy lehetetlen lenne. (Pl: bitenkénti műveletek, bool vektor tárolása)


Konkrétabban mire jók a mutatók?

  • komplex adatstruktúrák kialakítására (láncolt listák, fák)
  • tömbök címzésére
  • függvénynek paraméterként átadható: csak a cím másolódik, ez egyrészt hatékonyabb egy nagy adatstruktúra esetén, másrészt így a mutatott objektumot megváltoztathatja a függvény
  • akár több mutatónk is lehet ugyanarra a memóriacímre: adatok sorbarendezése többféle sorrendben, adat-többszörözés nélkül


Hogy néz ki egy mutató C-ben?

Két operátort kell ismernünk a mutatók használatához (mindkettőt a változó neve elé kell írni amire vonatkoztanni akarjuk):

  • Egy létező változó címét a "&" operátorral kérhetjük el.
  • A "*" operátorral kérhetjük el a dolgot/objektumot amire egy mutató mutat

Egy egyszerű példa: a "szam" egész típusú változó értékét a mutatóján keresztül állítjuk be. (Emlékeztető: az értékadás operátora az "=", és ez mindig a bal oldali dolognak ad új értéket, a bal oldali változó új értéke a jobb oldali kifejezés kiértékelésének eredménye lesz.)

/* egy szám deklarálása */ 
int szam;
/* létrehozzuk a mutatót, a típusa "olyan mutató ami int típusra mutat"  */
int *szam_ptr;
 
/* itt még nincsenek "összekötve" a fenti változók, 
nincs is értékük (ill. a lokális int-nem 0 lesz az értéke), 
a lényeg hogy a memóriában lefoglalódott nekik a hely*/ 
 
/* most értéket adunk a mutatónknak, azt mondjuk mutasson 
a "szam"-ra vagyis a "szam" címével tesszük egyenlővé */
szam_ptr = &szam;
 
/* végül a "szam" értékét beállítjuk 3-ra a mutatót használva */
*szam_ptr = 3;

Nem kötelező, de ajánlott, hogy a mutató típusú változóknak a neve is utaljon erre, vagyis végződjön a neve "_ptr"-re, vagy kezdődjön "p_"-vel (mindegy melyiket választod, de utána - legalább egy programon belül - mindig csak azt a jelölést használd amit választottál!). Ez segít a kód megértésében, csökkenti a hibák valószínűségét.


Források és további olvasnivalók:
Személyes eszközök