Navigation


RSS: tutorialok Jelenleg 1 vendég és 0 tag van az oldalon.

Függvények, eljárások

szerző: elodani
dátum: 2009-06-15
Kategóriák:
  Pascal/Alapok

Elérkeztünk a függvényekhez.
Szemben sok más nyelvvel a Pascalban megkülönböztetjük a visszatérési érték nélküli függvényeket (ezek az eljárások).
Természetesen a visszatérési értékkel rendelkezőket itt is függvénynek nevezzük.

Ugyan tudtunk nélkül de már használtunk függvényeket,alprogramokat, ugyanis a pascal már jó előre definiált nekünk ezekből párat. (pl a writeln(), readln(), sin(), cos()...).
Ebben a részben azt fogjuk megnézni, hogy hogyan lehet saját függvényeket/eljárásokat írni.

és most lássuk a medvét:

Szerintem kezdjük az eljárásokkal(alprogramok).
Ha valamit a programunkban többször szeretnénk végrehajtani, például beolvasni egy tömböt, változtatni rajta valamit, stb... akkor ezekre általában eljárásokat használunk. Ezek tulajdonképpen kis alprogramok a programban, amiket akárhányszor és (majdnem)akárhol végrehajthatunk.

Ezen kívül akkor is érdemes függvényekre és eljárásokra "szétszedni" a programot, ha komolyabb szoftvert fejlesztünk, párszáz vagy többezer sorosat. Ilyenkor nem szabad az egészet a fő begin...end közé megírni, ugyanis átláthatatlan és bonyolult lesz, nehéz lesz benne hibákat keresni, stb. Ez tulajdonképp jóval fontosabb, mint a kód újrafelhasználhatósága.

Nézzük a deklarációját:
a változók után, de még a főprogram begin-je előtt kell deklarálnunk. Pl.:
procedure eljaras;
begin
  Ide jöhetnek az utasítások amiket végre akarunk hajtani, a meghíváskor
end;

Magyarázat: Az eljárás deklaráció kulcsszava a procedure ezután mintha csak egy új programot írnánk jön egy begin-end; páros, de itt az end mögött pontosvessző van. (ugye a főprogram endjét egy pont zárja, ezt ne felejtsük el).

A kis alprogramunknak átadhatunk változókat is, amikkel dolgozni szeretnénk, ezeket az alprogram neve után () jelek között soroljuk fel pontosvesszővel elválasztva, méghozzá úgy, hogy a típusukat is meg kell adnunk.
példa:
procedure parameteres(param1:integer;param2:char);

A fenti paraméterátadás olyan típusú, hogy csak dolgozik a változó értékével, az eljárás lefutása után az eredeti változó értéke változatlan marad (készít magának egy saját változatot belőle és azzal buherál ezt nevezzük formális paraméternek).
Ha azt szeretnénk, hogy az eredeti változóval dolgozzon, és annak az értékét manipulálja, akkor a var kulcsszót kell használnunk a paraméterlista kívánt változója előtt.
(ez pedig az ún. valódi paraméter)

És itt kéne pár szót ejtenünk a változók hatásköréről is.
Megkülönböztetünk Globális és Lokális változókat.
Globális változókat már eddig is használtunk, a program elején a var után deklaráltuk őket. ezeket az egész program és minden függvény látja, dolgozni tud vele, minden szép és jó, de aztán bekavarunk a lokális változókkal.
Lokális változónak nevezzük azt a változót, ami egy függvény/eljárás sajátja, csak ő látja, és csak ő tud vele dolgozni. Ezeket a függvényünk/eljárásunk neve után, de még a beginje előtt kell deklarálnunk, a szokásos var kulcsszóval.

Na és mi van akkor, ha van mondjuk egy globális i nevű egész változónk, és van egy lokális, szintén i nevű egészünk is?
Nos ekkor abban az eljárásban ahol van a lokális i-nk ott Ő (a lokális) fog érvényesülni, egyébként akiknek nincs ilyen szép saját i-jük azok csak a globális i-t látják.

