4. előadás (2005. március 8.)
Post on 04-Jan-2016
23 Views
Preview:
DESCRIPTION
TRANSCRIPT
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
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).
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.
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!
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!
6
Pointer aritmetika 2.
Logikai műveletek:
összehasonlítás: == !=
Pl.char *p1,*p2;
....if ( p1 == p2 ) ...
if ( p1 != NULL ) ...
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)
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]
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*/
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.
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]
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;
}
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;
}
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)
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.
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++;
}
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*/
}
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*/
}
}
19
Példa: string másolása 4.
void strc4 (char* sbe, char* sbol)
{
while ((*sbe++ = *sbol++) !='\0');
}
20
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"};
vagydouble *koord[2], x, y;
koord[0] = &x; koord[1] = &y;
vagydouble 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
**pp = *p = i = 66
1008
1014
66
pp
p
i
1000
1004
1008
100C
1010
1014
top related