HIK Elektronikus Felsőoktatási Tankönyv- és Szakkönyvtár
A Kempelen Farkas Felsőoktatási Digitális Tankönyvtár/vagy más megjelenítő által közvetített digitális tartalmat a felhasználó a szerzői jogról szóló 1999. évi LXXVI. tv. 33. paragrafus (4) bekezdésében meghatározott oktatási, illetve tudományos kutatási célra használhatja fel. A felhasználó a digitális tartalmat képernyőn megjelenítheti, letöltheti, arról elektronikus adathordozóra vagy papíralapon másolatot készíthet, adatrögzítő rendszerében tárolhatja. A Kempelen Farkas Felsőoktatási Digitális Tankönyvtár/vagy más megjelenítő weblapján található digitális tartalmak üzletszerû felhasználása tilos, valamint kizárt a digitális tartalom módosítása és átdolgozása, illetve az ilyen módon keletkezett származékos anyag további felhasználása.

14. Eljárások és függvények középfokon

Hernyák Zoltán

Amikor eljárást (vagy függvényt) írunk, az alprogram törzsében sokszor hivatkozunk ilyen megosztott (közös) változókra. E változókban az eljárás a program előző részei által előállított adatokat kap meg, vagyis bemenő adatokat fogad. Az eljárás ezen adatok segítségével újabb értékeket állíthat elő, melyeket elhelyezhet megosztott változókban, ahol a többi eljárás megtalálhatja őket. Így állít elő az eljárás kimenő adatokat.

Bemenő adatokat az eljárás azonban nem csak a megosztott változókban vehet át, hanem paraméterekben is.

A paramétereket az eljárás fejrészében kell feltüntetni. Fel kell sorolni vesszővel elválasztva a bemenő adatok típusát, és egy azonosítót (nevet) kell adni ezen adatoknak. Ezt a listát formális paraméterlistának hívjuk.

Pl:

static void Kiiras(int a,int b)

{

Console.WriteLine("A {0}+{1}={2}",a,b,a+b);

}

A fenti példában ezen eljárás két bemenő értéket vár. Mindkettő ’int’ típusú, vagyis egész számok. Az eljárás törzsében a paraméterekre a formális paraméterlistában feltüntetett azonosítókkal (név) hivatkozhatunk. A fenti eljárás kiírja a két számot a képernyőre, majd a két szám összegét is.

Amikor ezen eljárást meg akarjuk hívni, akkor ezen eljárásnak a fenti bemenő adatokat át kell adni. A hívás helyén feltüntetett paraméterlistát (mely az aktuális bemenő adatok értékét tartalmazza) aktuális paraméterlistának hívjuk. Aktuális paraméterlistában már sosem írunk típusokat, hanem konkrét értékeket!

Kiiras(12,15);

A fenti kódrészlet elindítja a Kiiras eljárást, átadván neki a két bemenő adatot. Az eljárás elindulása előtt feltölti a paraméterváltozókat az aktuális értékekkel (a=12, b=15), majd utána kezdődik az eljárástörzs utasításainak végrehajtása.

Bizonyos szempontból nézve a formális paraméterlista egyúttal változó-deklarációnak is minősül, hiszen a formális paraméterlistában lényegében típusok és nevek vannak megadva. Az eljárás törzsében ezekre a paraméterekre mint adott típusú változókra hivatkozhatunk. Ezen változók kezdőértékkel rendelkeznek, a kezdőértékeket az aktuális paraméterlistában adjuk meg.

Ennek megfelelően az aktuális és a formális paraméterlistára szigorú szabályok vonatkoznak:

  • az aktuális paraméterlistában pontosan annyi értéket kell felsorolni, amennyit a formális paraméterlista alapján az eljárás vár tőlünk,

  • az aktuális paraméterlistában pontosan olyan típusú értékeket kell rendre megadni, mint amilyet a formális paraméterlista szerint az adott helyen fel kell tüntetni.

Hibásak az alábbiak:

