Az átlátható programok kellékei

Slides:



Advertisements
Hasonló előadás
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Advertisements

C++ programozási nyelv Gyakorlat hét
Kifejezések 2+3 Egy egyszerű kifejezés… © Pasztuhov Dániel, www.programozas-oktatas.hu.
LFüggvények Alkalmazott Informatikai Tanszék MŰSZAKI INFORMATIKA dr.Dudás László 20./0. lFüggvények deklarációja és prototípusa lA függvénydefiníció lHivatkozás.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Öröklődés 2..
Programozási Nyelvek (C++) Gyakorlat Gyak 03.
JavaScript.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Bevezetés a Java programozásba
Bevezetés a Java programozásba
5. előadás (2005. március 22.) Függvények definíciója, deklarációja, hívása Enumerációs adattípus 1.
4. előadás (2005. március 8.) Pointerek Pointer aritmetika
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 9. Gyakorlat Alap file műveletek.
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Tömbök ismétlés Osztályok Java-ban Garbage collection
A CLIPS keretrendszer CLIPS "C" Language Integration Production System.
Függvények, mutatók Csernoch Mária.
Mutatók, tömbök, függvények
C A C nyelv utasításai. Ismétlés Utasítások csoportosítása.
A C++ programozási nyelvSoós Sándor 1/10 C++ programozási nyelv Gyakorlat - 5. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
A C++ programozási nyelvSoós Sándor 1/12 C++ programozási nyelv Gyakorlat - 8. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
WEB Technológiák Dr. Pance Miklós – Kolcza Gábor Miskolci Egyetem.
C++ Alapok, első óra Elemi típusok Vezérlési szerkezetek
ANY u WHERE u : seq(MININT..MAXINT) & size(u) = size(s) & #f.(f : 1..size(s) >->> 1..size(s) & !j.(j : 1..size(s) => s(f(j)) = u(j))) & !i.(i : 1..size(s)-1.
C++ alapok, harmadik óra
Programozás I Függvények általános jellemzői
Operációs rendszerek gyakorlat 4. Gyakorlat Vakulya Gergely.
PHP I. Alapok. Mi a PHP? PHP Hypertext Preprocessor Szkriptnyelv –Egyszerű, gyors fejlesztés –Nincs fordítás (csak értelmező) Alkalmazási lehetőségek:
P ROGRAMOZÁS C# - BAN Kivételkezelés. P ÉLDA I. Nullával való osztás miatt kapjuk a hibaüzenetet.
P ROGRAMOZÁS I/O műveletek. S YSTEM.C ONSOLE A programjainknak fontos része a felhasználóval való kommunikáció. Adatokat kell kérni tőle, vagy közölnünk.
Programozás Az adatokról C# -ban.
Programozási Nyelvek (C++) Gyakorlat Gyak 02.
Alprogramok deklarációja, definíciója és meghívása Páll Boglárka.
Programozási nyelvek, Pascal
Szintaktikai, szemantikai szabályok
1.3. Pascal program felépítése Az els ő program. Program ; … Begin … End. Program fej Deklarációs rész Végrehajtó rész.
Készítette: Csíki Gyula
Hernyák Zoltán Programozási Nyelvek II.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
Visual Basic 2008 Express Edition
Objektum orientált programozás
Webprogramozó tanfolyam
Függvények a C nyelvben 1 Függvényeket a következő esetekben szokás írni: Ha ugyanazt a tevékenységet többször is el kell végeznünk ugyanolyan típusú,
C Programozási alapok.
2012. március 21. Paulik Áron.  Ha a függvényünk feladata olyan, hogy nem lenne értelme a visszatérési értéknek, vagy csak nincs rá szükség, void típusúként.
1. feladat  Készíts olyan függvényt, mely paraméterül kapja két egész típusú változó címét, s hívása után a két változó értéke helyet cserél.
Kiterjesztések szemantikája: Szemantikai tartomány : Adatoknak, vagy értékeknek egy nem üres halmazát szemantikai tartománynak nevezzük. Jelölése: D. Egy.
Függvények, mutatók Csernoch Mária. Függvények függvény definíciója az értelmezési tartomány tetszőleges eleméhez hozzárendel egy értéket –függvény helyettesítési.
Függvények, mutatók Csernoch Mária. Függvények függvény definíciója az értelmezési tartomány tetszőleges eleméhez hozzárendel egy értéket –függvény helyettesítési.
TÖMBÖK – péntek Jordán Sándor.
a programegységek között
Kifejezések C#-ban.
Gépészeti informatika (BMEGEMIBXGI)
Beépített függvények használata programozáskor
Programozás C# -ban Elágazások.
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
A CLIPS keretrendszer
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
Fájlkezelés C++ alatt – péntek Jordán Sándor.
Változók.
Az átlátható programok kellékei
B M Java Programozás 1. Gy: Java alapok IT A N Ismétlés ++
Informatikai gyakorlatok 11. évfolyam
Konverziós operátorok
Függvénysablonok használata
Előadás másolata:

