4. előadás (2005. március 8.)

23
4. előadás (2005. március 8.) • Pointerek • Pointer aritmetika • Tömbök és pointerek kapcsolata • Karakter tömbök • Cím szerinti paraméter átadás • Mutatótömbök • Pointerre mutató pointer

description

4. előadás (2005. március 8.). Pointerek Pointer aritmetika Tömbök és pointerek kapcsolata Karakter tömbök Cím szerinti paraméter átadás Mutatótömbök Pointerre mutató pointer. Mutatók (pointerek). A mutató adattípus létrejöttének okai: előre nem ismert méretű tömbök létrehozása, - PowerPoint PPT Presentation

Transcript of 4. előadás (2005. március 8.)

Page 1: 4. előadás (2005. március 8.)

4. előadás (2005. március 8.)

• Pointerek

• Pointer aritmetika

• Tömbök és pointerek kapcsolata

• Karakter tömbök

• Cím szerinti paraméter átadás

• Mutatótömbök

• Pointerre mutató pointer

Page 2: 4. előadás (2005. március 8.)

2

Mutatók (pointerek)

A mutató adattípus létrejöttének okai:• előre nem ismert méretű tömbök létrehozása,• egyetlen adatelemre való többszörös

hivatkozás,• dinamikus függvényhivatkozás.

Változó jellemzői: név, típus, cím (balérték), aktuális érték (jobbérték).

A mutató egy olyan típusú változó, amelynek aktuális értéke egy adott típusú változó címe (a jobbértéke balérték).

Page 3: 4. előadás (2005. március 8.)

3

Pointer típusú változó deklarációja

típus *név;

Pl.long *pj, j = 101L;

Pointer változó inicializálása:long j=101L, *pj = &j;

A hivatkozott változónak ismertnek kell lennie!

Itt a * nem operátor, hanem jelöléstípus, azonban az & jel már operátor.

Page 4: 4. előadás (2005. március 8.)

4

A visszahivatkozás operátora: *

& operátor : egy adott változó címe

* operátor : egy adott memóriacímen található (meghatározott típusú) aktuális érték előállítása, a visszahivatkozás (dereferencing) operátora.

Pl.long *pj, j=101L;

pj = &j;

printf("\n%ld",*pj);

*pj = 50L;

printf("\n%ld",*pj);

Pointer típus csak azzal a típussal együtt említhető, amilyen típusú változóra mutat!

Page 5: 4. előadás (2005. március 8.)

5

Pointer aritmetika 1.

Null pointer : általában az stdio.h-ban definiált szimbolikus név, amely az olyan mutatók értéke, amelyek nem mutatnak változóra:

#define NULL (char *)0

vagy#define NULL (void *)0

nem int 0 (méretkülönbség lehet),

0 nem azonos a NULL-lal!

Page 6: 4. előadás (2005. március 8.)

6

Pointer aritmetika 2.

Logikai műveletek:

összehasonlítás: == !=

Pl.char *p1,*p2;

....if ( p1 == p2 ) ...

if ( p1 != NULL ) ...

Page 7: 4. előadás (2005. március 8.)

7

Pointer aritmetika 3.

összeadás (pointer + egész):char *pc;

int *pi;

...

pc + 7 pi + 7

Értelmezése: 7 típusnyi objektummal való előre mutatás a memóriában

Speciális esete: ++ inkrementálás (jobb vagy baloldalon)

Page 8: 4. előadás (2005. március 8.)

8

Pointer aritmetika 4.

kivonás (pointer - egész):

Értelmezése: adott típusnyi objektummal való visszafelé mutatás a memóriában

Speciális esete: -- dekrementálás (jobb vagy baloldalon): pc+(-1)

Két pointer eltérése:char a[5];

...&a[0] - &a[3]

&a[3] - &a[0]

Page 9: 4. előadás (2005. március 8.)

9

Tömbök és pointerek kapcsolata 1.

Minden változó azonosítója elsődleges kifejezés.

Minden tömb azonosítója, mint kifejezés, megegyezik az első elemre mutató pointerrel.

Egy tömbelem hivatkozás ekvivalens a megfelelő pointer aritmetikai kifejezéssel:int a[20],*p;

p = &a[0]; p = a;

a[0] *p *(p+0)

a[1] *(p+1)

a[15] *(p+15)

*(a+5) p[5] /*keveredhet*/

Page 10: 4. előadás (2005. március 8.)

10

