Programozás I. 3.1. Függvények általános jellemzői Rendszer és Szoftvertechnológia Tanszék
3.1. Függvények általános jellemzői Problémaosztályok előadáson elhangzottakat átnézni ! Eljárás, szubrutin: meghatározott tevékenységsorozat végrehajtását jelenti. Függvény: Olyan szubrutin, amely meghatározott tevékenységsorozat végrehajtását jelenti, melynek eredményeként a függvény egy értéket állít elő és ad vissza a hívási pontra. A C-ben és a C++-ban a programok építőkövei a függvények. Példa: y = sin (x) + cos (x); z = sqrt (y); Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
3.1. Függvények általános jellemzői A függvények általános alakja: visszatérési_típus függvénynév (paraméterlista) { függvénytörzs } Visszatérési típus: visszatérési érték típusa. (Alapért.: egész típus) Függvénynév: az egyszerű változó nevével kapcs. szabályokat ... Paraméterlista: azon – típussal és névvel megadott – változók felsorolása (vesszővel elválasztva), amelyekkel az átadott paraméterekre hivatkozhatunk a függvényen belül. Ha nincs paraméter: void (C-ben kötelező) Függvénytörzs: deklarációk, utasítások Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
3.1. Függvények általános jellemzői A függvényen belül a végrehajtás végét az utolsó zárójel jelenti, ekkor a hívó eljárás visszakapja a vezérlést. Ennél korábbi visszatérést a return utasítással kényszeríthetünk ki. Egy nem void-ként deklarált függvény visszatérési értékként a return utasítás mögött álló kifejezés értékét kapja meg. Egy függvényen belül tetszőleges számú return utasítás elhelyezhető. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.1. feladat Készítsen egy olyan függvényt, amely valamilyen üdvözlő szöveget ír ki a képernyőre, véletlenszerűen választva 5 letárolt üzenetből. Hívja meg a függvényt háromszor egymás után. void koszon (void); // A koszon fgv.prototípusa void main (void) { int i; randomize (); for (i=1; i<4; i++) koszon (); //a fv hívása getch(); } Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.1. feladat Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.2. feladat Készítsen egy olyan függvényt, amely adott sorszámú üzenetet ír ki a képernyőre. Hívja meg a függvényt ötször, öt különböző sorszámú üzenet kiírásához. Megoldás: A függvénynek egy paramétere van, a kiírandó üzenet sorszáma, visszatérési értéke 0, ha nincs az átadott paraméternek megfelelő üzenet és 1, ha az üzenet kiírása sikeres volt. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.2. feladat #include <stdio.h> #include <conio.h> int uzen (int); // Az uzen függv. prototípusa void main (void) { int i, ok; clrscr (); //meghívjuk az uzen függvényt hatszor for (i=1; i<7; i++) ok = uzen (i); //Az uzen függvény hívása printf (" ** %2d **", ok); } Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.2. feladat int uzen (int sorszam) //Az uzen fv definíciója { switch (sorszam) case 1: printf("\nElső üzenet"); return 1; case 2: printf("\nMásodik üzenet"); return 1; case 3: printf("\nHarmadik üzenet"); return 1; case 4: printf("\nNegyedik üzenet"); return 1; case 5: printf("\nÖtödik üzenet"); return 1; default: return 0; } Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
3.1. Függvények általános jellemzői A függvényen belül a végrehajtás végét az utolsó zárójel jelenti, ekkor a hívó eljárás visszakapja a vezérlést. Ennél korábbi visszatérést a return utasítással kényszeríthetünk ki. Egy nem void-ként deklarált függvény visszatérési értékként a return utasítás mögött álló kifejezés értékét kapja meg. Egy függvényen belül tetszőleges számú return utasítás elhelyezhető. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Függvények definíciója és deklarációja A saját függvényeinket mindig definiálni kell. A definíciót csak egyszer lehet megadni. A definíció C programon belül bárhol elhelyezkedhet, de ha a függvény hívás után helyezzük el (pl. a main függvény után), akkor kötelező a prototípus megadása a hívási pont előtt. Ha a definíció megelőzi a hívás (felhasználás) helyét, akkor ez egyben a függvény deklarációja is. Tilos a függvényeket egymásba ágyazni ! Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Függvények definíciója Általános alak: Visszatérési érték típusa függvénynév (f. param. l.) /* Függvényfej, melyet nem zár le pontosvessző ! */ { /* A függvény törzse */ lokális definíciók és deklarációk utasítások } Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Függvények prototípusa Általános alak: Visszatérési érték típusa függvénynév (formális paraméterek típusainak felsorolása); C++-ban csak a prototípus használható. (Könyvtári függvények: prototípus az include állományokban …) Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Függvények prototípusa, példák float sum ( int , float ); fgvnév: sum paraméter: 2 db, int és float típusú vissz.ért.típus: float uj ( int, long ); fgvnév: uj paraméter: 2 db, int és long vissz.ért.típus: int ( default ) Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
A függvények paraméterei Függvény definíció, paraméterlista: minden paraméter előtt ott áll a paraméter típusa. FORMÁLIS PARAMÉTEREK: Példa: int uzen (int sorszam) { if (sorszam < 0) return 0; } A deklarált paraméterek a függvényen belül mint a függvény lokális változói használhatók, a függvényen kívülről azonban nem érhetők el. Prototípus: csak a típusok felsorolása, de a sorrend azonos kell legyen ! A deklarált paraméterek a függvényen belül mint a függvény lokális változói használhatók, a függvényen kívülről nem érhetők el. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
A függvényhívás menete A függvényhívás során a vezérlés átadódik a hívó függvénytől az aktivizált függvényhez. A paraméterek (ha vannak) szintén átadódnak a meghívott függvénynek. A már bemutatott return utasítás végrehajtásakor, vagy a függvénytörzs utolsó utasításának végrehajtása után a vezérlés visszakerül a hívás helyére. Ha a függvény típusa nem void, akkor kötelező a return utasítás használata, s ekkor a return utasításban szereplő kifejezés értéke, mint függvényérték (visszatérési érték) jelenik meg. A függvény hívásnál megadott paramétereket AKTUÁLIS PARAMÉTEReknek nevezzük. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
3.1. Függvények általános jellemzői Paraméter átadási módok: Érték szerinti Cím szerinti A gyakorlatokon csak az érték szerinti paraméterátadást használjuk. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Érték szerinti paraméterátadás -1 A formális paraméter számára lefoglalódik egy megfelelő méretű memóriaterület. A: 5 Az A aktuális paraméter értéke 5 Ide átmásolódik az aktuális paraméter értéke. Lehet kifejezés is az aktuális paraméter, ekkor a kifejezés értéke kerül másolásra. F: 5 Az F formális param., megfeleltetve az A akt. paraméternek A rutinban ezen a külön memóriaterületen dolgozunk a formális paraméter értékének módosításakor. A: 5 F: 5 módosítás F: 3 A rutin végén a formális paraméterek számára lefoglalt memóriaterület felszabadul. A: 5 F: 3 Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Érték szerinti paraméterátadás - 2 int szamol (int fparam) { fparam = fparam + 5; return fparam; } void main (void) int aparam = 10; printf (”\na fv. visszaadott értéke:%3d”, szamol (aparam)); printf (”\n aparam értéke: %5d”,aparam); Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Érték szerinti paraméterátadás - 3 A paraméter értéke a rutin szempontjából csak bemenő, input érték. A rutin során nem történhet olyan értékadás, amely az algoritmust az eljáráson kívül befolyásolja. Hátránya: a másolat egy új helyen kerül tárolásra. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Cím szerinti paraméterátadás - 1 Az aktuális paraméter címe rendelődik a formális paraméterhez. Nincs külön memóriafoglalás, ugyanaz a memóriaterülete az aktuális és a formális paraméternek. A rutinban módosítva a formális paraméter értékét, az aktuális paraméter értéke is megváltozik. A rutin végén a formális paraméter hozzárendelése a memóriaterülethez megszűnik. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Cím szerinti paraméterátadás - 2 A paraméter értéke a rutin szempontjából kimenő, output érték is lehet! A paraméternek a rutinban történő módosítása hatással van az algoritmusra a rutinon kívül. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Aktuális és formális paraméterek Az aktuális és a formális paraméterek megfeleltetése balról jobbra, a felsorolás sorrendjében történik. Az aktuális és a formális paramétereknek (típusban), sorrendben és darabszámban egyezniük kell. C-ben csak érték szerinti paraméterátadás van. A paraméterek cím szerint történő átadásáról nekünk kell gondoskodni. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.3. feladat Készítsen programot, amely bekér egy természetes számot, majd kiírja a faktoriálisát.A faktoriális meghatározására készítsünk függvényt! Írjunk egy billentyűre váró eljárást is! // n faktoriális számítása unsigned long fakt(int); void bill(void); void main(void) { int n; printf("Kérem n értekét!"); scanf("%d",&n); printf("\nA faktoriális értéke : %lu" , fakt(n)); bill(); } // main Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.3. feladat void bill() { //tetszőleges billentyű leütésére vár... gotoxy(1,24); printf("Bármely billentyűre tovább...."); getch(); } // bill Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.3. feladat unsigned long fakt(int n) { //paraméter: egész szám //visszatérési érték: a szám faktoriálisa int i ; unsigned long f=1; for (i=1 ; i<=n ; i++) f *= i; return f; } // fakt Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
A main függvény paraméterei és visszatérési értéke A C programon belül a main függvénynek kitüntetett szerepe van, mivel kijelöli a program belépési pontját. A main függvénynek nulla, egy vagy két paramétere is lehet. (ld. Szakirodalom). A main visszatérési értékét, mely általában int típusú, a main függvényen belüli return utasításban, vagy a program tetszőleges pontján az exit könyvtári függvény argumentumában adhatjuk meg. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Változók érvényességi köre A függvények alkalmazása felveti azt a kérdést, hogy egy adott változó milyen érvényességi körrel (láthatósággal) rendelkezik. Globális változók: a függvényeken kívül deklaráljuk, többnyire a main előtt. Ezek a változók a teljes program futása alatt fennmaradnak és a program valamennyi függvényében “láthatók”. Lokális változók: egy adott függvényben deklaráljuk, tehát a függvény hívásakor “keletkeznek” és a függvényből való kilépéskor “megszűnnek”. Ezek a változók csak az adott függvényen belül “láthatók”. Lehetőleg kerülni kell a globális változók használatát ! Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Címszerinti paraméterátadás a C-ben A függvény meghívásakor az aktuális paraméterlistában a megfelelő változó címét kell elhelyezni az & címoperátort használva. A formális paraméterlistában a megfelelő típusra mutató pointert kell deklarálni. A függvénytörzsben az indirekció * operátorát használva hivatkozunk a változóra. ( Használjuk az ökölszabályt! ) Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Címszerinti paraméterátadás a C-ben 3.1.5. feladat Beolvasunk két egész számot. A CSEREL eljárás segítségével felcseréljük a két változó tartalmát, majd kiírjuk őket. void main(void) { int a,b; void cserel(int *,int *); //cserel prototípusa printf("\nKérem a két számot"); scanf("%d%d",&a,&b); cserel(&a,&b); //cserel hívása printf("\n\nMegcserélve %d - %d",a,b); getch(); } // main Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
Címszerinti paraméterátadás a C-ben 3.1.5. feladat Beolvasunk két egész számot. A CSEREL eljárás segítségével felcseréljük a két változó tartalmát, majd kiírjuk őket. void cserel(int *x,int *y) //cserel definíciója { int s; s=*x; *x = *y; *y = s; } // cserel Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 3.1.8. feladat Készítsen programot, amely egy 2003-as dátumról (hónap, nap) megmondja, hogy az az évnek hányadik napja és milyen napra esik. 1. részfeladat: ellenőrzött adat bevitel: int típusú szám beolvasása, amely adott (h1, h2) határok közé esik. prototípus: int adatbe (int, int); 2. részfeladat: szökőév ellenőrzés fv. prototípus: int szokoev (evszam); a visszatérési érték = 1, ha szökőév, egyébként nulla 3. részfeladat: nap sorszáma éven belül fv. prototípus: int napsorszam (ho, nap); 4. részfeladat: fv. prototípus: void napnevek (sorszam, eltolas); Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék 1.6.7. Pointer operátorok A C nyelvben kiemelt szerepe van egy olyan speciális változónak, amely más objektumok címét tárolja, ez a mutató (pointer): Amikor deklaráljuk a mutatót, meg kell adnunk a nevét, és azt, hogy milyen típusú változóra fog mutatni. A C nyelvben két speciális egyoperandusú művelet van, melyeket a mutatókkal kapcsolatosan használunk. A "címe" (&) művelet eredménye az operandusként megadott memóriaobjektum címe: int a, *pa; pa = &a; A másik mutató operátor (*) az indirekt hivatkozás elvégzéséhez szükséges: *pa = *pa + 5; A *pa kifejezés a pa pointer által mutatott objektumot jelenti, a fenti példában az a változót. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék Pointer aritmetika A mutató léptetése a szomszédos elemre többféle módon is elvégezhető: int *p, *q, j; p = p + 1; p += 1; p++; ++p; Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék Pointer aritmetika Az előző elemre visszalépésre szintén többféle lehetőség van: p = p - 1; p -= 1; p--; --p; Két mutató különbsége valójában a két mutató között elhelyezkedő elemek számát jelenti: j = p - q; A léptető és az indirektség operátorok együttes alkalmazásához kellő óvatosság szükséges, mivel ez a két operátor azonos precedenciával rendelkezik. Pécs, 2003. PTE PMMFK Számítástechnika Tanszék
PTE PMMFK Számítástechnika Tanszék Pécs, 2003. PTE PMMFK Számítástechnika Tanszék