„Dinamikus adatszerkezetek tutorial” változatai közötti eltérés

Ferrero (vitalap | szerkesztései)
Ferrero (vitalap | szerkesztései)
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).


%CODE{"cpp"}%
<pre>
  int *a;
  int *a;
  char *b;
  char *b;
%ENDCODE%
</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:
%CODE{"cpp"}%
<pre>
  int x;
  int x;
  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 *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 '''*pp = &mp;   
  int **pp = &mp;   
  /''' igen, a pointerre mutató pointer... Értéke egy olyan memóriacím, ahol elfér egy pointer. '''/
  /* igen, a pointerre mutató pointer... Értéke egy olyan memóriacím, ahol elfér egy pointer. */
%ENDCODE%
</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.


%CODE{"cpp"}%
<pre>
  int x= ... ;
  int 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 + 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++;  /''' 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. */
  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 '''d= ... ;
  char *d= ... ;
  d++; /''' a következő karakterre fog mutatni '''/
  d++; /* a következő karakterre fog mutatni */


  d--; /''' ugyanez, csak visszafelé */
  d--; /* ugyanez, csak visszafelé */
%ENDCODE%
</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.


%CODE{"cpp"}%
<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.
%ENDCODE%
</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
'''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ő:
%CODE{"cpp"}%
<pre>
typedef union
  typedef union {
{
  int n;
int n;
  void* p;
void* p;
  } int_and_ptr;
} int_and_ptr;
</pre>
%ENDCODE%


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==