Tömbök és pointerek kapcsolata 2.

Fontos megjegyzés: a

p++ megengedett, de az

a++ nem megengedett! (mivel egy lefoglalt memóriaterület első elemére mutató szimbólum - konstans pointer). p kaphat új értéket, a azonban nem.

Page 11: 4. előadás (2005. március 8.)

11

Megjegyzés a többdimenziós tömbökhöz

int a[5][8]; ...

a[2][3]

Ha a második index jelentése egy mutató eltolása 3-al, akkor a[2]-nek egy tömbmutatónak kell lennie, amely egy teljes sort azonosít.

a[2][3] egyenértékű a *(a[2] + 3) kifejezéssel (a[2] egy olyan tömb elejére mutat, amely 8 elemű valós tömb)

a[1] ekvivalens az &a[1][0] -al.

Hiba forrás:

név[index1, index2] jelentése : név[index2]

Page 12: 4. előadás (2005. március 8.)

12

Függvények cím szerinti formális paraméterei

A formális paraméterlisták cím szerinti elemei pointerek.void nullaz(double *p)

{

*p = 0.0;

}

Page 13: 4. előadás (2005. március 8.)

13

Két változó értékének felcseréléseHibás megoldás!

void csere (int x; int y)/*Hibás megoldás*/

{

int s;

s = x;

x = y;

y = s;

}

Page 14: 4. előadás (2005. március 8.)

14

Két változó értékének felcseréléseHelyes megoldás!

void csere (int *px; int *py)

/*helyes megoldás*/

{

int s;

s = *px;

*px = *py;

*py = s;

}

Hívása pl.:csere(&a, &b)

Page 15: 4. előadás (2005. március 8.)

15

Karakter tömbök

char s[méret];

/* max méret-1 karakter tárolására */

Az aktuális szöveget a '\0' karakter határolja.

A függvények formális paraméterlistájában egy cím szerinti paraméter tömbként is deklarálható! Így a

void func(char *px) helyett

void func(char px[]) is írható.

A [] jelölés arra utal, hogy a memóriában egymás után azonos típusú elemek helyezkednek el, amelyek közül az elsőre mutat a mutató paraméter.

Page 16: 4. előadás (2005. március 8.)

16

Példa: string másolása 1.

void strc1 (char* sbe, char* sbol)

{

int i; i=0;

while ((sbe[i] = sbol[i]) != '\0') i++;

}

Page 17: 4. előadás (2005. március 8.)

17

Példa: string másolása 2.

void strc2 (char* sbe, char* sbol)

{

int i; i=0;

while (sbe[i] = sbol[i]) i++;/*Warning*/

}

Page 18: 4. előadás (2005. március 8.)

18

Példa: string másolása 3.

void strc3 (char* sbe, char* sbol)

{

while ((*sbe = *sbol) !='\0')

{

sbe++; sbol++;

/*a cím is érték szerint adódik át*/

}

}

Page 19: 4. előadás (2005. március 8.)

19

Példa: string másolása 4.

void strc4 (char* sbe, char* sbol)

{

while ((*sbe++ = *sbol++) !='\0');

}

Page 20: 4. előadás (2005. március 8.)

20

Példa: string másolása 5.

void strc5 (char* sbe, char* sbol)

{

while (*sbe++ = *sbol++); /*Warning*/

}

Page 21: 4. előadás (2005. március 8.)

Mutatótömbök

Olyan tömbök, melyeknek elemei mutatók:

típus *azonosító[elemszám];

Pl. char *szovegsorok[25];

Inicializálás:char *text[3] ={"e l s o h o s s z u s o r",

"masodik sor","harmadik sor"};

vagydouble *koord[2], x, y;

koord[0] = &x; koord[1] = &y;

vagydouble x, y, *koord[2] = {&x, &y};

21

Page 22: 4. előadás (2005. március 8.)

Pointerre mutató pointer

Az indirekció láncban folytatható, azaz lehet olyan mutatónk, amely egy olyan változóra mutat, amely szintén mutató: kétszeres indirekció. Pl.int i, *p, **pp;

p = &i;

pp = &p;

Ekkor *pp a p pointer aktuális értéke, ami az i címe, és

**pp a pp aktuális értéke szerinti címen található cím által mutatott memória tartalma:

**pp = *p = i = 66

22

Page 23: 4. előadás (2005. március 8.)

**pp = *p = i = 66

1008

1014

66

pp

p

i

1000

1004

1008

100C

1010

1014