Programozas 1 Strukturak, mutatok
Strukturak
Tömb: több egyforma típusú változó együttese Struktúra: több különböző típusú de logikailag egybetartozó változó együttese, amelyet az egyszerű kezelhetőség érdekében gyűjtöttünk össze
Arak={1500, 2200, 700, 5000} Könyv={"Milne,A.A.","Micimacko",250,1800} szerző
cím
oldalszám ár
Strukturak
Deklaralasa: struct
{ <mező1>; <mező2>; ….. }
Struktúra használatakor a mezőkre valtozónév.mező szintaxissal utalunk
Struktúrák
Példa: struct konyv { char szerzo[20]; char cím[20]; int oldalszam; int ar; } struct konyv micimacko; strcpy(micimacko.szerzo,"A.A.Milne"); micimacko.oldalszam=250;
Egymásba ágyazás struct datum { int ev; int honap; int nap; }; struct szemely { char nev[100]; struct datum szuletes; }; struct szemely kolto; strcpy(kolto.nev,"Arany Janos"); kolto.szuletes.ev=1817; kolto.szuletes.honap=3;
Struktúra tömb
struct szemely koltok[100]; strcpy(koltok[0].nev,"Petofi Sandor"); koltok[0].szuletes.ev=1823; strcpy(koltok[1].nev,"Arany Janos"); koltok[1].szuletes.ev=1817; …
Mutatok
Memoria: több milliard byte-bol all Windows
Meghajtoprogramok Böngészo Powerpoint
Visual Studio Program
Powerpoint dokumentum
Mutatok
Honnan lehet tudni hogy hol van amit keresunk?
Minden memoriabyte-nak van egy cime
Pl. a Powerpoint a 1435432-es byte-tol kezdodik A dokumentum a 1532412-es byte-tol Az 5. dia a 1535757-es byte-tol A 6. dia a 1536124-es byte-tol
Ugyanugy a mi programunkban is minden utasitasnak, valtozonak, fuggvenynek van egy cime
Mutatok
Példaul: int i=5; char s[20]="Ez egy szoveg"; i valtozo -> 4 byte-on (int) -> értéke: (00 00 00 0)5 ->cime: 0x0044FBF
s valtozo ->20 byte-on -> cime: 0x0044FC04
Mutatok
Egy valtozonak a memoriacimet a kovetkezokeppen kaphatjuk meg: void main() { char s[20]="Ez egy szoveg"; printf("Az s erteke: %s \n",s); printf("Az s memoriacime: %x \n",&s); getch(); }
Mutatok
A mutato (pointer) egy olyan valtozo, amely egy memoriacimet tartalmaz Mutatok deklaralasa:
tipus *valtozonev;
Példa: int *p;
egy egész tipusu valtozora mutato pointer
Mutatok és változók Valtozok
Mutatok
int a;
int *p;
a érték &a memoriacim
p memoriacim *p érték
Példa
int a=5; int *p; p=&a; *p=6;
a p
5 6
Példa int a=1; int b=2; int c=3; int *p; int *q;
a
1
xxx
p
b
2
xxx
q
c
3
Példa int a=1; int b=2; int c=3; int *p; int *q;
p=&a; q=&b;
a
1
p
b
2
q
c
3
Példa int a=1; int b=2; int c=3; int *p; int *q;
p=&a; q=&b; c=*p
a
1
p
b
2
q
c
1
Példa int a=1; int b=2; int c=3; int *p; int *q;
p=&a; q=&b; c=*p
p=q;
a
1
p
b
2
q
c
1
Példa int a=1; int b=2; int c=3; int *p; int *q;
p=&a; q=&b; c=*p
p=q; *p=13
a
1
p
b
13
q
c
1
Példa int *p, q; *p=45;
//HIBA: p nem mutat sehova
*q=45;
//HIBA: q nem mutato
A NULL pointer
Speciális eset, amikor a pointer értéke 0 (nulla) Ez azt jelenti, hogy a pointer nem mutat érvényes adatra A NULL a stdio.h-ban van deklarálva Ezt legtöbbször a pointer érvényességének az ellenőrzésére használjuk Ha a pointer üres, ajánlott NULL-ra állítani (hogy utolag tudjuk leellenőrizni)
Mutatok es fuggvenyek
A fuggvenyek hianyai:
Egyetlen erteket tudnak visszaadni Nem tudjak megvaltoztatni a parameterek ertekeit
A fuggvenyek a bemeno parameterek ertekeit kapjak meg, nem magukat a valtozokat
Mi van ha a valtozok cimet adjuk meg parameternek?
Ezt hivjuk cim szerinti parameteratadasnak
Hasznalat: void fuggveny(int* parameter)
Példa void csere(int *p, int *q) { int c; c=*p; *p=*q; *q=c; } void main() { int a=4; int b=7; int *x,*y; x=&a; y=&b; csere(x,y); printf("a: %d b: %d",a,b); }
Rovidebben:
void main() { int a=4; int b=7;
csere(&a,&b); printf("a: %d b: %d",a,b); }
Mutatok es tombok
A tömbök és mutatók szorosan egybetartoznak Egy egydimenziós vektor esetén a változó egy mutató a vektor 0-dik elemére.
tomb
tomb == & (tomb[0])
Tömbök és mutatók
Példa: int Tomb[10]; int *pTomb; pTomb=Tomb;
Van egy különbség, a tömb címe konstans, míg a mutató megváltoztatható pTomb++;
Tomb++;
Mutatók és tömbök
A mutatókat is kezelhetjük tömbként, amennyire tömbre mutatnak
Példa: int v[10]; int *p=v; p[5]=2;
Címaritmetika
A mutatóknak az értéke tetszés szerint változtatható: a megfeleltetésen kívül növelhető, csökkenthető. A cím+egész kifejezésnek az az alapvető tulajdonsága, hogy mindig a pointer típusának megfelelően a következő címet állítja elő Példa: int tomb[10]; int *p=tomb; //ptomb[0] *(p+2)=3; p+=4; *(p+3)=1;
//tomb[2]=3 //ptomb[4] //tomb[7]=1
Címaritmetika
Ha két pointer ugyanannak a tömbnek az elemeire mutat, akkor értelmezettek a <, >, ==, != stb. relációs műveletek. Ha két pointer ugyanannak a tömbnek az elemeire mutat, ( pl.: a és b ), akkor a - b az a és b közötti elemek darabszámát adja. Pointerhez hozzáadhatunk, ill. levonhatunk egész számot. Tilos : Pointerek szorzása, osztása, shiftelése, maszkolása, ill. float vagy double mennyiségek pointerekhez való hozzáadása vagy kivonása.
Példa int i,n; int *p; int v[100]; p=&v[0]; // p a tomb elso elemere mutat scanf("%d",&n); for(i=0;i
Tömbök és mutatók
A kétdimenziós tömb a memóriában soronként van tárolva char a[3][4]
Memóriában
1
2
3
4
A
B
C
D
á
é
ö
ü
1 p
2
3
4
A
B
C
D
á
é
ö
char *p; p=a; putc(*(p+2)); //3 putc(*(p+5)); //B
A szabály egy elem pozíciójának kiszámolására: pozicio=sor*szélesség+oszlop sor=pozicio/szelesseg;oszlop=pozicio%szelesseg
ü
Dinamikus memoriakezeles
Tomb deklaralasa:
Mindig elore meg kell adni a tomb meretet
int v[100]; Nem lehetseges: int v[n]
Dinamikus memoriakezelest akkor hasznalunk:
Ha nem tudjuk elore, mekkora tomb kell Ha bemeneti adattol fugg a tomb merete
Dinamikus memoriakezeles
Memoriafoglalas: void* malloc(int meret);
Ez egy adott meretu memoriatombot foglal le A meret byte-ban van megadva A fuggvenynek nincs tipusa =>barmilyen tipusu valtozot le lehet foglalni Cast-olni kell a meghivaskor a valtozo tipusara Ha nem sikerul: NULL-ot ad vissza
Példa int *p p=(int*)malloc(100*sizeof(int));
Dinamikus memoriakezeles
Memoriafoglalas: void* calloc(int elemszam, int elemmeret);
Hasonlit a malloc fuggvenyhez Egy adott elemszamu tombot foglal le, ahol minden elem adott meretu Nullazza (torli) az adott teruletet Cast-olni kell a meghivaskor a valtozo tipusara Ha nem sikerul: NULL-ot ad vissza
Példa int *p; int n=35; p=(int*)calloc(n,sizeof(int));
Dinamikus memoriakezeles
Memoriafelszabaditas free(void* block);
Felszabadit egy dinamikusan lefoglalt memoriareszt A pointert nem modositja, az pedig igy ervenytelen lesz!
FONTOS!!! A lefoglalt memóriaterületeket mindig szabadítsuk fel!
Tehát a programban legyen annyi free ahány calloc+malloc van…
Pelda Statikus memoriafoglalas
Dinamikus memoriafoglalas
int i,n; int v[100]; printf("Hany elem?"); scanf("%d",&n);
int i,n; int *v; printf("Hany elem?"); scanf("%d",&n); v=(int*)calloc(n,sizeof(int)); for(i=0;i
for(i=0;i
Dinamikus tombok
Akkor használunk dinamikus tömböket, ha egy szabálytalan mátrixot akarunk létrehozni **p
*p[0] *p[1] *p[2] ….
Ebben az esetben a tömb minden sora egy pointer A tömb maga egy duplamutató (mutató a mutatók felé). A p-t lehet kétdimenziós tömbként kezelni (pl: p[2][2])
Dinamikus tömbök int j,sor,elem; int **p; printf("Hany sor?"); scanf("%d",&sor); p=(int**)calloc(sor,sizeof(int*)); for(j = 0; j < sor; j++) { printf("Hany elemu a %d.sor?",j); scanf("%d",&elem); p[j] = (int *)calloc(elem, sizeof(int)); }
Strukturak es pointerek
A C-ben a függvények csak struktúrára mutató pointereket kaphatnak bemenő paraméterként, és csak struktúrára mutató pointereket adhatnak vissza!!!!
Struktúra címe: &
Hozzáférés struktúra pointer eleméhez: ->
Struktúrák és függvények struct szemely { char nev[100]; int kora; }; void sajat_adat(struct szemely *p) { p->kora = 30; strcpy(p->nev, ”Kovacs Istvan”); } void main() { struct szemely valaki; struct szemely *masvalaki; masvalaki=(struct szemely *)malloc(sizeof(struct szemely)); sajat_adat(&valaki); sajat_adat(masvalaki); }