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 <nev> { <tipus1> <mező1>; <tipus2> <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: Példa: tipus *valtozonev; int *p; egy egész tipusu valtozora mutato pointer
Mutatok és változók Valtozok int a; Mutatok 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 56
Példa int a=1; int b=2; a 1 xxx p int c=3; int *p; b 2 xxx q int *q; c 3
Példa int a=1; int b=2; a 1 p int c=3; int *p; b 2 q int *q; c 3 p=&a; q=&b;
Példa int a=1; int b=2; a 1 p int c=3; int *p; b 2 q int *q; c 1 p=&a; q=&b; c=*p
Példa int a=1; int b=2; p=q; a 1 p int c=3; int *p; b 2 q int *q; c 1 p=&a; q=&b; c=*p
Példa int a=1; int b=2; p=q; a 1 p int c=3; int *p; *p=13 b 13 q int *q; c 1 p=&a; q=&b; c=*p
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; //p tomb[0] *(p+2)=3; p+=4; *(p+3)=1; //tomb[2]=3 //p tomb[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]; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",p); p++; } p=&v[0]; for(i=0;i<n;i++) { printf(" %d ",*p); p++; } // p a tomb elso elemere mutat // p a tomb kovetkezo elemere mutat
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] 1 2 3 4 A B C D á é ö ü 1 2 3 4 A B C D á é ö ü p Memóriában 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: int v[100]; Mindig elore meg kell adni a tomb meretet 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 int i,n; int v[100]; printf("hany elem?"); scanf("%d",&n); for(i=0;i<n;i++) { printf("%d.elem",i); scanf("%d",&v[i]); } Dinamikus memoriafoglalas int i,n; int *v; printf("hany elem?"); scanf("%d",&n); v=(int*)calloc(n,sizeof(int)); for(i=0;i<n;i++) { printf("%d.elem",i); scanf("%d",&v[i]); } free(v);
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); }