„Dinamikus adatszerkezetek tutorial” változatai közötti eltérés
| 29. sor: | 29. sor: | ||
Ilyenkor az operációs rendszert kérjük meg arra, hogy adjon egy olyan memóriacímet, amit szabadon használhatunk. Miután memóriát kértünk, az értéket el is tároljuk, ezekre valók a pointerek, amik maguk is statikus változók, memóriacímek tárolására szolgálnak. Méretük 32 bites rendszereken (pl. Windows 98, Linux stb.) 4 byte (mindig ugyanannyi, mint egy 'int' tipus mérete, s hasonló műveleteket végezhetünk velük). | Ilyenkor az operációs rendszert kérjük meg arra, hogy adjon egy olyan memóriacímet, amit szabadon használhatunk. Miután memóriát kértünk, az értéket el is tároljuk, ezekre valók a pointerek, amik maguk is statikus változók, memóriacímek tárolására szolgálnak. Méretük 32 bites rendszereken (pl. Windows 98, Linux stb.) 4 byte (mindig ugyanannyi, mint egy 'int' tipus mérete, s hasonló műveleteket végezhetünk velük). | ||
<pre> | |||
int *a; | int *a; | ||
char *b; | char *b; | ||
</per> | |||
Deklarálásukkor még nem mutatnak sehová, vagy érvénytelen helyre. | Deklarálásukkor még nem mutatnak sehová, vagy érvénytelen helyre. | ||
Ha azonban helyes címet adunk neki, akkor használhatóak: | Ha azonban helyes címet adunk neki, akkor használhatóak: | ||
<pre> | |||
int x; | int x; | ||
int | int *px = &x; // itt a 'px' az 'x' változó címét veszi fel. Ilyen komment nincs C89-ben, csak /* */. Ne használjátok prog1-en! | ||
int *mp = (int *) malloc ( sizeof(int)*5 ); /* itt kértünk egy olyan memóriaterületet, ahol elfér 5 int. Ennek a címét kapjuk vissza. */ | int *mp = (int *) malloc ( sizeof(int)*5 ); /* itt kértünk egy olyan memóriaterületet, ahol elfér 5 int. Ennek a címét kapjuk vissza. */ | ||
int | int **pp = ∓ | ||
/ | /* igen, a pointerre mutató pointer... Értéke egy olyan memóriacím, ahol elfér egy pointer. */ | ||
</pre> | |||
Látjuk tehát, hogy a pointerek tulajdonképpen számokat tárolnak (memóriacímeket). Lehet használni tehát az 'int'-ekkel használatos műveleteket. | Látjuk tehát, hogy a pointerek tulajdonképpen számokat tárolnak (memóriacímeket). Lehet használni tehát az 'int'-ekkel használatos műveleteket. | ||
| 51. sor: | 51. sor: | ||
Egész pontosan pointerekhez hozzá lehet adni (vagy kivonni) inteket (vagy intekhez ptr-eket). Összeszorozni vagy összeadni két pointert például már nem lehet (compiler error). Viszont pl. van <, >, == stb. | Egész pontosan pointerekhez hozzá lehet adni (vagy kivonni) inteket (vagy intekhez ptr-eket). Összeszorozni vagy összeadni két pointert például már nem lehet (compiler error). Viszont pl. van <, >, == stb. | ||
<pre> | |||
int x= ... ; | int x= ... ; | ||
mp = mp + x; / | mp = mp + x; /* FONTOS! az mp-ben tárolt memóriacím nem x-szel fog növekedni, hanem x * sizeof(*mp)-vel, azaz a mutatott típus méretével. */ | ||
mp++; / | mp++; /* a pointer tipusa int *, tehát az érték sizeof(int)-tel fog növekedni. Hasznos, ha egy dinamikus tömbben a következő elemre akarunk mutatni. */ | ||
char | char *d= ... ; | ||
d++; / | d++; /* a következő karakterre fog mutatni */ | ||
d--; / | d--; /* ugyanez, csak visszafelé */ | ||
</pre> | |||
A pointerek értékeit (mi van azon a címen, amire mutat) az elé írt '*' operátorral kaphatjuk meg. | A pointerek értékeit (mi van azon a címen, amire mutat) az elé írt '*' operátorral kaphatjuk meg. | ||
<pre> | |||
int a=2006 , b; | int a=2006 , b; | ||
int *p=&a; // ilyenkor 'p' mutat 'a'-ra | int *p=&a; // ilyenkor 'p' mutat 'a'-ra | ||
int b=(*p); // 'b' = a 'p' által mutatott címen lévő érték (2006). | int b=(*p); // 'b' = a 'p' által mutatott címen lévő érték (2006). | ||
(*p)=26; // a 'p' által mutatott címre beírunk 26-ot. | (*p)=26; // a 'p' által mutatott címre beírunk 26-ot. | ||
</pre> | |||
FONTOS! A pointerek tömbként is használhatóak ( a tömbök is memóriacímre mutatnak, konkrétan oda, ahol vannak az elemei tehát ők is pointerek a maguk formájában). Így a fentebb deklarált 'mp' a következőképpen indexelhető: mp[0] ugyanaz, mint *mp vagy (mp-1)[1] (bonyolodik) mutat az első elemre. mp[1] mutat a 2. elemre, ugyanaz, mint *(mp + 1) vagy *(++mp) vagy (mp-1)[2] :) | FONTOS! A pointerek tömbként is használhatóak ( a tömbök is memóriacímre mutatnak, konkrétan oda, ahol vannak az elemei tehát ők is pointerek a maguk formájában). Így a fentebb deklarált 'mp' a következőképpen indexelhető: mp[0] ugyanaz, mint *mp vagy (mp-1)[1] (bonyolodik) mutat az első elemre. mp[1] mutat a 2. elemre, ugyanaz, mint *(mp + 1) vagy *(++mp) vagy (mp-1)[2] :) | ||
A ++mp-nek van mellékhatása. Ügyelni kell arra, hogy a foglalt memóriatartományok elejére mindig legyen pointer, különben a program memóriát fog szivárogtatni. Egyébként nem érdemes 'kivinni' pointereket memóriaterületekről (mint pl. a (mp-1)[1]), mert a C szabvány nem minden műveletet garantál. | A ++mp-nek van mellékhatása. Ügyelni kell arra, hogy a foglalt memóriatartományok elejére mindig legyen pointer, különben a program memóriát fog szivárogtatni. Egyébként nem érdemes 'kivinni' pointereket memóriaterületekről (mint pl. a (mp-1)[1]), mert a C szabvány nem minden műveletet garantál. | ||
'''Megjegyzés''': x86-64-en az int 32 bites, de a pointerek 64 bitesek, ez vidám errorokat | |||
szokott okozni régebbi progrmoknál (itt egyébként épp a long ugyanakkora, mint egy pointer). Garantáltan működő viszont a következő: | szokott okozni régebbi progrmoknál (itt egyébként épp a long ugyanakkora, mint egy pointer). Garantáltan működő viszont a következő: | ||
<pre> | |||
typedef union | typedef union { | ||
{ | int n; | ||
int n; | void* p; | ||
void* p; | } int_and_ptr; | ||
} int_and_ptr; | </pre> | ||
Mondjuk ilyenre egészen biztosan nem lesz szükségetek még vizsgán sem, de nem árt tudni. | Mondjuk ilyenre egészen biztosan nem lesz szükségetek még vizsgán sem, de nem árt tudni. | ||
Ennyit a pointerekről és a memóriáról. | Ennyit a pointerekről és a memóriáról. | ||
==Láncolt lista== | ==Láncolt lista== | ||