Ha meg akarod tudni, hogy az egyes típusok milyen méretűek a te rendszereden, a következő program megmutatja:



Hasonló dokumentumok
Járműfedélzeti rendszerek II. 4. előadás Dr. Bécsi Tamás

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Programozás I gyakorlat. 10. Stringek, mutatók

A C programozási nyelv V. Struktúra Dinamikus memóriakezelés

C programozás. 6 óra Függvények, függvényszerű makrók, globális és

8. gyakorlat Pointerek, dinamikus memóriakezelés

Mutatók és mutató-aritmetika C-ben március 19.

A C programozási nyelv III. Pointerek és tömbök.

Járműfedélzeti rendszerek II. 3. előadás Dr. Bécsi Tamás

A C programozási nyelv III. Pointerek és tömbök.

Java II. I A Java programozási nyelv alapelemei

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós október 15. Széchenyi István Egyetem, Gy r

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós augusztus 29. Széchenyi István Egyetem, Gy r

11. gyakorlat Sturktúrák használata. 1. Definiáljon dátum típust. Olvasson be két dátumot, és határozza meg melyik a régebbi.

5. Gyakorlat. struct diak {

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák:

Bevezetés a C++ programozási nyelvbe

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Függvények. Programozás I. Hatwágner F. Miklós november 16. Széchenyi István Egyetem, Gy r

Programozás alapjai. 10. előadás

C memóriakezelés. Mutató típusú változót egy típus és a változó neve elé írt csillag karakterrel hozhatjuk létre.

Forráskód formázási szabályok

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

OOP #14 (referencia-elv)

Programozas 1. Strukturak, mutatok

Programozás C és C++ -ban

Adatszerkezetek Tömb, sor, verem. Dr. Iványi Péter

A verem (stack) A verem egy olyan struktúra, aminek a tetejéről kivehetünk egy (vagy sorban több) elemet. A verem felhasználása

Java II. I A Java programozási nyelv alapelemei

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Struktúrák (struct) A struktúra szerkezetét meghatározó deklaráció általános formája:

10. gyakorlat Struktúrák, uniók, típusdefiníciók

Programozás II. 4. Dr. Iványi Péter

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Mutatók. Dr. Bécsi Tamás 7. Előadás

Osztályok. 4. gyakorlat

Pénzügyi algoritmusok

Programozás BMEKOKAA146. Dr. Bécsi Tamás 5. előadás

Bevezetés a programozásba. 9. Előadás: Rekordok

Memóriagazdálkodás. Kódgenerálás. Kódoptimalizálás

C++ programozási nyelv

Programozás C++ -ban

A programozás alapjai 1 Rekurzió

Programozás alapjai. 7. előadás

3. Osztályok II. Programozás II

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Előfeldolgozó rendszer Tömbök. Dr. Bécsi Tamás 4. Előadás

Programozás 5. Dr. Iványi Péter

Programozás II. 2. Dr. Iványi Péter

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

Függvény pointer. Feladat: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányszor.

C++ programozási nyelv Konstruktorok-destruktorok

Tömbök kezelése. Példa: Vonalkód ellenőrzőjegyének kiszámítása

Programozási nyelvek Java

OOP. Alapelvek Elek Tibor

1. Alapok. Programozás II

Információs Technológia

Járműfedélzeti rendszerek II. 1. előadás Dr. Bécsi Tamás

C programozási nyelv

Java programozási nyelv 4. rész Osztályok II.

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós április 4. Széchenyi István Egyetem, Gy r

7. fejezet: Mutatók és tömbök

Készítette: Nagy Tibor István

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

Java programozási nyelv

sallang avagy Fordítótervezés dióhéjban Sallai Gyula

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

C++ programozási nyelv Konstruktorok Gyakorlat

Szövegek C++ -ban, a string osztály

Óbudai Egyetem. C programozási nyelv

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

1. Jelölje meg az összes igaz állítást a következők közül!

Objektumok inicializálása

10. gyakorlat. Pointerek Tárolási osztályok

C programozási nyelv

Adatszerkezetek 1. Dr. Iványi Péter

Programozás 1. Dr. Iványi Péter

Occam 1. Készítette: Szabó Éva

Programozás 6. Dr. Iványi Péter

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

Programozási nyelvek a közoktatásban alapfogalmak II. előadás

tétel: különböző típusú adatokat csoportosít, ezeket egyetlen adatként kezeli, de hozzáférhetünk az elemeihez is

Programozás C++ -ban

C programozás. 1 óra Bevezetés

Programozás I gyakorlat

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

Programozás C++ -ban 2007/1

Mérnöki programozás 7. Szerkesztette: dr. Vass Péter Tamás

Fordítóprogramok. Aszalós László szeptember 7.

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

A C programozási nyelv IV. Deklaráció és definíció

C++ programozási nyelv

Miről lesz ma szó? A PROGAMOZÁS ALAPJAI 1. Dinamikus változók. Dinamikus változók. Dinamikus változók. Dinamikus változók. 7.

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós október 11. Széchenyi István Egyetem, Gy r

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

17. előadás: Vektorok a térben

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

Átírás:

9 Mutató Ha profi akarsz lenni a C nyelv használatában, nagyon tiszta és világos fogalmak szükségeltetnek a mutatókról. Sajnos ez a téma sok "újonc" fejében csak egy nagy sötét foltként jelenik meg, főleg azoknál, akik más nyelvekből (pl. Pascal, BASIC) érkeztek. Nekik szól ez a cikk. Hogy a lehető leghasznosabb legyen, fontosnak tartom, hogy a kódok minél több környezetben működjenek. Ezért megpróbáltam ragaszkodni az ANSI szabványhoz, hogy bármilyen ANSI C fordítóval le lehessen őket fordítni. Arra is ügyeltem, hogy a kód mindig jól elkülönüljön a szöveg többi részétől. Így egyszerűen csak bemásolod egy szerkesztőprogramba, elmented sima szövegként (ASCII) és már fordítható is. Javaslom az olvasónak, hogy tegyen így, ez segíteni fogja a cikk megértését. 9.1 Mi is az a mutató? Azon dolgok egyike, amik nehéznek bizonyulnak a kezdők számára a C-ben. Azt tapasztaltam, hogy a mutatókkal kapcsolatos problémák a változók és kezelésük hiányos ismeretéből ered, ezért először ezekkel fogunk foglalkozni. A változó a programban egy olyan valami, aminek neve van, egy olyan érték, ami változhat. A fordító (compiler) és a szerkesztő (linker) ezt úgy kezeli, hogy hozzárendel egy blokkot a memóriából, ami ezt az értéket tárolja. Ennek a blokknak a mérete attól függ, hogy milyen határok között változhat a változó. Például, egy 32 bites PC-n az egész típus mérete 4 byte. A régebbi, 16 bites gépeken 2 byte volt. A C-ben egy változótípusnak, mint pl. ez egész, nem kell minden géptípuson ugyanolyan méretűnek lenni. Sőt mi több, nem is csak egyféle egész létezik a nyelvben. Lehet egész (int), hosszú egész (long), vagy rövid egész (short) is, ezeket majdnem minden C kódban megtalálhatod. A továbbiakban feltételezzük, hogy 32 bites rendszeren 4 byteos egészeket használunk. Ha meg akarod tudni, hogy az egyes típusok milyen méretűek a te rendszereden, a következő program megmutatja: #include int main() { printf("short merete %dn", sizeof(short)); printf("int merete %dn", sizeof(int)); printf("long merete %dn", sizeof(long)); } Amikor egy változót deklarálunk, akkor egyszerre két dologról is tájékoztatjuk a fordítót: a változó nevéről és típusáról. Például deklarálunk egy k nevű egészet: int k; Amikor a fordító az 'int'-hez ér, akkor szépen lefoglal 4 byte memóriát, hogy az egészünk értékét tárolni tudja. És ezen felül, beállítja a szimbólumtáblát (symbol table). Beleteszi a k szimbólumot, és mellé fölírja, hogy honnan kezdődik a memóriában az a 4 byte, amit lefoglalt. Így amikor később azt írjuk, hogy: 32

k=2; Amikor a futás ide ér, akkor a k számára fenntartott helyre a 2-es szám kerül. A C-ben a k egészre úgy hivatkozunk, hogy "objektum". Bizonyos értelemben, a k-hoz két érték is tartozik. Az egyik az egész szám, amit benne tárolunk (a fenti példában ez a 2), a másik pedig a memóriahely "értéke", tehát k címe. Több szövegben ezekre úgy hivatkoznak (ebben a sorrendben), mint rvalue (right value, jobbérték) és lvalue (left value, balérték). Néhány nyelvben balérték csak a "=" hozzárendelő operátor bal oldalán engedélyezett (tehát mint az a cím, ahova a jobb oldalon található kifejezés értéke kerül). A jobbérték pedig az, ami a jobb oldalon áll, a példánkban a 2. A jobbértékeket tilos az egyenlőségjel bal oldalára írni, ezért ez helytelen: 2=k; Azonban a balérték fenti definíciója egy kissé módosult a C-ben. [K&R II, 197.old] (ld. a fejezet végén) szerint: "Az objektum egy névvel rendelkező tárolási hely, a balérték pedig egy objektumra hivatkozó kifejezés." Jelenleg a fenti definíció számunkra bőven elegendő, később majd jobban belemegyünk a részletekbe. Rendben, akkor most tekintsük a következőt: int j, k; k = 2; j = 7; <-- első sor k = j; <-- második sor A fenti kódrészletben az első sorban a fordító j-t úgy értelmezi, mint j címét (tehát a balértékét), és olyan kódot készít, hogy a 7-est arra a címre helyezze. Azonban a második sorban, a j már a jobbértékét jelenti (mivel az "=" jobb oldalán van). Tehát most j az az érték, amit a j memóriacímén tárolunk, ebben az esetben 7. Így végül a k balértéke által mutatott helyre a 7 kerül. Az összes eddigi példában 4 byteos egészeket használunk, így amikor a másolásra kerül a sor, mindig 4 byteot másolunk. Ha 2 byteos egészeket használtunk volna, akkor 2 byteot is másoltunk volna. Most mondjuk, valamilyen okból egy olyan változóra van szükségünk, ami arra van kitalálva, hogy egy balértéket tároljunk benne (egy memóriacímet). Hogy egy ilyen változónak mennyi hely szükséges, az rendszerfüggő. Régebbi gépeken, amiknek összesen 64KB memóriája volt, egy memóriacím tárolására elég volt 2 byte. Az ennél több memóriával rendelkező gépeken nagyobb blokk szükséges. A ténylegesen szükséges érték nem is fontos, amíg van rá mód, hogy tájékoztassunk a fordítót, hogy most egy címet akarunk majd tárolni. 33

Egy ilyen változót hívnak mutató változónak (pointer variable). Hogy miért pont így, az a későbbiekben remélhetőleg egy kissé tisztábbá fog válni. A C-ben úgy definiálhatunk mutatót, hogy a változó neve elé egy csillagot (*) teszünk. A C-ben a mutatóknak típust is adunk, ami ebben az esetben, azt az adattípust jelenti, amilyen típusú változónak a címét akarjuk a mutatónkban tárolni. Példaként tekintsük a következő változódeklarációt: int *ptr; Itt a változónk neve ptr (mint ahogy az előbbiekben a k volt a neve az egész változónak). A '*' azt jelzi a fordítónak, hogy itt egy mutatóról van szó, tehát annyi helyet foglaljon le a memóriában, amennyivel egy mutatót tárolni lehet. Az int arra utal, hogy egy egész címét fogjuk majd tárolni. Tehát ez egy "egészre mutató" mutató. Vegyük észre, hogy amikor az int k;-t leírtuk, a k-nak nem adtunk értéket. Ha ez minden függvényen kívül történt, akkor egy szabványos ANSI fordító a 0 értéket kell hogy adja neki. Hasonlóképpen, a ptr-nek sem adtunk, tehát, ha minden függvényen kívül deklaráltuk, akkor a fordító biztosítja, hogy garantáltan ne mutasson egyetlen érvényes C objektumra vagy függvényre. Egy ilyen mutatót "nulla-mutatónak" (null pointer) nevezünk. Azonban egy nulla-mutató tulajdonképpen képe a memóriában (bitminta, bit pattern) valószínűleg nem lesz éppen 0, ez megint csak a használt rendszertől függ. Hogy a forráskód hordozható maradjon, a nulla-mutató jelölésére egy makrót használunk. Ennek a makrónak a neve NULL. Így ha egy mutatónak ezt adjuk értékül, pl. a ptr=null; utasítással, akkor a mutatónk garantáltan nulla-mutatóvá fog válni. Hasonlóan, amikor egy egész értéket vizsgálunk, akkor az if(k==0) kifejezést használjuk, pointerek esetén ez az if(ptr==null) lesz. De térjünk vissza a vadiúj ptr-ünk használatára. Tegyük fel most, hogy a ptr-ben a k címét akarjuk használni. Ehhez az & címképző operátort használjuk. ptr=&k; Az & operátor annyit csinál, hogy visszaadja k balértékét (címét), bár k az "=" jobb oldalán áll, utána ezt az értéket másoljuk ptr-be. Most azt mondjuk, hogy ptr "k-ra mutat". Ennek a fordítottja a hivatkozás-fordító (dereferencing) operátor, a csillag, használata a következő: *ptr=7; Ez a 7-et arra a címre másolja, amit a ptr-ben tároltunk. Így, ha ptr k-ra mutat (k címét tartalmazza), a fenti utasítás eredményeképpen k értéke 7 lesz. Amikor a '*' operátort használjuk, akkor arra az értékre hivatkozunk, amire ptr mutat, és nem ptr értékére. Hasonlóképpen írhatjuk: printf("%d\n",*ptr); 34

hogy kiírjuk a képernyőre annak az egésznek az értékét, amire ptr mutat. Hogy lássuk hogy is működik az egész egyben, nézzük át és futtassuk a következő példaprogramot. #include int j, k; int *ptr; int main(void) { j = 1; k = 2; ptr = &k; printf("n"); printf("j erteke %d es a %p cimen van tarolvan", j, (void *)&j); printf("k erteke %d es a %p cimen van tarolvan", k, (void *)&k); printf("ptr erteke %p es a %p cimen van tarolvan", ptr, (void *)&ptr); printf("annak az egesznek az erteke, amire ptr mutat: %dn", *ptr); return 0; } Megjegyzés: még nem beszéltünk a C nyelv azon elemeiről, amik a (void *) kifejezés használatát megindokolják. Egyelőre rakd bele a kódba, az okokat majd később magyarázzuk meg. Összefoglalva A változót a típus és a név megadásával deklaráljuk. (pl.: int k;) Mutatót szintén típus és név megadásával deklarálunk (pl.: int *ptr;), a fordítónak a csillag jelzi, hogy mutatóról van szó, a típus pedig ezt mondja meg, hogy milyen típusra fog a mutató mutatni (ebben az esetben egész). A már deklarált változó címét az & címképzõ operátorral érhetjük el (pl.:&k). Egy mutatót "megfordíthatunk" (dereference), tehát hivatkozhatunk arra az értékre, amire a mutató mutat. Ezt a * operátorral érhetjük el (pl.:*ptr). Egy változó balértéke a címének az értéke, tehát hogy a memóriában hol tárolódik. A jobbérték pedig a változóban, a balérték által mutatott címen tárolt érték. 35

10 Struktúrák A struktúra egy vagy több, esetleg különböző típusú változó együttese, amelyet a kényelmes kezelhetőség céljából önálló névvel látunk el. Néhány nyelvben az így értelmezett struktúrát rekordnak nevezik (pl. a Pascal rekordja hasonló tulajdonságú adatfajta). A struktúra bevezetése segíti az összetett adathalmazok szervezését, ami különösen nagy programok esetén előnyös, mivel lehetővé teszi, hogy az egymással kapcsolatban lévő változók egy csoportját egyetlen egységként kezeljük, szemben az egyedi adatkezeléssel. A struktúrára az egyik hagyományos példa a bérszámfejtési lista: ez az alkalmazottakat attribútumok halmazával (név, lakcím, társadalombiztosítási szám, bér stb.) írja le. Ezen attribútumok némelyike maga is lehet struktúra, pl. a név is több részből áll, csakúgy mint a cím vagy a bér. A másik, C nyelvre jellemzőbb példát a számítógépes grafika adja: a pont egy koordinátapárral írható le, a négyzet egy pontpárral adható meg stb. A struktúrákat érintő, az ANSI szabványból adódó legfontosabb változás, hogy a szabvány értelmezi a struktúrák értékadását. A struktúrák átmásolhatók egymásba, értékül adhatók más struktúráknak, átadhatók függvénynek és a függvények visszatérési értékei is lehetnek. Ezt évek óta a legtöbb fordítóprogram támogatja, de ezeket a tulajdonságokat most pontosan definiáljuk. A szabvány lehetővé teszi az automatikus tárolási osztályú struktúrák és tömbök inicializálását, amivel szintén ebben a fejezetben foglalkozunk. 10.1 Alapfogalmak Hozzunk létre néhány struktúrát, amelyek a grafikus ábrázoláshoz használhatók. Az alapobjektum a pont, amely egy x és egy y koordinátával adható meg. Tételezzük fel, hogy a koordináták egész számok. A két komponens (koordináta) egy struktúrában helyezhető el a struct pont { int x; int y; }; deklarációval. A struktúra deklarációját a struct kulcsszó vezeti be, amelyet kapcsos zárójelek között a deklarációk listája követ. A struct kulcsszót opcionálisan egy név, az ún. struktúracímke követheti (mint a példánkban a pont). Ez a címke vagy név azonosítja a struktúrát és a későbbiekben egy rövidítésként használható a kapcsos zárójelek közötti deklarációs lista helyett. A struktúrában felsorolt változóneveket a struktúra tagjainak nevezzük. Egy struktúra címkéje (neve), ill. egy tagjának a neve és egy közönséges (tehát nem struktúratag) változó neve lehet azonos, mivel a programkörnyezet alapján egyértelműen megkülönböztethetők. Továbbá ugyanaz a tagnév előfordulhat különböző struktúrákban, bár célszerű azonos neveket csak egymással szoros kapcsolatban lévő adatokhoz használni. Egy struct deklaráció egy típust is definiál. A jobb oldali, záró kapcsos zárójel után következhet a változók listája, hasonlóan az alapadattípusok megadásához. Így pl. a struct {...} x, y, z; 36

szintaktikailag analóg az int x, y, z; deklarációval, mivel mindkét szerkezet a megadott típusú változóként deklarálja x, y és z változót és helyet foglal számukra a tárolóban. Az olyan struktúradeklaráció, amelyet nem követ a változók listája, nem foglal helyet a tárolóban, csak a struktúra alakját írja le. Ha a struktúra címkézett volt, akkor a címke a későbbi definíciókban a struktúra konkrét előfordulása helyett használható. Például felhasználva a pont korábbi deklarációját a struct pont pt; definíció egy pt változót definiál, ami a struct pont-nak megfelelő típusú struktúra. Egy struktúra úgy inicializálható, hogy a definíciót az egyes tagok kezdeti értékének listája követi. A kezdeti értékeknek állandó kifejezéseknek kell lenni. Például: struct pont maxpt = { 320, 200 }; Egy automatikus struktúra értékadással vagy egy megfelelő típusú struktúrát visszaadó függvény hívásával is inicializálható. Egy kifejezésben az adott struktúra egy tagjára úgy hivatkozhatunk, hogy struktúra-név.tag A pont struktúratag operátor összekapcsolja a struktúra és a tag nevét. A pt pont koordinátáit pl. úgy írathatjuk ki, hogy printf("%d, %d", pt.x, pt.y); A pt pont origótól mért távolsága: double dist, sqrt(double); dist = sqrt((double)pt.x * pt.x + (double)pt.y * pt.y); A struktúrák egymásba ágyazhatók. 10.2 Struktúrák és függvények A struktúrák esetén megengedett művelet a struktúra másolása vagy értékadása, ill. a struktúra címéhez való hozzáférés az & operátorral és a struktúra tagjaihoz való hozzáférés. Ezek a műveletek a struktúrát egy egységként kezelik, és a másolás vagy értékadás magában foglalja a struktúrák függvényargumentumkénti átadását, ill. a struktúra típusú függvényvisszatérés lehetőségét is. Struktúrák egy egységként nem hasonlíthatók össze. A struktúrák állandó értékek listájával inicializálhatók, és automatikus tárolási osztályú struktúrák kezdeti értéke értékadással is beállítható. A struktúrák tulajdonságainak vizsgálatához írjunk néhány függvényt, amelyek pontokkal és téglalapokkal manipulálnak. A feladat megoldásának három lehetséges módja van: a függvénynek átadjuk az egyes komponenseket, a teljes struktúrát vagy annak mutatóját. Mindegyik módszernek van előnye és hátránya. Az első függvény legyen a makepoint, amelyet két egész értékkel hívunk és visszatér egy pont struktúrával. 37

/* makepoint: egy pont struktúrát csinál az x és y komponensekből */ struct pont makepoint (int x, int y) { struct pont temp; temp.x = x; temp.y = y; return temp; } Vegyük észre, hogy nincs konfliktus abból, hogy az argumentum és a struktúratag neve megegyezik: az összefüggés kiértékelésekor újra felhasználja a rendszer a nevet. Ha nagy struktúrát kell átadnunk egy függvénynek, akkor sokkal hatékonyabb, ha a struktúra mutatóját adjuk át és nem pedig a teljes struktúrát másoljuk át. Egy struktúrához tartozó mutató éppen olyan, mint egy közönséges változó mutatója. A struktúra mutatójának deklarációja: struct pont *pp; Ez egy struct pont típusú struktúrát kijelölő mutatót hoz létre. Ha pp egy pont struktúrát címez, akkor *pp maga a struktúra, és (*pp).x, ill. (*pp).y pedig a struktúra tagjai. A pp értékét felhasználva pl. azt írhatjuk, hogy struct pont kezdet, *pp; pp = &kezdet; printf("kezdet: (%d, %d)\n", (*pp).x, (*pp).y); A zárójelre a (*pp).x kifejezésben szükség van, mert a. struktúratag operátor precedenciája nagyobb, mint a * operátoré. A *pp.x kifejezés azt jelentené, mint a *(pp.x), ami viszont szintaktikailag hibás, mivel jelen esetben x nem mutató. A struktúrák mutatóit gyakran használjuk egy új, rövidített jelölési formában. Ha p egy struktúra mutatója, akkor a p-> struktúratag kifejezés közvetlenül a struktúra megadott tagját címzi. A -> operátor a mínusz jel és a nagyobb jel egymás után írásával állítható elő. Ezt felhasználva az előző példa printf függvényét úgy is írhatjuk, hogy printf("kezdet: (%d, %d)\n", pp->x, pp->y); A. és a -> operátorok balról jobbra hajtódnak végre, ezért a struct tegla r, *rp = &r; deklaráció esetén az r.pt1.x; rp->pt1.x; (r.pt1).x; (rp->pt1).x; kifejezések egymással egyenértékűek. 38