Az átlátható programok kellékei - Függvények - Az átlátható programok kellékei 2009. 11. 13 – péntek Jordán Sándor

Mielőtt a függvényekbe belekezdenénk, meg kell ismerkedni a folyamattal, hogy a gép hogyan értelmezi a mi kódunkat. Egyszerű programoknál egyszerűen „fentről lefelé” halad compiler az értelmezésben … de ha függvények használatánál már nem ilyen egyszerű a dolog.

Lássunk egy egyszerű példát #include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } Lássunk egy egyszerű példát

#include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } Megnézi a compiler, hogy milyen fájlokat kell még hozzáfűznie a kódhoz … jelen esetben az iostream tartalmazza a számunkra fontos cin és cout parancsoakt is.

#include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } Megnézi a compiler, hogy milyen névterekben keresse a parancsokat … más mód is van, hogy tudassuk a compilerrel, hogy „honnan származik” az adott parancs, de ez így sokkal egyszerűbb nekünk.

#include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } Megkeresi a main függvény kezdetét, és innen folytatja az általunk írt kód értelemzését… egészen addig, amíg nem talál a main függvényben valami féle „return” kifejezést … ugyanis akkor ott befejeződik a futás.

#include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } Értelemzi a main függvény „törszét” … mondhatni, hogy elvégzi a munka lényegi részét 

#include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } Meg találta a main függvény visszatérési értékét, azaz a „return 0” kifejezést … a program futása véget ér.

A függvényekkel kapcsolatban alsó osztályban találkozhattunk először … gondoljunk csak a „gépes” feladatokra: Belerakunk egy számot a gépbe (x) és például (x+2) jön ki belőle … aztán több számot raktunk bele (x,y,z), majd az (x+y*z) kifejezés jött ki például. A feladatunk a gép működési szabályának meghatározása volt…

Most mi fogunk szabályt írni adott feladatokra Most mi fogunk szabályt írni adott feladatokra. Például 3 szám összeadására: 6 5 7 18

A függvények szintatktikája: <típus> <név>(<paraméterek>){ <utasítások> } konkrét példa: int osszead(int x, int y){ return x+y; }

