C++ programozás 11. – Függvények

Függvények, avagy a programozás igáslovai

A C++ készítői rengeteg dolgot megírtak helyettünk, amelyeket kezdő programozóként sokszor úgy használunk, hogy nem is tudatosul. Ezek végzik a munka nagyját, ők azok, akik a változókat kezelik, és a programunk esetleges különböző részei között a kapcsolatot tartják. A függvények olyan programrészletek, melyek esetleges bemenő adatok segítségével vagy egy eredményt állítanak elő, vagy valamilyen feladatot hajtanak végre, és nincs eredmény. A bemenő adatok sem kötelezőek, lehet, hogy a függvény valamilyen előre meghatározott módon állít elő egy értéket. Fontos, hogy ez a fejezet egyelőre csak az előre megírt és az általunk megírt függvényekkel foglalkozik.

Függvények szignatúrája

A függvényeket tekinthetjük egyfajta üzeneteknek, melyek valamilyen feladat megoldását kérik valakitől. Választ nem minden esetben kapunk a teljesítésről, egyszerűen csak történik valami.

Ha a függvényeket üzenetnek tekintjük, akkor 3 részből állhatnak.

  1. Címzett – A címzett nem kötelező. Csak abban az esetben kell megadni, ha konkrétan valamilyen objektumot szeretnénk megszólítani, és valamilyen feladat végrehajtására kérjük meg. Ebben a fejezetben ennek nem lesz jelentősége.
  2. Függvény neve – A függvény neve kötelezően megadandó, hiszen meg kell mondani, hogy mit akarunk végrehajtani.
  3. Paraméterek – A függvénynek átadandó paraméterek nem kötelezőek. Lehet, hogy megadott adatok nélkül is végrehajtható a feladat.

Anélkül, hogy egy konkrét függvény megvalósítást látnánk, nézzük meg a függvények használatához szükséges legfontosabb fogalmat, a szignatúrát:

visszatérési_érték függvény_neve( paraméter1, paraméter2, ... );

A függvényünk, mint a bevezetőben említettem, vagy eredményt állít elő, vagy feladatot hajt végre eredmény nélkül. Ha a függvény mondjuk egy szám négyzetét adja eredményül, akkor egy szám lesz az eredmény. Ha azonban kiír valamit a képernyőre, akkor nincs eredmény, csak végrehajtja a feladatot. Utóbbi esetben a függvény visszatérési értékének típusa void lesz. Míg mondjuk négyzet esetén ha egész számnak számítjuk ki a négyzetét, akkor az eredmény típusa mondjuk int lesz.

A függvény neve általában valami tömör megfogalmazása annak, hogy az adott függvény mit is csinál. Mondjuk ha írnánk egy függvényt, ami a kapott számot négyzetre emeli, akkor lehetne negyzet a függvényünk neve. A függvény neve állhat több szóból is, ilyenkor az egyes szavakat _ jellel szokás elválasztani. A névben csak kisbetűket szokás használni, és esetleg számok is szerepelhetnek benne, de semmiképp nem a név elején. A név egyedi kell hogy legyen, de ehhez lejjebb még kiegészítést teszek.

A zárójelen belül a függvény bemenő adatai szerepelnek, amelyek a feladat végrehajtásához kellenek. A szignatúrában kizárólag a bemenő adatok típusai szerepelnek, egymástól vesszővel elválasztva, sorrendben felsorolva. Ha mondjuk egy függvény egy egész szám tetszőleges többszörösét állítja elő, akkor a függvényünk szignatúrája a következőképp néz ki:

int tobbszoros( int, int );

Ez azt jelenti, hogy a tobbszoros nevű függvényünk két egész számot vár paraméterként, és egy egész számot ad majd eredményül. De honnan fogjuk tudni, hogy először a számot és utána a szorzót kell megadni, vagy épp fordítva? A szignatúrából sehogy. Ez dokumentációs kérdés, hogy szerepeltessem a függvény általam megírt magyarázatában: először a számot, aztán a szorzót kell megadni vesszővel elválasztva a függvény helyes használatához.

Összefoglalva tehát, a szignatúra a függvény használatához nyújt tömör segédletet, rögzíti, hogy milyen típusú bemeneti paramétereket vár, és milyen típusú eredményt ad. Azt nem tudhatjuk meg belőle, hogy a paramétereknél melyik típusú bemenet konkrétan mit jelent, csak a típushelyességet biztosítja.

Függvény használata

És akkor hogy néz ki egy függvény konkrét használata? Maradva az előzőleg ismertetett szignatúrájú tobbszoros nevű függvénynél lássuk a következő példát:

tobbszoros( 3, 5 );

Ez a függvényhívás a 3 szám többszörösét állítja elő egész számként úgy, hogy a szorzó 5 lesz. Az eredmény, vagyis ez az egész kifejezés értéke a 15-ös számot fogja jelenteni bárhol, ahol ezt szerepeltetjük. Természetesen ezt a függvényt, ahogy a fenti példában látható, nincs sok értelme használni, hiszen semmit nem kezdek az eredménnyel, csak úgy lóg a levegőben. Ha ezt egy változóban eltárolom későbbi használatra, vagy kiírom a képernyőre, az már valóban hasznos tevékenység.

