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.