Vizsgáljuk meg ezt közelebbről kicsit: int osszead(int x, int y){ Vizsgáljuk meg ezt közelebbről kicsit: int osszead(int x, int y){ return x+y; } Meghatározzuk, hogy milyen típusú értékkel térhet vissza a függvény, azaz milyen típus kerülhet a return utána, azaz „milyen típusú elem jönne ki a gépből”  Mi lesz a függvény neve … ezzel a névvel hívhatjuk meg a függvényt a kód egyéb területén Milyen értékeket kap a függvény amikkel dolgozni tud és ezek milyen típusúak … ergo „mit teszünk bele a gépbe”. Akár nulla, akár egy, akár akármennyi paramétert megadhatunk itt. Ezzel az értékkel térünk vissza a függvényből … ez az érték fog „kijönni a gépből”

Megjegyzések a return-hoz: - Ha elér a program egy return-t, akkor az az utáni kód már nem fut le, hanem ott „visszatérünk”, azaz visszatér a futás a függvényt meghívó sor utánra. - Lehet több return is egy függvényben … pl elágazásnál lehet hasznos … ha igaz az állítás, „if”, akkor return true „else” return false. - DE csak egy return fog lefutni!!!

Van egy a függvényhez hasonló dolog Van egy a függvényhez hasonló dolog. A különbség annyi, hogy semmivel sem térünk vissza, mert az adott körülmények között fölösleges … például csak egy menüt szeretnénk kiíratni. Ezt hívjuk eljárásnak!

Az eljárás C++ alatt teljesen hasonlít a függvény deklarációjára, csak itt a visszatérési típus helyett void –ot írunk. De a „semmivel” vissaz tudunk térni. Ekkor csak simán return; -t kell írnunk és a program futása visszatér a hivó részhez azonnal. Lássunk egy példát az eljárásra:

Eljárás: void menu(int x, int y){. cout << „MENU” << endl; Eljárás: void menu(int x, int y){ cout << „MENU” << endl; return ; } Mivel eljárás, ezért void lesz a visszatérés értéke. Mi lesz a függvény neve … ezzel a névvel hívhatjuk meg a függvényt a kód egyéb területén Milyen értékeket kap a függvény amikkel dolgozni tud és ezek milyen típusúak … ergo „mit teszünk bele a gépbe”. Akár nulla, akár egy, akár akármennyi paramétert megadhatunk itt. Ezzel az értékkel térünk vissza a függvényből … ez az érték fog „kijönni a gépből” … most csak a függvény befejezésére szolgál … elhagyható … ha eljutunk a csukó zárójelig, akkor úgy is megtörténik a visszatérés

Megvannak a függvényeink és eljárásaink (azaz együttesen nevezve alprogramok), és most el szeretnénk helyezni a kódban ezeket. Azt tudjuk, hogy ha eljut a compiler a main függvényhez (mert hogy mostmár látjuk tisztán, hogy ez is csak egy függvény  ), akkor onnan már a „melós” része fut a programnak … pedig ez előtt még be kellene mutatni neki az alprogramjait.

Megoldás: Még a main függvény előtt kell megírni az alprogramokat , vagy csak deklarálni és akkor később kifejteni. Másik kérdés: Hogyan hívjuk meg a függvényeket … mert, hogy attól, hogy csak beírjuk még nem fog lefutni 

Az összeadás függvényt például így hívtuk volna meg a main függvényből: int main() { int a,b; int x=osszead(a,b); return 0; } A main függvényben vagyunk, de bármelyik másik függvényben meghívhattuk volna. FIGYELEM … akár magában az osszead függvényben is meghívhattuk volna saját magát … ez a rekurzív függvény hívás. Sokszor hasznos lehet!!! Lesz két változónk, amiket átadunk a függvénynek, és típusuk egyezik a függvény által várt típusokkal. A függvény nevével hívhatjuk meg magát a függvényt, valamint zárójelben sorban megadjuk az átadni kívánt értéket … itt hívódik meg a függvény X nem lesz már mint az osszead függvény visszatérési értéke Itt a vége a mókának 

Most akkor rakjuk össze a függvény deklarációs részét és a függvény hívást … azaz nézzük meg, hogy hogy áll össze egy teljes programmá mindez amit láttunk. És nézzük meg rögtön azt is, hogy hogyan gondolkodik a gép eközben 

Tehát X (ami nem azonos a fenti X-el Tehát X (ami nem azonos a fenti X-el!!!!) értéke az osszead függvény vissaztérési értéke lesz … azaz X+Y; A visszatérési érték X+Y lesz ami int típusú, így megfelel a függvény deklarációs részben az int kritériumnak Itt megtaláltuk a main függvényt … innen kezdődik az igazi munka #include <iostream> using namespace std; int osszead(int x, int y){ return x+y; } int main() { int a,b; cin >> a >> b; int x=osszead(a,b); return 0; } Léthoztunk két változót ami majd az osszead függvénynek oda tudunk adni … típusokra figyelni!! Ebből a függvényből is visszatérünk .. Méghozzá egy 0 értékkel ( ha 0-val térünk vissza, akkor jelezhetjük MAGUNKNAK, hogy nem volt hiba), de a main függvényből a visszatérés egyet jelent a program végével így a futás leáll. Megnézi a compiler, hogy milyen fájlokat kell még hozzáfűznie a kódhoz … jelen esetben az iostream tartalmazza a számunkra fontos cin és cout parancsoakt is. Megnézi a compiler, hogy milyen névterekben keresse a parancsokat … más mód is van, hogy tudassuk a compilerrel, hogy „honnan származik” az adott parancs, de ez így sokkal egyszerűbb nekünk. Most csak megjegyzi a program, hogy van ilyen függvény, hogy osszead és ha valahol hivatkozást talál rá, akkor tudja, hogy ezt kell lefuttatni . Ha eléri a compiler a main-t, akkor nem fog több függvény deklarációt keresni!!! Ezért kell „előre” deklarálni a függvényeket és eljárásokat!! Bekérjük a konzolról a függvénynek adandó két egész típusú számot. Ergo két számot kérünk amit össze fogunk adni. Tudta a program, hogy az osszead fuggveny itt már deklarálva lett, így itt folytatja a futást. X kezdőértéke A lesz, míg Y kezdőértéke B, DEEE A és B értéke nem változik meg a függvény lefutása közben, akárhogy is próbáljuk ott megváltoztatni, mert ott csak X és Y értéke fog változni!!! Azok másik változók!!!! Deklarálunk egy x változót ami int típusú, pont úgy mint az osszead visszatérési értéke, éppen ezért lehetséges az értékadás … azaz X az osszead függvény visszatérési értéke lesz. Az osszead függvényt pedig meghívjuk A és B paraméterekkel. FONTOS : akármit változtat az osszead függvény a két változón … az nem lesz hatással a mainben lévő A-ra és B-re!!!

A csak egy értékkel térhetek vissza … de mi van ha én többel akarok A csak egy értékkel térhetek vissza … de mi van ha én többel akarok? Semmi … C++ ilyen nincs, egyes nyelvekben van… … és ha én azt szeretném, hogy a paraméterként adott változókon végzett változtatások megmaradjanak a függvény/eljárás lefutása után is? Na ilyenünk már van 

Ezt úgy tudjuk megoldani, hogy nem egy változót, hanem annak a memória címét adjuk át … és az azon végzett változtatások ugyebár megmaradnak. Ezt cím szerinti paraméterátadásnak hívjuk. A függvény deklarációjában a változó név(ek) elé kell tenni egy „&” karaktert, hogy közöljük a programmal a cím szerinti átadás tényét.

Ábra az előzőekben leírtak ábrázolására: Memóriacím Int x Int& a Int& b

A kulcsszó amit érdemes megjegyezni, az az hogy KÖZÖS memóriacímet használnak … ha az egyik belerak valamit, a másik ugyan azt fogja látni és az lesz az értéke ezen túl. Nézzünk erre a fontos esetre is egy példát:

#include <iostream> using namespace std; int exampleee(int& x){ // Itt látszik a & jel használata x=x+6; // Megnöveltük x-et 6-al … de A-t is most return x; } int main() { int a=5; cin >> a >> b; exampleee(a); // itt A már 11 lett, ha nem lett return 0; // volna paraméterátadás, akkor // maradt volna A az 5 értékkel }

Még egy dolog van ami a függvényekhez tartozik, de csak később vesszük igazán hasznát … de nem baj ha hall róla az ember. C++ lehetséges az, hogy két azonos nevű függvényt/eljárást készítsen de más paraméterezéssel, azaz vagy a paraméterek típusa, vagy a paraméterek száma különböző.

Például: int pelda(int& x, string s) int pelda(int x, int s) bool pelda(bool t, double k, float& e) Eze között a program különbséget tud tenni … ezt Függvény túlterhelésnek nevezzük!

Érdemes ráérezni, hogy mit rakjon az ember külön alprogramba Érdemes ráérezni, hogy mit rakjon az ember külön alprogramba. Ha mindent a main-ben hagy, akkor olvashatatlan lesz a kód … ha mindent függvényekbe rak, akkor nagyon szétszabdalt lehet a kód, ami megint olvashatatlanságot okozhat.

Egy utolsó tanács a függvényekhez/eljárásokhoz: Egy függvény/eljárás lehetőleg csak egy dolgot tudjon … de azt bombabiztosan. Tehát ezek olyan építőköveink legyenek, amik nem túl nagyok, hogy programot építsünk belőlük (könnyű átláthatóság, egyszerűség), de lehessen rájuk számítani és ne omoljon össze minden munkánk egy hibás „tégla” miatt.

Azt hiszem a függvények használtára és nem használatára az alábbi példa elég szemléletes: Lehet egy kastélyt erős sziklakockákból építeni, de akár ki is lehet faragni egyetlen kőtömbből  (Petra romvárosa (Jordánia) egyetlen sziklából van kifaragva … egyedülálló munka … de gondoljatok bele mennyivel több munka kellett az építéséhez)