Fontos, hogy ez a tobbszoros nevű függvény, amit megírtunk, a programunkkal azonos nevű névtérben legyen, vagy ha más névtérbe helyeztük el, akkor a névteret a using kulcsszó használatával elérhetővé kell tenni, különben a függvényt így nem érhetjük el. A névterekről amennyire szükségünk van, az alapok című leckében írtam.

Beépített függvények

A C++ nyelv több olyan függvényt is tartalmaz, mely valamilyen előre megadott alapfeladatot old meg. Ezeket természetesen mi is megírhatnánk, de ezekben az esetekben a nyelv készítői segítettek nekünk egy kicsit.

Ha a Code::Blocks-ot elindítod, és egy project-et hozol létre, akkor azonnal készít egy alap kódot, melyben az std névteret elérhetővé teszi a using kulcsszóval. Ettől a ponttól kezdve működnek a cin és cout objektumok, valamint két alapfüggvény is elérhető lesz. Megjegyzésbe odaírtam, hogy mi a függvények eredménye. Szándékosan nem írtam típust. A követelmény annyi, hogy a két számnak azonos típusúnak kell lennie. Vagyis vagy két int, vagy két double típust adhatok meg, és az eredmény típusa a két paraméter értékének megfelelő lesz.

min( szam1, szam2 ); // a két szám közül a kisebb értéke
max( szam1, szam2 ); // a két szám közül a nagyobb értéke

A többi beépített függvény, melyek jellemzően matematikai jellegű függvények, valamint kerekítő függvények, nem érhetőek el ilyen egyszerűen. Ezek úgynevezett header fájlokban vannak megírva, és ezeket kell beemelni a kódunkba. A következőkben felsorolt függvények mindegyike a cmath nevű header-ben találhatóak. Ahhoz, hogy ezeket használni lehessen, a kódunk elején a következő sort kell megadni, lehetőleg az esetleges using-ok előtt.

#include <cmath>

Ettől kezdődően a következő függvényeket érhetjük el:

abs(-5);
sqrt(2);
pow(2,4);
round(12.345);
ceil(12.345);
floor(12.789);
trunc(12.789);
trunc(-3.345);
  1. -5 abszolút értéke
  2. 2 négyzetgyöke
  3. 2 a 4. hatványon
  4. 12.345 kerekítése a közelebbi egészre matematikai szabályok szerint
  5. 12.345 kerekítése a tőle nagyobb egészre
  6. 12.345 kerekítése a tőle kisebb egészre
  7. 12.789 tizedesjegyeinek levágása
  8. -3.345 tizedesjegyeinek levágása

Hasonlóan beépített függvényekkel dolgozik a véletlen szám sorsolás is, de erről a hivatkozott későbbi leckében bővebben írok.

Úgy gondolom, indulásként ennyi beépített függvény ismertetése bőven elegendő, az egyes leckéknél úgyis ismertetem azokat, melyek ahhoz a témakörhöz feltétlenül szükségesek.

Túlterhelés

Fent említettem, hogy a függvény neve egyedi kell, hogy legyen. Ezek szerint ha írtam egy függvényt és lefoglaltam egy nevet, akkor azt máshol már soha nem használhatom? Másik programban természetesen igen, de még azonos programban is lehet használni akár többször is. Az egyediség valójában nem a névre vonatkozik, hanem a szignatúrára. Ez azt jelenti, hogy létezhet ugyanabban a programban ugyanazon névtérben két azonos nevű program, de csak abban az esetben, ha a szignatúrájuk különbözik. Nézzük, hogy néz ki ez technikailag.

Szeretnénk ezt a tobbszoros nevű függvényt úgy is használhatóvá tenni, hogy nem kell megadni a szorzót. Ez azt jelentené, hogy ha nem adunk meg szorzót, akkor automatikusan a szám dupláját adja meg, ha pedig megadjuk a szorzót, akkor az annak megfelelő eredményt adja. Ezt a következőképp tehetjük meg:

int tobbszoros( int );
int tobbszoros( int, int );

Itt két azonos nevű, de különböző szignatúrájú függvényt láthatsz. Az elsőnél a megadott szám duplája lesz az eredmény, a másodiknál az első szám másodikként megadott többszörösét adja. Ez természetesen szintén csak a dokumentációból, vagy megjegyzésekből derülhetne ki, mivel a szignatúra csak a paraméterezést és a visszatérési értéket rögzíti. A két függvényt külön kell megírni, és a függvényhívás módja adja meg, hogy melyiket szeretnénk használni:

tobbszoros( 3, 5 );
tobbszoros( 6 );
tobbszoros( 6, 2 );

A fenti példákból egyértelmű lesz, hogy hogyan is kell ezeket használni.

  1. A 3 ötszörösét állítja elő.
  2. A 6 dupláját állítja elő.
  3. A 6 dupláját állítja elő, de itt azt a függvényt használja, amelyik két paramétert vár. A végeredmény az előző sorral megegyező.

A túlterhelésről és a saját magunk által megírt függvényekről egy későbbi leckében írok majd részletesebben, addig csak a beépítetteket használjuk.

Következő lecke: Véletlen számok

Vélemény, hozzászólás?

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük

*

Ez az oldal az Akismet szolgáltatást használja a spam csökkentésére. Ismerje meg a hozzászólás adatainak feldolgozását .