Kiiras(12.5,15); // 12.5 nem ’int’ !

Kiiras(12);// túl kevés paraméter

Kiiras(12,15,20); // túl sok paraméter

Kiiras(”Hello”,20); // a ”Hello” nem ’int’ típusú

Helyesek az alábbiak:

Kiiras(12,15);

Kiiras(3*4,15*3-12);

int x=8; Kiiras(x,x+2);

Megállapíthatjuk, hogy az aktuális paraméterlistában olyan értéket kell írnunk, amelynek a végeredménye jelen esetben ’int’ típusú. A hívás helyére írhatunk számkonstanst (literál), kifejezést – melynek kiszámítása int-et eredményez, illetve változót is (ekkor a változó aktuális értékét adjuk át).

A konstans (literál) és a változó is kifejezésnek minősül, csak egyszerű kifejezés. Ezért általánosan azt mondhatjuk, hogy az aktuális paraméterlistában olyan kifejezést kell írnunk, melynek típusa megfelel a formális paraméterlistában leírt követelményeknek. Ezt a típus-megfelelőséget a kompatibilis típusok szabályai írják le. Az OO nyelvekben a típuskompatibilitást is az OO szabályai írják le. Egyelőre annyit jegyezzünk meg, hogy az ’int’ kompatibilis a ’double’-val, az ’int’-ek (sbyte, uint, int, …) kompatibilisek egymással, csakúgy mint a double típusok is (double, float), persze ha az aktuális érték a kívánt típusban az adott pillanatban elfér.

Pl:

static void Kiiras(double a)

{

Console.WriteLine("A szám fele={0}",a/2);

}

Ezen eljárás egy tetszőleges racionális számot vár, majd kiírja az adott szám felét.

Kiiras(12);

Ebben az esetben az aktuális paraméterlistában nem egy tört, hanem egy egész számot adtunk át. Ez ugyan nem pontosan ugyanolyan típusú, mint amit a formális paraméterlistában leírtunk, de az aktuális érték (12) konvertálható (kompatibilis) a kért típusra.

int x=12; Kiiras(x);

Ezen példa szerint is az aktuális érték egy ’int’ típusú érték, de ez elfogadható, ha a fogadó oldalon akár ’double’-t is képesek vagyunk fogadni.

Fordítva nem igaz:

static void Kiiras_Egesz(int a)

{

Console.WriteLine("A szám kétszeres={0}",a*2);

}

double z=12.5; Kiiras_Egesz (z);

Értelemszerűen a küldő oldal (aktuális paraméterlista) hiába próbálná átadni a 12.5 értéket, a fogadó oldal (formális paraméterlista) csak egész típusú értéket tud átvenni. Ezért ezt a paraméterátadást a C# fordító nem engedi, még akkor sem, ha …

double z=12; Kiiras_Egesz (z);

Ekkor hiába van a ’z’ változóban olyan érték, amelyet a fogadó oldal akár át is tudna venni, ez általános esetben nem biztonságos. A hívás helyére olyan típusú kifejezést kell írnunk, amely ennél több garanciát ad. Ezért nem engedi meg a C# fordító, hogy a típusok ennyire eltérjenek egymástól.

Ennél persze bonyolultabb típusok is szerepelhetnek a formális paraméterlistában:

static void Kiiras(int[] tomb)

{

Console.Write("A tomb elemei: ");

for(int i=0;i<tomb.Length;i++)

Console.Write("{0}, ",tomb[i]);

Console.WriteLine();

}

A fenti példában a ’Kiiras’ eljárás egy komplett tömböt vár paraméterként. A tömb elemei ’int’ típusú értékek kell hogy legyenek. A hívás helyére ekkor természetesen egy ennek megfelelő értéket kell írni:

int[] x = new int[10];

Kiiras( x );

Itt az ’x’ változó típusa ’int[]’, ami megfelel a fogadó oldali elvárásoknak, ezért a fenti eljáráshívás típusában megfelelő, így helyes is.