Na ennyi kitérő után nézzünk egy példát:
  1. program eljarasos;
  2. var i:integer;
  3.     s:string;
  4.  
  5. procedure szovegel(hanyszor:integer);
  6. var i:integer;
  7. begin
  8.   for i:= 1 to hanyszor do writeln(s);
  9. end;
  10.  
  11. begin
  12.   s:='duma...';
  13.  
  14.   for i:= 1 to 10 do szovegel(i);
  15.   readln;
  16. end.


A fenti programban még egyszer benne van az a globális vs. lokális probléma. Tulajdonképpen a működése a következő:
A globális i-vel futtatunk egy for ciklust amiben egyetlen utasítás van mégpedig a saját alprogramunk meghívása egy paraméterrel(ami a globális i).
a saját eljárásunk pedig annyiszor írja ki s értékét, ahányadik globális i-nél tartunk, tehát először egyszer aztán még 2szer, még 3szor, stb...

Sok értelme ugyan nincs de ebből szépen látszik, hogy a két i nem veszik össze egymással, hanem szépen megosztoznak a szerepeken és az alprogramból is szépen látjuk s-t.

Na most nézzük mi van a függvényekkel:
Egy függvény attól függvény, hogy van visszatérési értéke.

Deklarálása:
function fuggveny(param1,param2:byte):shortint;
var ....
{változódeklarációk, ugyanúgy mint az eljárásnál}
begin
......utasítások........
end;

Ennek a függvénynek 2 paramétere van, visszatérési értéke shortint. A visszatérési értéket : után adjuk meg még a begin előtt.

Viszont a visszatérési értékkel vissza is kell térni, ezt úgy csináljuk pascalban, hogy a függvény neve után := (legyen egyenlő) és utána a visszatérési érték.

Nézzünk egy példát függvényre is:
  1. program osszead;
  2. var szam1,szam2:integer;
  3.  
  4. function osszeg(mit1,mit2:integer):longint;
  5. begin
  6.   osszeg:=(mit1+mit2);
  7. end;
  8.  
  9. begin
  10.  
  11.   readln(szam1);
  12.   readln(szam1);
  13.  
  14.   writeln('A két szám összege: ',osszeg(szam1,szam2));
  15.   readln;
  16. end.


Ez a program bekér két egész számot majd kiírja az összegüket. (Amivel a kis függvényünk visszatért, behelyettesítődött a hívás helyére, így az került kiírásra)

A visszatérési érték dolgon kívül a függvények pont úgy viselkednek mint alprogram rokonaik, ezért is van, hogy sok programnyelvben nincs külön alprogram csak visszatérési érték nélküli függvény...

Természetesen az eljárások/függvények egymást is hívhatják, sőt saját magukat is (rekurzió és társai...).
Másik elj./függv. (közös néven alprogram) hívásával kapcsolatban egy feltétel van, hogy amit meghívunk annak előbb kell deklarálva lennie mint amiből meghívtuk. Ez persze néha nem mgoldható, akkor, ha két alprogram egymást hívja. Nézzünk egy példát:
  1.  
  2. procedure eljaras1(a: integer)
  3. begin
  4.    eljaras2(a + 1);
  5. end;
  6.  
  7. procedure eljaras2(a: integer): integer
  8. begin
  9.    if odd(a) then eljaras1(a);
  10. end;
  11.  


Vajmi kevés értelme van a kódnak, de jól szemlélteti a problémát. Az ilyen helyzeteket az alprogramok cserélgetésével nem lehet feloldani. A probléma megoldására az előrevetett (forward) deklarációt használjuk. Az előző kódunk elejére írjuk be a következő sort:
  1. procedure eljaras2(a: integer); forward


Ebből az eljaras1 tudni fogja, hogy az eljaras2 létezik, csak még nem volt definiálva.

Aki nem hiszi járjon utána...