230 likes | 323 Views
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,
E N D
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öklé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).
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.
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!
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!
Pointer aritmetika 2. Logikai műveletek: összehasonlítás: == != Pl. char *p1,*p2; .... if ( p1 == p2 ) ... if ( p1 != NULL )...
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)
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]
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ő pointeraritmetikai 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*/
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 azonbannem.
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]
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; }
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; }
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)
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.
Példa: string másolása 1. void strc1 (char* sbe, char* sbol) { int i;i=0; while ((sbe[i] = sbol[i]) != '\0') i++; }
Példa: string másolása 2. void strc2 (char* sbe, char* sbol) { int i;i=0; while (sbe[i] = sbol[i]) i++;/*Warning*/ }
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*/ } }
Példa: string másolása 4. void strc4 (char* sbe, char* sbol) { while ((*sbe++ = *sbol++) !='\0'); }
Példa: string másolása 5. void strc5 (char* sbe, char* sbol) { while (*sbe++ = *sbol++); /*Warning*/ }
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"}; vagy double *koord[2], x, y; koord[0] = &x; koord[1] = &y; vagy double x, y, *koord[2] = {&x, &y}; 21
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