Programozás 5. Dr. Iványi Péter 1
Struktúra Véges számú különböző típusú, logikailag összetartozó változó együttese, amelyeket az egyszerű kezelhetőség érdekében gyűjtünk össze. Rekord-nak felel meg struct <struktura nev> <tipus> <nev>;... }; 2
Struktúradeklarálása, definiálása struct szemely char nev[100]; int kora; char cim[100]; }; int main() struct szemely en; en.kora = 18; /* hivatkozas egy struktura elemre */ strcpy(en.nev, Kovacs Istvan );... 3
Egymásba ágyazás 1. struct datum int ev; int honap; int nap; }; struct szemely char nev[100]; struct datum szuletesi_ido; }; 4
Egymásba ágyazás 2. int main() struct szemely sz1; sz1.szuletesi_ido.ev = 1950; sz1.szuletesi_ido.honap = 1; sz1.szuletesi_ido.nap = 12; strcpy(sz1.nev, Kovacs Istvan );... 5
Struktúra tömb struct szemely char nev[100]; int kora; double fizetes; }; int main() struct szemely emberek[10]; /* 10 db deklarálása */ emberek[1].kora = 21; strcpy(emberek[1].nev, Kovacs Istvan ); 6
Mutatók Tömbök és mutatók szorosan összetartoznak. Mutató: egy másik objektum, vátozó címét tárolja típus *név; Példa: int *p; Egész típusú változóra mutató pointer. 7
Példa 1 int a=1; a 1 xxx p int b=2; int c=3; b 2 xxx q int *p; c 3 int *q; 8
Példa 2 int a=1; a 1 p int b=2; int c=3; b 2 q int *p; c 3 int *q; p=&a; q=&b... 9
Példa 3... c = *p; a 1 p... b 2 q c 1 10
Példa 4... p = q; a 1 p... b 2 q c 1 11
Példa 5... *p = 13; a 1 p... b 13 q c 1 12
int *p; Példa 6 xxx p /* HIBÁS */ *p = 45; sehova sem mutat 13
Példa 7 int *p, q; /* p : egy mutató */ /* q : NEM mutató, csak egész szám */ 14
NULL Speciális eset, amikor pointer 0 (nulla) értéket tartalmaz. Ez a NULL pointer Azt jelenti, hogy nem mutat érvényes adatra stdio.h tárolja a NULL definícióját 15
Függvények és mutatók Érték szerinti paraméter átadás Az érték bemásolódik az argumentumba Ha meg akarjuk változtatni az eredeti objektumot, csak a return-el tehetjük meg Több változó esetén nem jó Cím szerinti paraméter átadás is lehetséges 16
Függvények és mutatók #include <stdio.h> int csere(int *a, int *b) int c; c = *a; *a = *b; *b = c; } int main() int x = 1; int y = 2; csere(&x, &y); printf( %d-%d, x, y); return 0; } a b x y 1 2 2-1 17
Függvények és mutatók #include <stdio.h> /* void csere(int *a) */ void csere(int a[]) /* ez is lehet vektor jeloles */ int i; for(i = 0; i < 5; i++) printf( %d, a[i]); } int main() int a[5]; nyomtat(a); return 0; } 18
Tömbök és mutatók Egy egydimenziós vektor neve megegyezika vektor 0-dik eleméneka címével, teháta vektor kezdőcímével : vektor == &(vektor[0]); vektor 0 1 2 19
Példa: int v[10]; int *pv; pv = v; Tömbök és mutatók Van egy különbség, a tömb neve konstans nem változtatható, a mutató megváltoztatható: Érvényes Érvénytelen pv++; v++; 20
Címaritmetika Egy cím+ egész kifejezésnek az az alapvető tulajdonsága, hogy mindig az illető cím típusának megfelelően a következő elemre mutató címet állítjaelő. &(x[2]) == x+2; /* 3. elem címe */ x[2] == *(x+2); /* 3. elem értéke */ 21
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 vagydouble mennyiségek pointerekhez való hozzáadása vagy kivonása. 22
Memória kezelés Dinamikus memória kezelés Például: Nem tudjuk előre mekkora vektor kell Bemeneti adattól függ a vektor mérete 23
Memória foglalás void *malloc( size_t size ); Byte-ban kell megadni a méretet Ha nem sikerül NULL-t ad vissza Cast-olni kell az adott típusra Példa: void fvg(int n) int *p p = (int *)malloc(n * sizeof(int));... 24
Memória foglalás void *calloc(size_t nitems, size_t size ); Byte-ban kell megadni a méretet Ha nem sikerül NULL-t ad vissza Cast-olni kell az adott típusra Nullázza a területet Példa: void fvg(int n) int *p; p = (int *)calloc(n, sizeof(int));... 25
Memória felszabadítás void free( void *block ); Felszabadítja a területet, de a területre mutató pointereket nem módosítja, pedig azok is érvénytelenek lesznek!!! 26
Példa /* nagyban hasonlít a statikus tömbökhöz */ #include <stdio.h> int main() int n, i; int *p; printf( Elemek szama ); scanf( %d, &n); p = (int *)calloc(n, sizeof(int)); for(i = 0; i < n i++) scanf( %d, &(p[i])); } free(p); return 0; } 27
Például: 3x3 matrix Többdimenziós tömb #include <stdio.h> int main() double m[3][3]; int i, j; for(i = 0; i < 3; i++) for(j = 0; j < 3 ; j++) m[i][j] = i+j; } } return 0; } 0 1 2 0 1 2 0 1 2 1 2 3 2 3 4 28
Inicializálás 1. #include <stdio.h> int main() double m[3][3] = 0, 1, 2, 3, 4, 5, 6, 7, 8}; double m[3][3] = 0, 1, 2}, 3, 4, 5}, 6, 7, 8} };... 29
Inicializálás 2. char *honap_neve(int n) static char *nevek[] = ervenytelen, januar, februar, marcius, aprilis, majus, junius, julius, augusztus, szeptember, oktober, november, december }; } return ((n < 1 n > 12)? nev[0] : nev[n]); 30
Inicializálás 3. char *honap_neve(int n) static char *nevek[] = e, r, v, e, n, y, t, e, l, e, n }, j, a, n, u, a, r },... 31
Dinamikus tömbök 1. 32
Dinamikus tömbök 1. /* két dimenziós tömb vagy mátrix, sorok darabokban */ int **alloc_tomb(int sor, int oszlop) int **p; int j; } p = (int **)calloc(sor, sizeof(int *)); for(j = 0; j < sor; j++) p[j] = (int *)calloc(oszlop, sizeof(int)); } return p; 33
Dinamikus tömbök 2. 34
Dinamikus tömbök 2. /* két dimenziós tömb vagy mátrix, sorok folytatólagosan */ int **alloc_tomb(int sor, int oszlop) int **p; int j; } p = (int **)calloc(sor, sizeof(int *)); p[0] = (int *)calloc(sor * oszlop, sizeof(int)); for(j = 1; j < sor; j++) p[j] = p[j-1]+oszlop; } return p; 35
Struktúrák és függvények 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: -> 36
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 ); } int main() struct szemely en; struct szemely *pen; pen = &en; sajat_adat(pen); return 0; } 37
Dinamikus struktúra tömb 1 struct szemely char nev[100]; int kora; double fizetes; }; int main() struct szemely *emberek; /* deklarálás*/ emberek = (struct szemely *)calloc(10, sizeof(struct emberek)); strcpy(emberek[0].nev, Kovacs Istvan ); emberek[0].kora = 10;... 38
struct szemely char nev[100]; int kora; double fizetes; }; Dinamikus struktúra tömb 2 int main() int i; struct szemely **emberek; emberek = (struct szemely **)calloc(10, sizeof(struct emberek *)); for(i = 0; i < 10; i++) emberek[i] = (struct szemely *)calloc(1, sizeof(struct emberek)); } strcpy(emberek[0]->nev, Kovacs Istvan ); emberek[0]->kora = 10;... 39
Típus definíció Új típus is definiálható typedef regi_tipus uj_tipus; A típusdefiníció különösen hasznos akkor, ha többféle struktúrát használunka programunkban. Szemléletesebb és könnyebb megérteni egy struktúra típus nevet, vagy egypointer típus-nevet mint egy bonyolult struktúra nevét, vagy egy arra mutató pointer nevét. A típusnév definíció használatának másik okaa gépfüggőség kivédése. Ha a programunkban gépfüggő adattípusokat használunk, akkor egy másik gépre történő áthelyezésnél elég csupán a typedef-eket módosítani. 40
Típus definíció typedef struct _szemely char nev[100]; int kora; char cim[100]; } /* eredeti típus */ szemely; int main() szemely en; en.kora = 18; /* hivatkozas egy struktura elemre */ strcpy(en.nev, Kovacs Istvan );... 41
Típus definíció typedef unsigned int BOOL; #define IGAZ 1 #define HAMIS 0 int main() BOOL logikai; logikai = IGAZ; if(logikai) printf( Igaz ); } 42
Elolvasni, megtanulni Kernighan-Ritchie: A C programozási nyelv 5. Fejezet, kivéve 5.10, 5.11, 5.12 6. Fejezet, kivéve 6.8, 6.9 Benkő Tiborné: Programozzunk C nyelven! Teljes 3.6. Fejezet 3.7. Fejezet, kivéve 3.7.6, 3.7.7 3.8.5, 3.8.6 Fejezet 43