Programozás alapjai C nyelv 7. gyakorlat Szeberényi Imre BME IIT <szebi@iit.bme.hu> Függvények C program egymás mellé rendelt függvényekből áll. A függvény (alprogram) jó absztrakciós eszköz a programok tervezésénél. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -1- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -2- Függvények(2) Függvények által használt / előállított adatokat a függvény interfészén keresztül adjuk át. A C nyelvben csak érték szerinti paraméterátadás van. LNKO függvény Feladat: Írjunk függvényt két egész szám legnagyobb közös osztójának kiszámítására Be: 2 db egész Ki: 1 db egész Algoritmus: euklideszi algoritmus Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -3- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -4- LNKO függvény (2) Függvény deklaráció v. prototípus: int lnko(int x, int y); Algoritmus: while x!= y nagyobb számból kivonjuk a kisebbet LNKO függvény (3) Függvény definíció: int lnko(int x, int y) while (x!= y) if (x > y) x -= y; else y -= x; return(x); Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -5- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -6-
LNKO fájl végéig Feladat: Fájl végéig, olvassunk be számpárokat, és határozzuk meg a legnagyobb közös osztójukat! Vázlat: while olvas(x, y) kiír lnko(x, y) Külön tesztelhető, újból felhasználható Funkcionális dekompozíció Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -7- LNKO fájl végéig (2) #include <stdio.h> Feltételezzük, hogy az input sorozat helyes (csak int lnko(x, y); számpárokat tartalmaz) int main() int x, y; while (scanf( %d %d,&x, &y)!= EOF) printf( LNKO(%d,%d)=%d\n, x, y, lnko(x, y)); return(0); Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -8- C program szerkezete újból Egymás mellé rendelt ún. külső objektumokból (függvény és változó) áll. Külső - nem függvény belsejében Belső - függvények belsejében A függvények paramétereken, függvényértékeken, vagy külső adatokon keresztül kommunikálhatnak egymással. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -9- C program szerkezete újból (2) Külső objektum int alma; Paraméter int lnko(int x, int y) Lokális változó int i = 3; while (x!= y) if (x > y) x -= y; else y -= x; alma = 23; return x; main() Függvényérték Akt. paraméter int x = 8, i = 24; printf( %d %d\n, alma, lnko(x, i)); Mi az objektumok érvényessége? (alma, x, i, y, lnko, main) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -10- Érvényességi tartomány Lexikális érvényességi tartomány. (Programszöveg azon része, ahol az azonosító ismert és tulajdonságai meghatározottak.) külső: a fordítási egység végéig blokk: a blokk végéig különböző névterek vannak (függvények, typedef, cimkék, felsorolások, struktúrák stb.) Külső csatolású objektumok érvényességi tartománya. (A fordítási egységek közötti kapcsolatot határozza meg.) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -11- Lexikális érvényességi tartomány Ford. egységben int alma; Blokkban int lnko(int x, int y) Nem ua. a változó! int i = 3; while (x!= y) if (x > y) x -= y; else y -= x; i = alma; return x; main() Ua. a változó! int x = 8, i = 24; printf( %d %d\n, alma, lnko(x, i)); Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -12-
C program szerkezete újból (3) Különböző fordítási egységek lehetnek. Az egyes fordítási egységek közötti kapcsolatot interfész definíciók teremtik meg, melyeket ún. header állományokban szokás megadni. (Nem kötelező, de...) C program szerkezete újból (4) #include rendez.h main ()...Kiir(t, n); void Kiir(int a[],int n); beszurte.c (főprogram, rendező és kiíró függvények használata) rendez.h (interfész definíciók, konstansok) #include rendez.h void Kiir(int a[],int n)... rendez.c (rendező és kiíró függvények megvalósítása) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -13- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -14- Függvényparaméterek Definíció ill. felhasználás szintjén formális pl: int Kiir(int a[], int n); aktuális pl: Kiir(t, 23); void Kiir(int a[], int n) int i; for (i = 0; i < n; i++) printf("%5d", a[i]); n = 0; Meg is változtathatjuk A formális paraméterre úgy hivatkozhatunk, mint egy változóra. Átadhatjuk egy másik függvénynek aktuális paraméterként. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -15- Függvényparaméterek (2) Információátadás szintjén érték (csak befelé) változó (be és ki) C nyelvben csak értékparaméter van. Mégis hogyan működik a BeszuroBinker vagy pl. a scanf? Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -16- változó v. konstans érték függvény fv.érték Értékparaméter A paraméterek nem változhatnak meg, mivel azok értéke adódik át. Azok eredeti tartalma az eredeti helyen megmarad. A függvény csak a függvényértéken keresztül tud a külvilágnak eredményt szolgáltatni. (Ez sokszor kevés.) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -17- változó fv.érték cím függvény Változóparaméter A paraméter címe adódik át, így annak tartalma felhasználható, de meg is változtatható. A magas szintű nyelvek elfedik ezt a trükköt. Sem az aktuális paraméterek átadásakor, sem a formális paraméterekre való hivatkozáskor nem kell jelölni. Csupán a paraméter jellegét (változó) kell megadni a definíciókor. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -18-
Változóparaméter a C-ben void KozKi(int a[], int n) int i, j, x; for (i = 1; i < n; i++) k = i; x = a[i]; for (j = i+1; j<= n; j++) if (a[j] < x) k = j; x = a[j]; a[k] = a[i]; a[i] = x; C nyelvben a tömb átadásától eltekintve jelölni kell a cím átadását és használatát (az indirekciót). Ebben a formában a tömb átadása változóparaméter átadásának fogható fel. A tömb címe adódik át és nem maga a tömb! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -19- Változóparaméter helyett cím int add(int a, int b, int *ab2) *ab2 = a * a + b * b; return (a + b); Címet várunk main() int x, y; Indirekció y = add(2, 3, &x); y = add(2, 3, x); Változó címét adjuk át Változó értékét adjuk át, ami egy integer!! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -20- Változóparaméter helyett cím (2) void KozKi(int *a, int n) int i, j, x; for (i = 1; i < n; i++) k = i; x = a[i]; for (j = i+1; j<= n; j++) if (a[j] < x) k = j; x = a[j]; a[k] = a[i]; a[i] = x; Címet várunk Ez is indirekció Összetartozó adatok tárolása A tömbök segítségével azonos típusú adatokat tudunk kezelni. Ezek többnyire nem tartoznak össze. Gyakran előfordul, hogy az adatok összetartozása a fontos, és ezért együtt szeretnénk kezelni azokat. Ezek lehetnek azonos típusúak pl: pontok koordinátai, komplex számok stb eltérő típusúak pl: személyi adatok, számlák adatai stb. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -21- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -22- struct float re, im; k1, k2, k3[12]; struct hallgato char nev[40]; int tk; float odij; h1, h2, h3[10]; Struktúra Összetartozó adatok tárolására alkalmas összetett adattípus. struktúra_spec: struct struct_tip_azon opc dekl_lista k1.re = 1.3; k3[0]= k2; k3[1].im = 0; struct hallgato h4; h1.tk = 8; h2.nev[0] == A ; h3[1] = h4; Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -23- Struktúra (2) Értékkészlet - tagok értékkészletéből Konstansok - tagok konstansaiból Művelethalmaz értékadás szelekció (hivatkozás egy str. tagra) átadhatjuk fv. paraméterként hivatkozhatunk a címére más művelete nincs!!! Lehet struct típusú függvény! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -24-
Változók kezdeti értéke Külső és statikus változók garantáltan nulla kezdeti értéket kapnak, ha nincs explicit inicializálás. Explicit inicializálás hiányában az automatikus és regiszter típusú változók kezdeti értéke meghatározatlan. Változók kezdeti értéke (2) A változók a definíciójukkal együtt inicializálhatók. (int i = 23) Külső és statikus változóknak csak konstans kezdeti érték adható és csak egyszer kapnak értéket a program kezdete előtt. Automatikus és regiszter változók nem csak konstans értékkel inicializálhatók. (int j = a) Struktúra ill. tömb jellegű változók ún. agregátummal inicializálhatók. ( ) Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -25- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -26- Változók kezdeti értéke (3) Összetett adatszerkezetek esetén ún. adatelemkijelölőket lehet használni a megfelelő elem kiválasztásához. Pl: struct komplex_str Borland C float re, im; nem ismeri! kt[100] = [12].im = 8.2, [23] = 3., 2.1 ; struct komplex_str k =.im = 8.1 ; Rendezzük sorba: 9, 2, 5, 3, -12 Beszúró rendezett halmazt bővítjük Közvetlen csere buborék Közvetlen kiválasztás legkisebbet v. legnagyobbat kiválasztjuk a maradékból Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -27- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -28- Beszúró rendezés Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: a[i] beszúrása az a[1] a[i-1] halmazba A már rendezett halmazba beszúrjuk a következő elemet: a[i] beszúrása az a[1] a[i-1] halmazba 9 2 5 3-12 2 9 5 3-12 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -29- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -30-
Beszúró rendezés Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: a[i] beszúrása az a[1] a[i-1] halmazba A már rendezett halmazba beszúrjuk a következő elemet: a[i] beszúrása az a[1] a[i-1] halmazba i=4 2 5 9 3-12 i=5 2 3 5 9-12 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -31- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -32- Beszúró rendezés A már rendezett halmazba beszúrjuk a következő elemet: a[i] beszúrása az a[1] a[i-1] halmazba -12 2 3 5 9 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -33- Beszúró rendezés for (i = 2; i <= n; i++) x = a[i]; j = i-1; while (j > 0 && a[j] > x) a[j+1] = a[j]; j--; a[j+1] = x; kiértékelés sorrendje 2 5 9 3-12 A 0. elemet nem használjuk, ezért eggyel több elemet kell foglalnunk! C sajátosság, hogy az index mindig 0-tól megy!!! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -34- Beszúró r. strázsa elemmel Beszúró r. strázsa elemmel (2) for (i = 2; i <= n; i++) a[0] = a[i]; j = i-1; while (a[j] > a[0]) a[j+1] = a[j]; j--; a[j+1] = a[0]; feltétel egyszerűsödött for (i = 2; i <= n; i++) for (a[0] = a[i], j = i-1; a[j] > a[0]; j--) a[j+1] = a[j]; a[j+1] = a[0]; vessző operátor -12 25 3-12 92 95 32 95 3 39 5-12 9 logikailag a ciklushoz tartozik a kezdeti beállítás 0. Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -35- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -36-
Beszúró r. bináris kereséssel Beszúró r. bináris kereséssel (2) for (i = 2; i <= n; i++) x = a[i]; l = 1; r = i-1; while (l <= r) m = (l+r) / 2; már if (x < a[m]) r = m-1; rendezett else l = m+1; for (j = i-1; j >= l; j--) a[j+1] = a[j]; a[l] = x; 2 3 5 9-12 for (i = 1; i < n; i++) x = a[i]; l = 0; r = i-1; while (l <= r) m = (l+r) / 2; if (x < a[m]) r = m-1; else l = m+1; for (j = i-1; j >= l; j--) a[j+1] = a[j]; a[l] = x; A 0. elemet is használjuk! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -37- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -38- Közvetlen kiválasztás Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel i=1 k=5 9 2 5 3-12 k=2-12 2 5 3 9 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -39- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -40- Közvetlen kiválasztás Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel k=4-12 2 5 3 9 i=4 k=4-12 2 3 5 9 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -41- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -42-
Közvetlen kiválasztás for i = 1 to n-1 k = legkisebb_elem_indexe(i,n) a[k] cseréje a[i]-vel -12 2 3 5 9 Közvetlen kiválasztás for (i = 1; i <= n-1; i++) k = i; x = a[i]; for (j = i+1; j <= n; j++) if (a[j] < x) k = j; x = a[j]; a[k] = a[i]; a[i] = x; k=4-12 2 5 3 9 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -43- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -44- j=5 9 2 5 3-12 j=4 9 2 5-12 3 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -45- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -46- j=3 9 2-12 5 3 j=2 9-12 2 5 3 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -47- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -48-
j=5-12 9 2 5 3 j=4-12 9 2 3 5 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -49- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -50- j=3-12 9 2 3 5 i=4 j=5-12 2 9 3 5 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -51- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -52- i=4 j=4-12 2 9 3 5 i=5 j=5-12 2 3 9 5 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -53- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -54-
for (i = 2; i <= n; i++) for (j = n; j >= i; j--) if (a[j-1] > a[j]) x = a[j-1]; a[j-1] = a[j]; a[j] = x -12 2 3 5 9 j=3 9 2-12 5 3 Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -55- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -56- Közvetlen csere (javított) Közvetlen csere (javított) (2) i = 2; do cserelt = 0; for (j = n; j >= i; j--) if (a[j-1] > a[j]) x = a[j-1]; a[j-1] = a[j]; a[j] = x cserelt = 1; i = i + 1; while (i <= n) && cserelt; logikai változó! i = 1; do cserelt = 0; for (j = n-1; j >= i; j--) if (a[j-1] > a[j]) x = a[j-1]; a[j-1] = a[j]; a[j] = x cserelt = 1; i = i + 1; while (i < n) && cserelt; A 0. elemet is használjuk! Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -57- Programozás alapjai I. (C nyelv, gyakorlat) BME-IIT Sz.I. 2005.11.05. -58-