Programozás alapjai A C nyelv.

Slides:



Advertisements
Hasonló előadás
Szerver oldali programozás
Advertisements

C# nyelvi áttekintő A „Programozás C# nyelven (Illés Zoltán)”
Elemi algoritmusok Páll Boglárka.
Készítette: Boros Erzsi
Programozási feladatok
Definíciók: Algoritmus: bármely véges sok lépéssel leírható tevékenység. Olyan pontos előírás, amely megmondja, hogy egy adott típushoz tartozó feladat.
Adatelemzés számítógéppel
Matematika és Tánc Felkészítő tanár: Komáromi Annamária
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.
Halmazok, műveletek halmazokkal
Műveletek logaritmussal
2009 Bevezetés a programozásba Krankovits Melinda.
3. előadás (2005. március 1.) Utasítások, tömbök
Euklidészi gyűrűk Definíció.
4. VÉGES HALMAZOK 4.1 Alaptulajdonságok
Programozás alapjai.
Turbo Pascal Változók.
A tételek eljuttatása az iskolákba
Bevezetés a Java programozásba
Bevezetés a Java programozásba
Algoritmusok Az algoritmus fogalma:
1 Programozás alapjai GEIAL312B (ANSI C) BSc (Bachelor of Science) / Alap képzés 2005/2006. őszi félév Miskolci Egyetem Általános Informatikai Tanszék.
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. 6. Gyakorlat const, static, dinamikus 2D.
C A C nyelv utasításai.
Mutatók, tömbök, függvények
C A C nyelv utasításai. Ismétlés Utasítások csoportosítása.
Algoritmizálás Göncziné Kapros Katalin humaninformatika.ektf.hu.
1. IS2PRI2 02/96 B.Könyv SIKER A KÖNYVELÉSHEZ. 2. IS2PRI2 02/96 Mi a B.Könyv KönyvelésMérlegEredményAdóAnalitikaForintDevizaKönyvelésMérlegEredményAdóAnalitikaForintDeviza.
Utasítások, elágazás- és ciklusszervezés C nyelvi utasítások
1 Programozás alapjai GEIAL312B (ANSI C) BSc (Bachelor of Science) / Alap képzés 2005/2006. őszi félév Miskolci Egyetem Általános Informatikai Tanszék.
Valós számok Def. Egy algebrai struktúra rendezett test, ha test és rendezett integritási tartomány. Def. Egy (T; +,  ;  ) rendezett test felső határ.
C++ Alapok, első óra Elemi típusok Vezérlési szerkezetek
Programozás I. Ciklusok
Programozás I. Egymásba ágyazott szelekciók, többágú szelekció
Vizuális és web programozás II.
ISZAM III.évf. részére Bunkóczi László
DRAGON BALL GT dbzgtlink féle változat! Illesztett, ráégetett, sárga felirattal! Japan és Angol Navigáláshoz használd a bal oldali léptető elemeket ! Verzio.
Programozás Az adatokról C# -ban.
C nyelv utasításai.
szakmérnök hallgatók számára
Exponenciális egyenletek
Logikai szita Izsó Tímea 9.B.
Ciklusok (iterációk).
Programozási nyelvek.
Készítette: Csíki Gyula
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
A klinikai transzfúziós tevékenység Ápolás szakmai ellenőrzése
Objektum orientált programozás
Objektum orientált programozás
Objektum orientált programozás
1. Melyik jármű haladhat tovább elsőként az ábrán látható forgalmi helyzetben? a) A "V" jelű villamos. b) Az "M" jelű munkagép. c) Az "R" jelű rendőrségi.
Fontos tudnivalók A MATLAB egy fajta objektummal dolgozik (Mátrix)
Valószínűségszámítás II.
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.
Algoritmizálás, adatmodellezés
1 Az igazság ideát van? Montskó Éva, mtv. 2 Célcsoport Az alábbi célcsoportokra vonatkozóan mutatjuk be az adatokat: 4-12 évesek,1.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás I. 3. gyakorlat.
Adatszerkezetek és algoritmusok 2008/ Algoritmus Az algoritmus szó eredete a középkori arab matematikáig nyúlik vissza, egy a i.sz. IX. században.
Programozási alapok.
Programozás C# -ban Elágazások.
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Informatikai gyakorlatok 11. évfolyam
Algoritmus készítés.
Előadás másolata:

Programozás alapjai A C nyelv

Programozás Alapjai (2008) A C nyelv A C egy nagyon kicsi nyelv. Szintaxisa a K&R-ben csupán néhány oldal. A nyelv érzékeny a kis- és nagybetűkre! Nincs beépítve I/O kezelés Sztring kezelés Matematikai függvények Viszont gazdagon kínál standard függvénykönyvtárakat. Programozás Alapjai (2008)

A C nyelv tulajdonságai Kis méret Függvényhívások széleskörű használata A típus hanyagolása Struktúrált nyelv Alacsony szintű programozás olvasható elérése Pointer széleskörű használata: memória, tömb, struktúra, függvény Programozás Alapjai (2008)

A C nyelv tulajdonságai Miért vált a C széleskörűen használt profi programozási nyelvvé? Magas szintű konstrukciói vannak. Alacsony szintű tevékenységeket is kezelni tud. Hatékony programot készítenek a fordítók. A számítógépek sok változatán találunk C fordítót. Programozás Alapjai (2008)

A C nyelv rövid története UNIX fejlesztése 1969 körül az AT&T Bell Laboratóriumában Ken Thomson és Dennis Ritchie Első változat Assembly nyelven DEC PDP-7 gépen. BCPL – felhasználóbarát operációs rendszer fejlesztő nyelv Legfőbb jellemzője, hogy típustalan. Unalmasan hosszú kód sok hibával. Egy új nyelv, a "B", a második kísérlet 1970 körül Programozás Alapjai (2008)

A C nyelv rövid története 1971: teljesen új nyelv, a "C", a "B" leszármazottja 1973-ban a UNIX operációs rendszert átírták "C"-re. Az AT&T "hivatalos" változata a System V (System Five), amely a 4. Release-nél tart, rövidítve SVR4) 1988-89: ANSI C American National Standards Institute 1999: ISO C 99 International Organization for Standardization Programozás Alapjai (2008)

A C nyelv rövid története A C nyelv és a UNIX összefonódása miatt C shell (csh) parancsértelmező C-szerű szintaxissal man cc, man gcc, man a.out, man ldd, stb. sok man oldal van a 3-as szekcióban, pl. man 3 printf, man 3 scanf, stb. A hírcsoportok (newsgroup) közül érdemes megemlíteni: comp.lang.c comp.lang.c.moderated Programozás Alapjai (2008)

Programozás Alapjai (2008) Anyag a C nyelvhez A GNU project dokumentációi a gyakran használt leírások, kézikönyvek között találhatók: http://www.cab.u-szeged.hu/local/m/doku.html vagy közvetlenül a http://www.cab.u-szeged.hu/local/m/gnu.html oldalon. Megtalálhatjuk a dokumentációk .dvi és .ps változatait is a /pub/egyeb/doku/dvi/ illetve /pub/egyeb/doku/ps/ alkönyvtárakban. Programozás Alapjai (2008)

C fejlesztői környezetek MSVC Microsoft Visual C Integrált fejlesztői rendszer Windows alá fordít Programozás Alapjai (2008)

C fejlesztői környezetek GNU C gcc fordító programok linux alatt is gcc, ld, as i486-linux targetre fordít anjuta fejlesztői rendszer sokféle programnyelvhez Programozás Alapjai (2008)

Fordítás Linux rendszerben C fordítás Jobb megoldás, ha a programnak nevet adunk $ gcc program.c $ ./a.out $ gcc -o program program.c $ ./program Programozás Alapjai (2008)

Programozás Alapjai (2008) C fájlok A szabályos végződések: file.c C source (forrás) file file.h C header (fejléc) file file.i preprocessed C (preprocesszált) file file.s assembly language file file.o object file a.out link edited output Programozás Alapjai (2008)

A C forrás fordításának folyamata A fordítási folyamat sok lépésből is állhat, de 4 olyan lépés van, ahol a folyamatot elkezdeni illetve befejezni lehet. preprocessing – előfeldolgozás compilation – fordítás (assembly nyelvre) assembly – fordítás (gépi kódra) linking – szerkesztés Programozás Alapjai (2008)

A C forrás fordításának folyamata A fájl végződése utal a programozási nyelvre és arra, hogy mit kell vele csinálni: preprocesszor C fordító assembler linker .c .i .s .o a.out .h p.c gcc -E p.c >p.i p.i gcc -S p.i p.s gcc -c p.s p.o gcc p.o a.out as p.s ld p.o ... gcc -S p.c gcc p.s gcc -c p.c gcc p.i gcc -c p.i gcc p.c Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimális C program /* * Minimális C program, ami nem csinál semmit * Készítette: Dévényi Károly, devenyi@inf.u-szeged.hu * 1998. Február 26. */ main() { } Programozás Alapjai (2008)

Programozás Alapjai (2008) Hello World C nyelven /* * Helló Világ! * Készítette: Gergely Tamás, gertom@inf.u-szeged.hu * 2004. November 3. */ #include <stdio.h> int main() { printf ("Helló Világ!\n"); } Programozás Alapjai (2008)

Egy kicsit bonyolultabb C program main(l ,a,n,d)char**a;{ for(d=atoi(a[1])/10*80- atoi(a[2])/5-596;n="@NKA\ CLCCGZAAQBEAADAFaISADJABBA^\ SNLGAQABDAXIMBAACTBATAHDBAN\ ZcEMMCCCCAAhEIJFAEAAABAfHJE\ TBdFLDAANEfDNBPHdBcBBBEA_AL\ H E L L O, W O R L D! " [l++-3];)for(;n-->64;) putchar(!d+++33^ l&1);} Programozás Alapjai (2008)

… és a futásának eredménye $ ./where 46 20 !!!!!!!!!!! !!! !!! !!!!!!! ! !!!!!!!!!!!!!!!!! !!!!! ! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!! !!!! ! !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!! !!!!"!! !!!!!!!!!!!!!!!!! !! ! !!!!!!!!! !! ! !!!!!!!!!!!!!!!!!!!! ! ! !!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!! !!!!! !!!!!!!!!!!!! !!! !!! ! !!!!! !!!!!!!!!! ! ! ! ! !!!!!!!! !!!!! !! !!!!!! !!!! ! !!!!! !!!! !! !!!!!!!! !! !! !! ! ! $ Programozás Alapjai (2008)

Programozás alapjai A C nyelv alapjai

Programozás Alapjai (2008) A C nyelv alapjai Egy C programozási nyelven írt forrásfájl programegységek deklarációjából és definíciójából áll. Deklarálhatunk Konstanst Típust Változót Függvényt #define N 42 egyben N definíciója is typedef unsigned long ui32; int magassag; double mertani_kozep(double, double); Programozás Alapjai (2008)

Programozás Alapjai (2008) Deklaráció Egy programkomponens deklarációja egy azonosító hozzárendelése az adott komponenshez. Ezzel az azonosítóval hivatkozhatunk a program további részében az adott komponensre. A program egy adott pontján csak azok a komponensek használhatók (hivatkozhatók), amelyeket e pontot megelőzően már deklaráltunk, ellenkező esetben fordítási hiba lép fel. Programozás Alapjai (2008)

Programozás Alapjai (2008) Definíció Egy programkomponens definíciója egy (a komponens deklarációjában meghatározott típusú) érték hozzárendelése a komponens azonosítójához. A program egy adott pontján csak azoknak a komponenseknek az értékét szabad felhasználni, amelyeket e pontot megelőzően már definiáltunk, ellenkező esetben a program nem fordítható, nem szerkeszthető, vagy működése véletlenszerű, akár hibás is lehet. Programozás Alapjai (2008)

Programozás Alapjai (2008) Adattípus Az adattípus olyan egysége a programnak, amely két összetevője által meghatározott: Értékhalmaz Az értékhalmaz elemein végezhető műveletek Minden adattípus vagy elemi, vagy más adattípusokból képzett összetett adattípus. Programozás Alapjai (2008)

Programozás Alapjai (2008) Változó A változó olyan programegység, amely a hozzá rendelt adattípus értékhalmazából műveletek hatására tetszőleges értéket felvehet, és értékét a program végrehajtása során akárhányszor megváltoztathatjuk. A változó értéke kezdetben definiálatlan, és az marad, amíg valamilyen művelettel értéket nem adunk neki. Programozás Alapjai (2008)

Programozás Alapjai (2008) Változó (folyt.) A változók alapvetően úgynevezett értékadó művelet végrehajtásával kaphatnak értéket. Ennek jelölése: V = E ahol V egy meghatározott adattípusú változó E ezen adattípus egy értéke Feltételezhetjük, hogy az értékadó művelet minden elemi adattípus műveletei között szerepel. magassag = 100; magassag = (magassag + 83); Programozás Alapjai (2008)

Programozás Alapjai (2008) Konstans A konstans olyan komponense a programnak, amely a definíciójában megadott értéket azonosítja, és ez az érték a program végrehajtása során nem változtatható meg. Típusa a definíciója által meghatározott adattípus. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvény A függvény a matematikai értelemben vett függvény általánosítása, gyakorlatilag egy (rész-)algoritmus megvalósítása. A függvény deklarációja azt mondja meg, hogy milyen típusú értékekből milyen típusú értéket állít elő. A függvény definíciója megmondja, hogy a függvény végrehajtása során milyen algoritmust kell végrehajtani. A függvény meghívásakor azt adjuk meg, hogy milyen konkrét értékeken hajtsuk végre a függvény által leírt algoritmust. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvény (folyt.) A C nyelvben a függvény fogalma bővebb, mint a matematikában Vannak olyan függvények, amiknek valamilyen jól definiált „mellékhatása” is van a visszatérési érték kiszámítása mellett, ilyenek például a szöveget megjelenítő (pl. printf), vagy adatbevitelt kezelő (pl. scanf) függvények. Adott esetben az is előfordulhat, hogy egy függvénynek csak a „mellékhatása” fontos, ilyenkor lehet, hogy a függvény (matematikai értelemben) nem is számít ki semmilyen visszatérési értéket. Az ilyen függvényeket nevezhetjük eljárásnak. Programozás Alapjai (2008)

Deklarációk, definíciók C-ben Változók deklarációja: típusmegadás azonosító; Konstansok definíciója: #define azonosító érték int i; double f; #define N 42 #define EPS 1e-10 Programozás Alapjai (2008)

Programozás Alapjai (2008) Szintaxis A kommunikáció ember és gép között véges jelhalmazból (ábécé) vett, meghatározott formai szabályokat kielégítő, véges hosszúságú jelsorozatokkal történik. Ezek a jelsorozatok alkotják a kommunikáció nyelvét. Szintaxis Formai szabályok olyan rendszerét, amely meghatározza, hogy egy adott kommunikációs nyelvben melyek a szabályos jelsorozatok, a nyelv szintaxisának nevezzük. Programozás Alapjai (2008)

Programozás Alapjai (2008) Szintaxisdiagram Szintaxis megadására számos módszer ismeretes, mi szintaxis diagramokat használunk. Ebben minden szintaktikus egység egyedi elnevezést kap, és a szintaktikus egységhez tartozó szabályos jelsorozatokat egy diagram (ábra) definiálja Az ábrában a szintaktikus egységneveket tartalmazó dobozokat (téglalapokat) és konkrét jelsorozatokat irányított vonalak kötik össze Minden diagramnak egy bemenete és egy kimenete van Programozás Alapjai (2008)

Szintaxisdiagram (folyt.) Szintaxis diagramok egy (véges) rendszerében egy diagram azokat és csak azokat a jelsorozatokat határozza meg, amelyek úgy kaphatók, hogy a diagram bemenetéről indulva az irányított vonalak mentén haladva a kijáratig, valahányszor érintünk egy egységet, egymás után írjuk az úton érintett egység által meghatározott jelsorozatok egy elemét. A diagramban a konkrét jelsorozatok önmagukat definiálják. Programozás Alapjai (2008)

Programozás Alapjai (2008) Szintaxis Azonosító Számjegy Betű _ Programozás Alapjai (2008)

Programozás Alapjai (2008) Szintaxis Betű Számjegy A Z a z 1 2 3 4 5 6 7 8 9 Programozás Alapjai (2008)

A C nyelv elemi adattípusai int Egész float Valós A C-ben nincs logikai típus, de logikai igaz és hamis értékek keletkeznek, és logikai műveletek is vannak Programozás Alapjai (2008)

Programozás Alapjai (2008) Logikai műveletek Egy operandusú műveletek (logikai -> logikai) ! Tagadás művelet Két operandusú műveletek (logikai x logikai -> logikai) && 'és' művelet || 'vagy' művelet !a a && b a || b Programozás Alapjai (2008)

Programozás Alapjai (2008) Logikai műveletek Relációs műveletek (logikai x logikai -> logikai) == Egyenlőség != Nemegyenlő < Kisebb > Nagyobb <= Kisebb vagy egyenlő >= Nagyobb vagy egyenlő a == b a != b a < b a > b a <= b a >= b Programozás Alapjai (2008)

Programozás Alapjai (2008) Az int adattípus A C nyelv eleve definiált elemi adattípusa. Egész értékek tárolására alkalmas. Értékkészlete [INT_MIN, INT_MAX] zárt intervallumba eső egész számok halmaza Az INT_MIN és INT_MAX eleve definiált konstans azonosítók, használatukhoz a program elejére be kell szúrni az alábbi sort: #include <limits.h> Programozás Alapjai (2008)

Az int adattípus műveletei Egy operandusú műveletek (int -> int ) - Előjel váltás Két operandusú műveletek (int x int -> int) + Összeadás - Kivonás * Szorzás / Egészosztás hányadosa % Egészosztás maradéka -a a + 8 7 - a 6 * 7 a / 3 42 % a Programozás Alapjai (2008)

Az int adattípus műveletei Relációs műveletek (int x int -> logikai) == Egyenlőség != Nemegyenlő < Kisebb > Nagyobb <= Kisebb vagy egyenlő >= Nagyobb vagy egyenlő 3 == a a != 7 a < 42 a > 77 0 <= a 8 >= a Programozás Alapjai (2008)

Az int adattípus műveletei Az int adattípus műveleteire teljesülnek az aritmetika ismert azonosságai, feltéve, hogy a művelet eredménye az adattípus értékhalmazába esik. Ha a művelet eredménye nem esne az adattípus értékhalmazába, túlcsordulásról beszélünk. 2 * (3 * 7 + 5 * 4) == 4 * 2 * 5 + 3 * 2 * 7 2147483647 + 1 == -2147483648 Programozás Alapjai (2008)

Programozás Alapjai (2008) A float adattípus A C nyelv eleve definiált elemi adattípusa. A matematikai valós számok és műveleteik számítógépes modellezésére használható. A matematikai valós számok megközelíthetők az adattípus értékeivel, a matematikai műveletek pedig az adattípus műveleteivel. A közelítés mértéke a konkrét gépi megvalósítástól függ. A float adattípust valós típusnak is hívjuk. Programozás Alapjai (2008)

Programozás Alapjai (2008) A float adattípus Értékkészlete Az adattípus értékei egy adott intervallumba esnek úgy, hogy minden valós szám ebből az intervallumból adott relatív pontossággal megközelíthető float adattípusbeli értékkel. Ez azt jelenti, hogy bármely a valós számhoz van olyan x float típusú érték, hogy |(x-a)/a| < relatív pontosság Programozás Alapjai (2008)

A float adattípus műveletei Egy operandusú műveletek (float -> float) - Előjel váltás Két operandusú műveletek (float x float -> float) + Összeadás - Kivonás * Szorzás / Osztás -3.1415 41.3 + 0.7 a – 2.7172 0.5 * a a / 2.0 Programozás Alapjai (2008)

A float adattípus műveletei Relációs műveletek (float x float -> logikai) == Egyenlőség != Nemegyenlő < Kisebb > Nagyobb <= Kisebb vagy egyenlő >= Nagyobb vagy egyenlő 3.0 == a a != 7.2 a < 1e-10 a > 0.2E3 0.33 <= a 42.0 >= a Programozás Alapjai (2008)

A float adattípus műveletei A matematikai függvények és konstansok, mint például a sin cos M_PI log exp nem részei a nyelvnek, de egy könyvtárban össze vannak gyűjtve. Használatukhoz szükséges a matematikai függvénykönyvtár include-olása double sin(double x); double cos(double x); #define M_PI 3.14159265358979323846 double log(double x); double exp(double x); #include <math.h> Programozás Alapjai (2008)

Numerikus adattípusok Az int és a float adattípusokat összefoglalóan numerikus adattípusoknak nevezzük. Numerikus adattípus értékeinek leírására számleírást, röviden számokat használunk. Az int adattípus értékeit nyolcas, tízes vagy tizenhatos számrendszerbeli leírással adhatunk meg. (Tizenhatos számrendszerben a számjegyek értéke decimálisan: A=10, B=11, C=12, D=13, E=14, F=15.) Valós számok leírására tizedes törtet használhatunk, kiegészítve tízes exponenssel. Programozás Alapjai (2008)

Szintaxis Szám Előjeltelen szám Előjeltelen egész szám + - Előjeltelen egész szám Előjeltelen valós szám Számjegy Hexadecimális számjegy Oktális számjegy 0x Nem 0 számjegy Programozás Alapjai (2008)

Programozás Alapjai (2008) Szintaxis Előjeltelen valós szám Hexadecimális számjegy . Számjegy + - E e 42 052 0x2a -3.1415 3e5 3E+6 271.72e-2 A Számjegy a B b C c D d E e F f Programozás Alapjai (2008)

Programozás Alapjai (2008) Kifejezés Kifejezésen olyan programkomponenst értünk, amely egy adattípus értékének olyan jelölése, amely műveleteket is tartalmazhat. A kifejezés által jelölt értéket a kifejezés kiértékelése határozza meg. A kifejezés szintaxisa (egyelőre) Numerikus kifejezés Logikai kifejezés Programozás Alapjai (2008)

Programozás Alapjai (2008) Kifejezés szintaxisa Numerikus kifejezés Numerikus tag Numerikus tag + - Numerikus tényező * / % Programozás Alapjai (2008)

Kifejezés szintaxisa Numerikus tényező Numerikus változó Konstans azonosító Előjeltelen szám Numerikus kifejezés Numerikus tényező Numerikus függvényhívás ( ) + - Programozás Alapjai (2008)

Programozás Alapjai (2008) Kifejezés szintaxisa Logikai kifejezés Logikai tag Logikai tag || Logikai tényező && Programozás Alapjai (2008)

Kifejezés szintaxisa Logikai tényező Logikai változó Logikai konstans azonosító Relációs kifejezés Logikai kifejezés Logikai tényező Logikai függvényhívás ( ) ! Programozás Alapjai (2008)

Programozás Alapjai (2008) Kifejezés szintaxisa Relációs kifejezés Kifejezés == != < > <= >= (sin(M_PI + alfa) < 0.2 * alfa + 1e-1) && (beta != M_PI) Programozás Alapjai (2008)

Kifejezések kiértékelése A kifejezés kiértékelését két előírás együttesen határozza meg A kifejezés szerkezetén alapuló prioritási előírás A haladás irányára vonatkozó előírás Programozás Alapjai (2008)

Programozás Alapjai (2008) Prioritási előírás A műveletek között definiálva van egy erősségi sorrend, az úgynevezett prioritás. Ez azt jelenti, hogy egy A m1 B m2 C alakú kifejezésben, ahol m2 magasabb prioritású művelet, mint m1, az A m1(B m2 C) zárójelezésnek megfelelően értékelődik ki. a < b && a + - 5 * b < 7 || c != b ((a < b) && ((a + ((- 5) * b)) < 7)) || (c != b) Programozás Alapjai (2008)

Programozás Alapjai (2008) Műveletek prioritása Prioritás csökkenő sorrendben: a prefix művelet (prefix -, prefix +, ! ) a multiplikatív műveletek ( *, /, % ) az additív műveletek ( +, - ) a kisebb-nagyobb relációs műveletek ( <=, >=, <, > ) az egyenlő-nem egyenlő műveletek ( ==, != ) a logikai 'és' művelet ( && ) a logikai 'vagy' művelet ( || ) Programozás Alapjai (2008)

Műveletek asszociativitása Azonos prioritású műveletek esetén a kiértékelést az asszociativitás iránya szerint kell elvégezni. Ez azt jelenti, hogy egy A m1 B m2 C alakú kifejezés, ahol m1 és m2 azonos prioritású műveletek, a balról-jobbra asszociativitás esetén (A m1 B) m2 C jobbról-balra asszociativitás esetén A m1 (B m2 C) zárójelezésnek megfelelően értékelődik ki. Az eddig ismertetett műveletek balról-jobbra asszociatívak. a + 5 – b – 7 + c (((a + 5) – b) – 7) + c Programozás Alapjai (2008)

Programozás Alapjai (2008) Logikai kifejezések A logikai kifejezések kiértékelése mindig a rövidített kiértékelés szerint történik, vagyis Az A || B kifejezés rövidített kiértékelése során először kiértékelődik az A logikai tag, ha ennek értéke igaz, akkor a B tag kiértékelése elmarad és természetesen a kifejezés értéke igaz lesz. Az A && B kifejezés rövidített kiértékelése során először kiértékelődik az A logikai tényező, ha ennek értéke hamis, akkor a B tényező kiértékelése elmarad és természetesen a kifejezés értéke hamis lesz. Programozás Alapjai (2008)

Numerikus kifejezések típusa Minden numerikus kifejezés int vagy float típusú. A kifejezés típusának meghatározása a kifejezés felépítése szerinti indukcióval a következő Tényező típusa: ha a tényező változó, akkor a deklarációjában megadott típus konstans, akkor a számleírás szerinti típus (K), akkor a K kifejezés típusa +T , akkor a T tényező típusa -T , akkor a T tényező típusa függvényhívás, akkor a függvényművelet eredménytípusa Programozás Alapjai (2008)

Numerikus kifejezések típusa (folyt.) Tag típusa: legyen A m B alakú a tag, ahol A és B tényezők, m pedig multiplikatív műveleti jel. Ha m %, akkor A és B típusa csak int lehet, és a tag típusa is int /, és A és B típusa is int, akkor az eredmény is int, és a művelet az egészosztás hányadosa /, és A vagy B float, akkor a tag típusa is float, és a művelet a valós osztás *, akkor az eredmény tag típusa csak akkor lesz int, ha mindkét operandus típusa int, egyébként pedig float Kifejezés típusa: ha a tagok mindegyike int típusú, akkor a kifejezés típusa is int, egyébként float. Programozás Alapjai (2008)

Programozás Alapjai (2008) A / művelet A / lehet maradékos osztás de valós osztás is 15 / 6 == 2 15.0 / 6 == 2.5 15 / 6.0 == 2.5 15.0 / 6.0 == 2.5 Programozás Alapjai (2008)

Programozás Alapjai (2008) Konverziók Az int adattípus nem része a float adattípusnak. float típusú változó vagy konstans akkor sem szerepelhet olyan műveletben, amely csak az int típus művelete (%), ha az értéke egész számértek. Megengedett azonban, hogy a float típus egy műveletének egyik argumentuma float, a másik argumentuma pedig int típusú legyen. A művelet eredményének típusa ekkor float lesz. Programozás Alapjai (2008)

Programozás Alapjai (2008) Konverziók (folyt.) Az ilyen művelet végrehajtása előtt az int típusú argumentum automatikusan átkonvertálódik float típusúvá. Ez a konverzió azonban tényleges műveletet jelent és így időt igényel. Ajánlatos a 2*x művelet helyett 2.0*x műveletet használni, ha x float típusú (még akkor is, ha a fordítóprogramok az ilyen típusú konverziót már fordítási időben el tudják végezni). Programozás Alapjai (2008)

Programozás Alapjai (2008) Értékadó művelet Az értékadás jele az = De ez művelet, és nem utasítás, vagyis a változóazonosító = kifejezés művelet eredménye a kifejezés aktuális értéke, amit a megfelelő programkomponensben is eltárolunk. Természetesen nincs akadálya a művelet többszöri alkalmazásának Az = művelet jobb-asszociatív, prioritása az eddig ismertetett műveletek után következik. i = j = k = 1; Programozás Alapjai (2008)

Programozás Alapjai (2008) Utasítások A ; zárja le műveletek sorozatát, tehát „utasítást csinál a kifejezésből”. A C-ben szokásos példa: kifejezés utasítás i = 1 i = 1; Programozás Alapjai (2008)

Összetett utasítások képzése Tudunk tehát kifejezésekből egyszerű utasításokat gyártani. Most mélyebb magyarázat nélkül átnézzük, hogy a C nyelv milyen lehetőségeket ad összetett utasítások képzésére. Programozás Alapjai (2008)

Programozás Alapjai (2008) Utasítások sorozata Ha az utasításokat adott sorrendben kell végrehajtani, akkor egyszerűen { és } jelek között az adott sorrendben egymás után leírjuk őket. Számoljuk ki, melyik órában (o), percben (p) melyik másodperc (m) lesz a nap 54321. másodperce. { e = 54321; o = e / 3600; e = e % 3600; p = e / 60; m = e % 60; } Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvények Egy C nyelven írt program tulajdonképpen nem más, mint függvények (megfelelően struktúrált és rendezett) összessége. Egy-egy függvény valamilyen bemenő adatok alapján kiszámol egy értéket, mint ahogyan azt a matematikában már megszokhattuk. Függvényeket lehet deklarálni, definiálni és meghívni. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvények (folyt.) Deklarációnál csak azt mondjuk meg, hogy mennyi és milyen típusú paraméterekből milyen típusú értéket fog kiszámolni a függvényünk. Definíciónál azt is meg kell adnunk, hogy hogyan számoljon. A függvényhívásnál pedig konkrét értékekre alkalmazzuk a függvényt, és a kiszámított értéket felhasználhatjuk további számolásainkhoz. Programozás Alapjai (2008)

Függvények szintaxisa C-ben Függvény deklaráció Függvény definíció (egyben deklaráció is) Függvény fejléc int f(int a, int b); Függvény fejléc ; int f(int a, int b) { return a+b; } Függvény fejléc { Utasítások } Azonosító Típus ( ) , Programozás Alapjai (2008)

Programozás Alapjai (2008) A return utasítás A return utasítás Minden függvényben szerepelnie kell legalább egy return utasításnak. Ha a függvényben egy ilyen utasítást hajtunk végre, akkor a függvény értékének kiszámítása befejeződik. A hívás helyén a függvény a return által kiszámított értéket veszi fel. int f(int a, int b) { return a+b; } Kifejezés return ; Programozás Alapjai (2008)

Függvényhívás szintaxisa C-ben Természetesen egy függvénynek a híváskor pontosan annyi és olyan típusú paramétert kell átadni, amennyi és amilyen paraméterekkel deklarálva lett. Azonosító ( ) Kifejezés , int c; c = f(3,5); Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvények A C nyelvben van a main függvénynek kitüntetett szerepe van. Amikor elindítjuk a programot, a vezérlés a main függvény elején indul, tehát ez a függvény viselkedik főprogramként. Az operációs rendszertől ez a függvény is kaphat paramétereket, de ezekkel egyelőre nem foglalkozunk. A main által kiszámított értéket szintén az operációs rendszer értelmezi (miután befejeződött a program), de erről is később lesz szó. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvények Írjunk egy programot, ami óra, perc, másodperc alapján egy függvény segítségével kiszámolja az éjfél óta eltelt másodperceket. int masodpercek(int ora, int perc, int masodperc) { return 3600 * ora + 60 * perc + masodperc; } int main() int mp1, mp2; mp1 = masodpercek(12, 5, 7); mp2 = masodpercek(6, 45, 0); Programozás Alapjai (2008)

Programozás Alapjai (2008) Az if utasítás Ha valamilyen feltétel alapján egyik vagy másik utasítást akarjuk végrehajtani Szintaxis Logikai kifejezés if else Utasítás ) ( Programozás Alapjai (2008)

Programozás Alapjai (2008) Az if utasítás Végre kell-e hajtani valamit? Számoljuk ki f abszolútértékét! Két utasítás közül az egyiket hajtsuk végre! a és b közül melyik a kisebb érték? if(f < 0) f = -f; if(f < 0) { f = -f; } if(a <= b) k = a; else k = b; if(a <= b) { k = a; } else { k = b; } Programozás Alapjai (2008)

Programozás Alapjai (2008) A switch utasítás Ha egy kifejezés értéke alapján többféle utasítás közül kell választanunk Szintaxis switch ( ) Kifejezés { } case default : Konstans Utasítás break ; Programozás Alapjai (2008)

Programozás Alapjai (2008) A switch utasítás Megadhatjuk, hogy hol kezdődjön és meddig tartson az utasítás-sorozat végrehajtása Gyakorlati jegyből csináljunk háromfokozatú minősítést! switch (gy) { case 5: case 4: printf("jól "); case 3: case 2: printf("megfelelt"); break; case 1: printf("nem felelt meg"); default: printf("nincs ilyen jegy"); } Programozás Alapjai (2008)

Programozás Alapjai (2008) A while utasítás Ha valamilyen műveletet mindaddig végre kell hajtani, amíg egy feltétel igaz. Ha a feltétel kezdetben hamis volt, a műveletet egyszer sem hajtjuk végre. (A feltétel ellenőrzése a művelet előtt történik.) Szintaxis Logikai kifejezés while Utasítás ( ) Programozás Alapjai (2008)

Programozás Alapjai (2008) A while utasítás A művelet végrehajtása nem szükséges a feltétel kiértékeléséhez Adjuk meg, hogy 0 fokról indulva adott mértékű pozitív irányú forgás után milyen irányban áll egy mutató. while (360 <= szog) { szog = szog – 360; } Programozás Alapjai (2008)

Programozás Alapjai (2008) A do while utasítás Ha valamilyen műveletet mindaddig végre kell hajtani, amíg egy feltétel igaz. A műveletet legalább egyszer végrehajtjuk akkor is, ha a feltétel kezdetben hamis volt. (A feltétel ellenőrzése a művelet után történik.) Szintaxis Logikai kifejezés while Utasítás ( ) do Programozás Alapjai (2008)

Programozás Alapjai (2008) A do while utasítás A művelet végrehajtása szükséges a feltétel kiértékeléséhez Kérjünk egy 0 és 999 közötti véletlenszámot, de zárjuk ki a 100 és 200 közötti számokat do { x = random() % 1000; } while ((100 <= x) && (x <= 200)) Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás Ha valamilyen műveletet sorban több értékére is végre kell hajtani, akkor ezt érdemes használni. Szintaxis Kifejezés for Utasítás ( ) ; Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás A C-ben a for utasítás általános alakja így néz ki: ami egyenértékű a alakkal. for (kif1; kif2; kif3) utasítás kif1; while (kif2) { utasítás kif3; } Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás Többnyire kif1 és kif3 értékadás vagy függvényhívás, kif2 pedig relációs kifejezés. A három kifejezés bármelyike elhagyható, de a pontosvesszőknek meg kell maradniuk. Ha kif1 vagy kif3 marad el, akkor a ; egyszerűen elmarad a kifejtésből. Ha a kif2 vizsgálat nem szerepel, akkor állandóan igaznak tekintjük, így végtelen ciklus, amelyből más módon kell kiugrani (pl. return vagy break révén). for (;;) { /* ... */ } Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás Hajtsunk végre egy műveletet adott számú alkalommal „És most büntetésből százszor leírod a nevedet!” Egy változót lépésenként ugyanúgy változtatunk Írassuk ki egy mértani sorozat elemeit a kezdőelem duplájáig for(i=0; i<100; i++) { printf("neved\n"); } for(x = a0; x < 2.0 * a0; x = q * x) { printf("%lf\n", x); } Programozás Alapjai (2008)

A break és continue utasítások A C nyelvben a ciklusmag folyamatos végrehajtásának megszakítására két utasítás használható: break Megszakítja a ciklust, a vezérlés a ciklusmag utáni első utasítással foglalkozik continue Megszakítja a ciklus aktuális lefutását, a vezérlés a ciklus feltételének kiértékelésével folytatódik Programozás Alapjai (2008)

Egyszerű ki- és bevitel Ahhoz, hogy egyszerű példát mutassunk be, szükségünk van beviteli és kiviteli utasításokra is. A nyelv nem tartalmaz ilyen utasításokat, de minden implementációban vannak standard függvénykönyvtárak ezek megvalósításaival. Programozás Alapjai (2008)

Egyszerű ki- és bevitel A ki- és bevitel használatához szükségünk van az sorra a program elején Ezek után használhatjuk az alábbi két függvényt: scanf(const char *, ...) a bemenetről tudunk olvasni printf(const char *, ...) a kimenetre tudunk írni #include <stdio.h> Programozás Alapjai (2008)

Egyszerű ki- és bevitel Anélkül, hogy a két függvényt részletesen elmagyaráznánk, egyelőre megmutatjuk, hogyan lehet int illetve float értékek beolvasására, valamint ugyanilyen típusú értékek és tetszőleges szöveg kiíratására használni őket. Programozás Alapjai (2008)

Egyszerű ki- és bevitel Mindkét függvény első paramétere egy úgynevezett formátumsztring, ami tulajdonképpen egy speciális szövegkonstans. Szöveg (szövegkonstans): ” Karakter, kivéve ” és \ \” \\ Programozás Alapjai (2008)

Egyszerű ki- és bevitel A printf használata: A szövegben az egyes kifejezések helyét a %d (int) és %f (float) karakterkombinációk jelzik: A \n hatására a kiírás végén új sor kezdődik ( printf Szöveg Kifejezés ) , printf("Hello world\n"); printf("Pi értéke kb. %f\n", 3.1415926); printf("%d + %d = %d\n", 2, 3, 2+3); Programozás Alapjai (2008)

Egyszerű ki- és bevitel A scanf használata: Az egyes beolvasandó számok típusát szintén %d (int) és %f (float) karakterkombinációk jelzik: ( scanf Szöveg Változó ) , & scanf("%d", &egesz); scanf("%f %f", &valos1, &valos2); Programozás Alapjai (2008)

Egyszerű ki- és bevitel Nagyon fontos, hogy a beolvasandó értékek illetve a kiírandó kifejezések számát és típusát sorban és pontosan adjuk meg. Egy float típusú kifejezés vagy változó esetén tehát akkor sem a %d kombinációt használjuk, ha tudjuk, hogy maga az érték egész, és int típusú kifejezés illetve változó esetén sem használhatjuk a %f –et. Az alábbi példák tehát hibásak: printf("%d", 10.0); printf("%f", 10); Programozás Alapjai (2008)

Egy C program felépítése Egy egyszerű C program így néz ki: /* A program adatai */ #include <stdio.h> main() { Változódeklarációk Utasítások } Programozás Alapjai (2008)

Egy C program felépítése Egy kevésbé egyszerű pedig így: /* A program adatai */ #include <stdio.h> Függvénydefiníciók main() { Változódeklarációk Utasítások } Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő Problémafelvetés Kiszámítandó a nap két időpontja között eltelt idő. Specifikáció A bemenő adat két időpont óra és perc formában, jelöljük ezeket O1, P1 illetve O2, P2-vel. A bemeneti feltétel: (0 <= O1 < 24) és (0 <= P1 < 60) (0 <= O2 < 24) és (0 <= P2 < 60) (O1 < O2) vagy (O1 == O2) és (P1 <= P2) A kimenő adatok O és P. A kimeneti feltétel: Az első időponttól a másodikig O óra és P perc telt el Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő (folyt.) Algoritmustervezés Az eltelt idő percben kifejezve (O2 * 60 + P2) - (O1 * 60 + P1) Tehát O, P akkor és csak akkor megoldás, ha O * 60 + P == (O2 * 60 + P2) - (O1 * 60 + P1) 0 <= P < 60 Ez tulajdonképpen a kimeneti feltételek formális megadása, de az első feltétel már mindenképpen az algoritmustervezés fázisához kapcsolódik Programozás Alapjai (2008)

Programozás Alapjai (2008) Szerkezeti ábra Az algoritmus tervezése során le kell írnunk valamilyen nyelvezetet használva azt, hogy a problémát milyen részproblémákra dekomponáltuk, és a megoldásukat milyen módon raktuk össze. Mi erre úgynevezett szerkezeti ábrát (structure diagram, struktúradiagram) használunk. Minden vezérlési módhoz bevezetünk egy szerkezeti ábra jelölést. Programozás Alapjai (2008)

Szerkezeti ábra tulajdonságai A szerkezeti ábra egyszerre fejezi ki az algoritmustervezés folyamatát és a kifejlesztett algoritmust is. Egy részprobléma megoldását leíró szerkezeti ábrarész különálló ábrával is kifejezhető, amelynek gyökerében a részprobléma megnevezése áll. Programozás Alapjai (2008)

Szekvenciális vezérlés A P problémát P1, ... , Pn részproblémákra bontjuk, és ezek megoldásait ebben a sorrendben egymás után végrehajtva kapjuk P megoldását P P1 P2 Pn P1, ... , Pn elemi műveletek, vagy részproblémák megnevezése. Utóbbi esetben a részproblémát tovább kell bontani. Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő (folyt.) Szerkezeti ábra Eltelt idő Számolás Beolvasás Kiíratás K = eltelt percek O és P kiszámolása K = (O2 * 60 + P2) - (O1 * 60 + P1) P = K/60 maradéka O = K/60 egészrésze Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő (folyt.) Az Eltelt idő algoritmusban használt változók O1, P1, O2, P2, O, P, K: valamennyi egész típusú, értékük tetszőleges egész szám lehet Az egész értékeken a következő műveleteket alkalmaztuk Összeadás (+) Kivonás (-) Szorzás (*) Osztás egészrésze (/) Osztás maradéka (%) Programozás Alapjai (2008)

Szekvenciális vezérlés C nyelven Kódolása C nyelven: { P1; P2; . Pn; } P P2 P1 Pn Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő /* * Egy nap két időpontja között mennyi idő telt el. * Készítette: Dévényi Károly, devenyi@inf.u-szeged.hu * 1997. Szeptember 26. Péntek */ #include <stdio.h> main() { int o1,p1; /* az első időpont */ int o2,p2; /* a második időpont */ int o,p; /* az eltelt idő */ int k; /* az eltelt idő percben */ >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő /* beolvasás */ printf("Kérem az első időpontot óra perc formában\n"); scanf("%d %d", &o1, &p1); printf("Kérem a második időpontot óra perc formában\n"); scanf("%d %d", &o2, &p2); /* számítás */ /* különbség számítás */ k = 60 * o2 + p2 - (60 * o1 + p1); o = k / 60; p = k % 60; /* kiíratás */ printf("Az eltelt idő: %d óra %d perc.\n", o, p); } Programozás Alapjai (2008)

Programozás Alapjai (2008) Eljárásvezérlés Adott művelet alkalmazása adott argumentumokra, ami az argumentumok értékének pontosan meghatározott változását eredményezi Az eljárásvezérlés fajtái Eljárásművelet Függvényművelet Programozás Alapjai (2008)

Eljárásvezérlés megvalósítása Vannak olyan programozási nyelvek, ahol a függvény és eljárásműveletek meg vannak különböztetve. Mivel azonban e kurzus keretében csak a C nyelvről lesz szó, egyelőre csak a függvényművelettel foglalkozunk, és a szerkezeti ábrán is igazodni fogunk a C nyelvhez. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A matematikai függvény fogalmának általánosítása. Ha egy részprobléma célja egy érték kiszámítása adott értékek függvényében, akkor a megoldást megfogalmazhatjuk függvényművelettel. Programozás Alapjai (2008)

Függvény specifikációja A függvényművelet specifikációja tartalmazza: A művelet elnevezését A formális argumentumok felsorolását Mindegyik argumentum adattípusát A függvényművelet eredménytípusát A művelet hatásának leírását Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A függvényművelet jelölésére a T F(T1 X1, ... ,Tn Xn) formát használjuk, ahol T a függvényművelet eredménytípusa F a függvényművelet neve Ti az i-edik formális argumentum adattípusa Xi az i-edik formális argumentum azonosítója A zárójeleket üres paraméterlista esetén is ki kell tenni. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A C jelölésmódhoz igazodva, a függvény algoritmusa egy olyan szerkezeti ábrával adható meg, melynek a feje így néz ki: Továbbá a szerkezeti ábrában lennie kell (legalább) egy olyan return utasításnak, amely visszaadja a függvény által kiszámított értéket. T F(T1 X1, ... ,Tn Xn) Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A fent jelölt függvényműveletnek adott A1, ..., An aktuális argumentumokra történő végrehajtását függvényhívásnak nevezzük és az F(A1, ... ,An) jelölést használjuk. A függvényhívás kifejezés. A zárójeleket paraméter nélküli függvény hívása esetén is ki kell tenni. Programozás Alapjai (2008)

Függvények szintaxisa C-ben Függvény deklaráció Függvény definíció (egyben deklaráció is) Függvény fejléc Függvény fejléc ; Függvény fejléc { Utasítások } Azonosító Típus ( ) , Programozás Alapjai (2008)

Függvények szintaxisa C-ben A return utasítás Minden függvényben szerepelnie kell legalább egy return utasításnak, amely kiszámítja a megadott kifejezés értékét, majd visszatér a függvényből. A hívás helyén a függvény a return által kiszámított értéket veszi fel. Kifejezés return ; Programozás Alapjai (2008)

Függvényhívás szintaxisa C-ben Természetesen egy függvénynek a híváskor pontosan annyi és olyan típusú paramétert kell átadni, amennyi és amilyen paraméterekkel deklarálva lett. Azonosító ( ) Kifejezés , Programozás Alapjai (2008)

Függvény megvalósítása Ha a függvény szerkezeti ábrája ez: Akkor a függvénydefiníció C-ben: T F(T1 X1, ... ,Tn Xn) M T F(T1 X1, ..., Tn Xn) { M; } Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet Például Régen C-ben a így kellett függvényt deklarálni: float atlag(float a, float b) { return (a + b)/2; } float atlag(a,b) float a, float b; { return (a + b)/2; } Programozás Alapjai (2008)

Eltelt idő Szerkezeti ábra int eltelt_percek(int ora1, int perc1, int ora2, int perc2) eltelt percek kiszámítása return (ora2 * 60 + perc2) - (ora1 * 60 + perc1) Programozás Alapjai (2008)

Eltelt idő (folyt.) Szerkezeti ábra Eltelt idő Számolás Beolvasás Kiíratás O és P kiszámolása P = eltelt_percek(O1, P1, O2, P2) /60 maradéka O = eltelt_percek(O1, P1, O2, P2) /60 egészrésze Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő /* * Egy nap két időpontja között mennyi idő telt el. * Készítette: Gergely Tamás, gertom@inf.u-szeged.hu * 2007. Augusztus 30. */ #include <stdio.h> int eltelt_percek(int ora1, int perc1, int ora2, int perc2) { return 60 * ora2 + perc2 - (60 * ora1 + perc1); } >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Eltelt idő main() { int o1,p1; /* az első időpont */ int o2,p2; /* a második időpont */ int o,p; /* az eltelt idő */ /* beolvasás */ printf("Kérem az első időpontot óra perc formában\n"); scanf("%d %d", &o1, &p1); printf("Kérem a második időpontot óra perc formában\n"); scanf("%d %d", &o2, &p2); /* számítás */ /* különbség számítás */ o = eltelt_percek(o1, p1, o2, p2) / 60; p = eltelt_percek(o1, p1, o2, p2) % 60; /* kiíratás */ printf("Az eltelt idő: %d óra %d perc.\n", o, p); } Programozás Alapjai (2008)

Szelekciós vezérlések Szelekciós vezérléssel azt írjuk elő, hogy véges sok rögzített művelet közül, véges sok adott feltétel alapján, melyik művelet kerüljön végrehajtásra. Típusai: Egyszerű Többszörös Esetkiválasztásos A fenti három „egyébként” ággal Programozás Alapjai (2008)

Egyszerű szelekciós vezérlés Egyszerű szelekció esetén egy feltétel és egy művelet van. Legyen F logikai kifejezés, A pedig tetszőleges művelet. Az F feltételből és az A műveletből képzett egyszerű szelekciós vezérlés a következő vezérlési előírást jelenti: 1.) Értékeljük ki az F feltételt és folytassuk a 2.) lépéssel. 2.) Ha F értéke igaz, akkor hajtsuk végre az A műveletet és fejezzük be az összetett művelet végrehajtását. 3.) Egyébként, vagyis ha F értéke hamis, akkor fejezzük be az összetett művelet végrehajtását. Programozás Alapjai (2008)

Egyszerű szelekciós vezérlés A vezérlés bővíthető úgy, hogy a 3. pontban üres művelet helyett egy B műveletet hajtunk végre. Legyen F logikai kifejezés, A és B pedig tetszőleges művelet. Az F feltételből és az A és B műveletből képzett egyszerű szelekciós vezérlés a következő vezérlési előírást jelenti: 1.) Értékeljük ki az F feltételt és folytassuk a 2.) lépéssel. 2.) Ha F értéke igaz, akkor hajtsuk végre az A műveletet és fejezzük be az összetett művelet végrehajtását. 3.) Egyébként, vagyis ha F értéke hamis, hajtsuk végre B-t és fejezzük be az összetett műveletet végrehajtását. Programozás Alapjai (2008)

Egyszerű szelekciós vezérlés Az egyszerű szelekciós vezérlés szerkezeti ábrája F i n A Programozás Alapjai (2008)

Egyszerű szelekciós vezérlés Az egyébként ággal kiegészített egyszerű szelekciós vezérlés szerkezeti ábrája F i n A B Programozás Alapjai (2008)

Egyszerű szelekciós vezérlés A vezérlés lényege: Ha az F feltétel igaz, hajtsuk végre az A műveletet. Ha az F feltétel hamis, hajtsuk végre a B műveletet. Programozás Alapjai (2008)

Többszörös szelekciós vezérlés Ha a szelekciós vezérlésben a feltételek száma nagyobb, mint egy, akkor többszörös szelekcióról beszélünk. Ekkor minden kiválasztó feltételhez tartozik egy alternatív művelet. Legyenek Fi logikai kifejezések, Ai pedig tetszőleges műveletek (1<=i<=n). Programozás Alapjai (2008)

Többszörös szelekciós vezérlés Az Fi kiválasztó feltételekből valamint az Ai műveletekből képzett többszörös szelekciós vezérlés a következő vezérlési előírást jelenti: 1.) Az Fi feltételek kiértékelésével adjunk választ a következő kérdésre: Van-e olyan i (1<=i<=n), amelyre teljesül, hogy az Fi feltétel igaz és az összes Fj (1<=j<i) feltétel hamis? Folytassuk a 2.) lépéssel. 2.) Ha van ilyen i, akkor hajtsuk végre az Ai műveletet és fejezzük be az összetett művelet végrehajtását. 3.) Egyébként, vagyis ha minden Fi feltétel hamis, akkor fejezzük be az összetett művelet végrehajtását. Programozás Alapjai (2008)

Többszörös szelekciós vezérlés Bővíthetjük a többszörös szelekciós vezérlést azzal, hogy a 3.) pontban ne az üres művelet, hanem egy előre megadott B tetszőleges művelet végrehajtását írjuk elő. Legyenek Fi logikai kifejezések, Ai és B pedig tetszőleges műveletek (1<=i<=n). Programozás Alapjai (2008)

Többszörös szelekciós vezérlés Az Fi kiválasztó feltételekből, valamint az Ai és B műveletekből képzett többszörös szelekciós vezérlés a következő vezérlési előírást jelenti: 1.) Az Fi feltételek kiértékelésével adjunk választ a következő kérdésre: Van-e olyan i (1<=i<=n), amelyre teljesül, hogy az Fi feltétel igaz és az összes Fj (1<=j<i) feltétel hamis? Folytassuk a 2.) lépéssel. 2.) Ha van ilyen i, akkor hajtsuk végre az Ai műveletet és fejezzük be az összetett művelet végrehajtását. 3.) Egyébként, vagyis ha minden Fi hamis, hajtsuk végre B-t és fejezzük be az összetett művelet végrehajtását. Programozás Alapjai (2008)

Többszörös szelekciós vezérlés A többszörös szelekciós vezérlés szerkezeti ábrája ? F1 F2 Fn A1 A2 An Programozás Alapjai (2008)

Többszörös szelekciós vezérlés Az egyébként ággal kiegészített többszörös szelekciós vezérlés szerkezeti ábrája ? F1 F2 Fn A1 A2 An B Programozás Alapjai (2008)

Többszörös szelekciós vezérlés A vezérlés lényege Hajtsuk végre a legelső olyan Ai műveletet, aminek az Fi feltétele igaz. Ha nincs olyan Fi ami igaz, akkor hajtsuk végre a B műveletet. Programozás Alapjai (2008)

Háromszögek osztályozása Problémafelvetés Milyen háromszöget határoz meg három valós szám, mint a háromszög három oldalhosszúsága? Specifikáció A probléma inputja A,B,C valós számok Outputja a következő szövegek egyike ‘nem háromszög’, ‘szabályos háromszög’, ‘egyenlőszárú háromszög’, ‘egyenlőszárú derékszögű háromszög’, ‘derékszögű háromszög’, ‘egyéb háromszög’ Programozás Alapjai (2008)

Háromszögek osztályozása Algoritmustervezés: fogalmazzuk meg a feltételeket magyarul és a matematika nyelvén ‘nem háromszög’ ‘szabályos háromszög’ ‘egyenlőszárú háromszög’ ‘egyenlőszárú derékszögű háromszög’ ‘derékszögű háromszög’ ‘egyéb háromszög’ Programozás Alapjai (2008)

Háromszögek osztályozása Algoritmustervezés A feltételek megfogalmazása érdekében célszerűnek látszik a bemenő adatokat úgy átrendezni, hogy az A változó tartalmazza a legnagyobb értéket. Ekkor a feltételek rendre NP feltétel: (A<=0) vagy (B<=0) vagy (C<=0) N feltétel: A >= B + C Sz feltétel: (A == B) és (B == C) E feltétel: (A == B) vagy (B == C) vagy (A == C) D feltétel: A2 = B2 + C2 Az osztályozás eredményét közvetlenül kiírjuk. Programozás Alapjai (2008)

Háromszögek osztályozása Struktúradiagram Háromszögek osztályozása Átrendezés Beolvasás Osztályozás Programozás Alapjai (2008)

Háromszögek osztályozása Struktúradiagram Osztályozás ? NP Nem N SZ Szabályos E Egyenlőszárú D Derékszögű Egyéb i n Egyenlőszárú derékszögű Programozás Alapjai (2008)

Háromszögek osztályozása Struktúradiagram Átrendezés A és B átrendezése A<B i n A=B A és C átrendezése A és B cseréje M=A B=M A<C A=C A és C cseréje C=M Programozás Alapjai (2008)

Programozás Alapjai (2008) Az if utasítás Ha valamilyen feltétel alapján egyik vagy másik utasítást akarjuk végrehajtani Szintaxis Logikai kifejezés if else Utasítás ) ( Programozás Alapjai (2008)

Egyszerű szelekciós vezérlés Az egyszerű szelekciós vezérlés szerkezeti ábrája és C megvalósítása F i n if ( F ) { A; } A Programozás Alapjai (2008)

Egyszerű szelekciós vezérlés Az egyébként ággal kiegészített egyszerű szelekciós vezérlés szerkezeti ábrája és C megvalósítása F i n if ( F ) { A; } else { B; } A B Programozás Alapjai (2008)

Többszörös szelekció megvalósítása C nyelvben nincs külön utasítás a többszörös szelekció megvalósítására, ezért az egyszerű szelekció ismételt alkalmazásával kell azt megvalósítani. Ez azon az összefüggésen alapszik, hogy a többszörös szelekció levezethető egyszerű szelekciók megfelelő összetételével. Programozás Alapjai (2008)

Többszörös szelekció megvalósítása Az alábbi két ábra ugyanazt a vezérlési előírást fejezi ki. ? B A1 An A2 F1 Fn F2 F1 i n A1 F2 A2 Fn An B Programozás Alapjai (2008)

Többszörös szelekció megvalósítása A többszörös szelekciós vezérlés szerkezeti ábrája és C megvalósítása if ( F1 ) { A1; } else if ( F2 ) { A2; ... } else if ( Fn ) { An; } ? A1 An A2 F1 Fn F2 Programozás Alapjai (2008)

Többszörös szelekció megvalósítása Az egyébként ággal kiegészített többszörös szelekciós vezérlés szerkezeti ábrája és C megvalósítása if ( F1 ) { A1; } else if ( F2 ) { A2; ... } else if ( Fn ) { An; } else { B; } ? B A1 An A2 F1 Fn F2 Programozás Alapjai (2008)

Háromszögek osztályozása /* Milyen háromszöget határoz meg három pozitiv valós szám, * mint a háromszög három oldalhosszúsága? * 1997. Október 13. Dévényi Károly */ #include <stdio.h> main() { float A, B, C; /* a háromszög oldalhosszúságai */ float M; /* munkaváltozó a cseréhez */ printf("Kérem a három pozitív valós számot!\n"); scanf("%f%f%f", &A, &B, &C); >>> Programozás Alapjai (2008)

Háromszögek osztályozása /* A,B,C átrendezése úgy, hogy A>=B,C legyen */ if (A < B) { /* A és B átrendezése */ M = A; A = B; B = M; } if (A < C) { /* A és C átrendezése */ A = C; C = M; /* osztályozás */ if (A <= 0 || B <= 0 || C <= 0) { printf(" Nem háromszög!\n"); /* 1. alternatíva */ >>> Programozás Alapjai (2008)

Háromszögek osztályozása } else if (A >= B + C) { printf(" Nem háromszög!\n"); /* 2. alternatíva */ } else if (A == B && B == C) { printf(" Szabályos háromszög.\n"); /* 3. alternatíva */ } else if (A == B || B == C || A == C) { if (A * A == B * B + C * C) { /* 4. alternatíva */ printf(" Egyenlőszárú derékszögű háromszög.\n"); } else { printf(" Egyenlőszárú háromszög.\n"); } } else if (A * A == B * B + C * C) { printf(" Derékszögű háromszög.\n"); /* 5. alternatíva */ printf(" Egyéb háromszög.\n"); /* egyébként */ } /* vége a többszörös szelekciónak */ Programozás Alapjai (2008)

if utasítások ismételt alkalmazása Az if utasítások ismételt alkalmazása esetén figyelembe kell venni, hogy a következő utasítás a mellette látható vezérlési szerkezet megvalósítása F1 if ( F1 ) if ( F2 ) A1; else A2; i n F2 i n A1 A2 Programozás Alapjai (2008)

if utasítások ismételt alkalmazása Az if utasítások ismételt alkalmazása esetén figyelembe kell venni, hogy a következő utasítás a mellette látható vezérlési szerkezet megvalósítása F1 if ( F1 ) { if ( F2 ) A1; else A2; } i n F2 i n A1 A2 Programozás Alapjai (2008)

if utasítások ismételt alkalmazása Az if utasítások ismételt alkalmazása esetén figyelembe kell venni, hogy a következő utasítás a mellette látható vezérlési szerkezet megvalósítása F1 if ( F1 ) { if ( F2 ) A1; } else { A2; } i n F2 A2 i n A1 Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés A többszörös szelekció egy speciális esete az, amikor minden Fi (1<=i<=n) feltétel így szól: Egy adott K kifejezés aktuális értéke eleme-e az értékek egy előre megadott Hi halmazának? Vagyis legyen a K egy szelektor kifejezés, Hi kiválasztó halmazok, Ai pedig tetszőleges műveletek (1<=i<=n). Ezekből képzett esetkiválasztásos szelekciós vezérlés a következő vezérlési előírást jelenti: Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés 1.) Értékeljük ki a K kifejezést és folytassuk a 2.) lépéssel. 2.) Adjunk választ a következő kérdésre: Van-e olyan i (1<=i<=n), amelyre teljesül, hogy a kiszámolt érték eleme a Hi halmaznak és nem eleme az összes Hj (1<=j<i) halmaznak? Folytassuk a 3.) lépéssel. 3.) Ha van ilyen i, akkor hajtsuk végre az Ai műveletet és fejezzük be az összetett művelet végrehajtását. 4.) Egyébként, vagyis ha a kiszámolt érték nem eleme a Hi (1<=i<=n) halmazok egyesítésének, akkor fejezzük be az összetett művelet végrehajtását. Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés Bővíthetjük az esetkiválasztásos szelekciós vezérlést azzal, hogy a 4.) pontban ne az üres művelet, hanem egy előre megadott B tetszőleges művelet végrehajtását írjuk elő. Legyen a K egy szelektor kifejezés, Hi kiválasztó halmazok, Ai és B pedig tetszőleges műveletek (1<=i<=n). Ezekből képzett esetkiválasztásos szelekciós vezérlés a következő vezérlési előírást jelenti: Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés 1.) Értékeljük ki a K kifejezést és folytassuk a 2.) lépéssel. 2.) Adjunk választ a következő kérdésre: Van-e olyan i (1<=i<=n), amelyre teljesül, hogy a kiszámolt érték eleme a Hi halmaznak és nem eleme az összes Hj (1<=j<i) halmaznak? Folytassuk a 3.) lépéssel. 3.) Ha van ilyen i, akkor hajtsuk végre az Ai műveletet és fejezzük be az összetett művelet végrehajtását. 4.) Egyébként, vagyis ha a kiszámolt érték nem eleme a Hi (1<=i<=n) halmazok egyesítésének, akkor hajtsuk végre a B műveletet és fejezzük be az összetett művelet végrehajtását. Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés Az esetkiválasztásos szelekciós vezérlés szerkezeti ábrája K ? A1 An A2 H1 Hn H2 Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés Az egyébként ággal kiegészített esetkiválasztásos szelekciós vezérlés szerkezeti ábrája K ? B A1 An A2 H1 Hn H2 Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés A vezérlés lényege Értékeljük ki a K kifejezést. Hajtsuk végre a legelső olyan Ai műveletet, aminek a Hi halmazában benne van a K értéke. Ha K értéke nem eleme egyetlen Hi halmaznak sem, akkor hajtsuk végre a B műveletet. Programozás Alapjai (2008)

Esetkiválasztásos szelekciós vezérlés A kiválasztó halmazok megadása az esetkiválasztásos szelekció kritikus pontja. Algoritmusok tervezése során minden effektív halmazmegadást használhatunk, azonban a tényleges megvalósításkor csak a választott programozási nyelv eszközeit alkalmazhatjuk. Programozás Alapjai (2008)

Programozás Alapjai (2008) Dátum helyessége Problémafelvetés Eldöntendő, hogy egy dátumként megadott számpár helyes dátum-e? Specifikáció Input Egy (hónap, nap) alakban megadott dátum Output A dátum akkor és csak akkor helyes, ha 1 <= hónap <= 12 és a nap érték is a megfelelő intervallumba esik. Programozás Alapjai (2008)

Programozás Alapjai (2008) Dátum helyessége Algoritmustervezés Dátum Hónap ? 2 Jó= (1<=Nap) És (Nap<=28) 1,3,5,7,8,10,12 4,6,9,11 Be(Hónap,Nap) Kiíratás Jó= (1<=Nap) És (Nap<=30) Jó= (1<=Nap) És (Nap<=31) Jó=Hamis Programozás Alapjai (2008)

Programozás Alapjai (2008) A switch utasítás Ha egy kifejezés értéke alapján többféle utasítás közül kell választanunk Szintaxis switch ( ) Kifejezés { } case default : Konstans Utasítás break ; Programozás Alapjai (2008)

Programozás Alapjai (2008) A switch utasítás A szelektor kifejezés és a konstansok típusának meg kell egyeznie. Egy konstans legfeljebb egyszer szerepelhet case mögött egy switch utasításban. A default kulcsszó csak egyszer szerepelhet egy switch utasításban. Programozás Alapjai (2008)

Esetkiv. szelekció megvalósítása Az esetkiválasztásos szelekciós vezérlés C megvalósítása switch (K) { case H1 : A1; break; ... case Hn : An; } K ? A1 An A2 H1 Hn H2 Programozás Alapjai (2008)

Esetkiv. szelekció megvalósítása Az egyébként ággal kiegészített esetkiválasztásos szelekciós vezérlés C megvalósítása switch (K) { case H1 : A1; break; ... case Hn : An; default : B; } K ? B A1 An A2 H1 Hn H2 Programozás Alapjai (2008)

A switch utasítás tulajdonságai C-ben a H1, ..., Hn halmazok csak egyeleműek lehetnek, amelyeket így egyszerűen az elem megadásával jelölhetünk. A hatékonyabb kódolás érdekében azonban kihasználhatjuk a switch utasítás tulajdonságát: A K kifejezés értékétől csak az függ, hogy melyik helyen kezdjük el végrehajtani a switch magját. Ha a végrehajtás elkezdődik, akkor onnantól kezdve az első break utasításig, vagy a switch végéig sorban hajtódnak végre az utasítások. Programozás Alapjai (2008)

A switch utasítás tulajdonságai Tegyük fel, hogy a H1 halmaz elemei x1,x2, ... ,xm Ezt C-ben a kódrészlettel tudjuk lekódolni. case x1: case x2: ... case xm: A1; break; Programozás Alapjai (2008)

A switch utasítás tulajdonságai A default ág olyan, mintha a K kifejezés összes lehetséges de a switch-ben fel nem sorolt értékét megadnánk egy-egy case ággal. Így a default ág a switch magján belül tetszőleges helyen lehet, de csak akkor kezdődik itt a vezérlés, ha a kifejezés aktuális értéke egyetlen case-ben sem szerepel, beleértve a default után megadott case-eket is. Éppen ezért a default ágban is mindig használjunk break utasítást. Programozás Alapjai (2008)

Logikai adattípus C nyelven Az algoritmustervezés során használtunk egy „Jó” nevű változót, amely logikai értéket tárolt. A C nyelvben nincs logikai típus, de azért logikai értékek persze keletkeznek. Ezeket az értékeket eltárolhatjuk egy int változóban. Ha egy logikai értéket egy int típusú változóba tettünk, akkor a logikai hamis érték tárolása után az int típusú változó értéke 0, az igaz érték tárolása után pedig nem 0. (Sok megvalósításban 1, de ezt nem használhatjuk ki, ha gépfüggetlen programot szeretnénk.) Programozás Alapjai (2008)

Programozás Alapjai (2008) Dátum helyessége /* Eldöntendő, hogy egy dátumként megadott számpár helyes dátum-e? * 1997. Október 4. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> main() { int Honap, Nap; int Jo; /* a Boolean érték tárolására */ printf("Kérem a dátumot (hónap, nap) !\n"); scanf("%d%d", &Honap, &Nap); switch (Honap) { case 2: Jo = (1 <= Nap && Nap <= 28); break; >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Dátum helyessége case 4: case 6: case 9: case 11: Jo = (1 <= Nap && Nap <= 30); break; case 1: case 3: case 5: case 7: case 8: case 10: case 12: Jo = (1 <= Nap && Nap <= 31); >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Dátum helyessége default: Jo = 0; break; } /* switch */ /* Kiíratás */ printf("A dátum "); if (!Jo) { /* Ezt másképpen szokták */ printf("nem "); } printf("helyes.\n"); Programozás Alapjai (2008)

Programozás Alapjai (2008) Feltételes kifejezés A feltételes operátor a C nyelv egyetlen háromoperandusú művelete. A K&R könyv feltételes kifejezésnek említi. Először a kif1 kerül kiértékelésre, ha ez Igaz (nem 0), a kifejezés értéke kif2 lesz Hamis (0), a kifejezés értéke kif3 lesz kif1 ? kif2 : kif3 Programozás Alapjai (2008)

Programozás Alapjai (2008) Feltételes kifejezés Az előző programban a kiíratás ez volt: printf("A dátum "); if (!Jo) { printf("nem "); } printf("helyes.\n"); Programozás Alapjai (2008)

Programozás Alapjai (2008) Feltételes kifejezés Ez lerövidíthető: vagy printf("A dátum "); printf(Jo ? " " : " nem "); printf("helyes.\n"); printf(Jo ? "A dátum helyes.\n" : "A dátum nem helyes.\n"); Programozás Alapjai (2008)

Programozás Alapjai (2008) Feltételes kifejezés Illesszük be prioritási sorba az = és a ?: műveleteket! prefix művelet (prefix -, ! ) multiplikatív műveletek ( *, /, % ) additív műveletek ( +, - ) kisebb-nagyobb relációs műveletek ( <=, >=, <, > ) egyenlő-nem egyenlő relációs műveletek ( ==, != ) logikai 'és' művelet ( && ) logikai 'vagy' művelet ( || ) feltételes művelet ( ? : ) értékadó művelet ( = ) Programozás Alapjai (2008)

Programozás Alapjai (2008) Feltételes kifejezés Így a következő programrészlet átírható így: vagy akár: if (a > b) { z = a; } else { z = b; } z = (a > b) ? a : b; z = a > b ? a : b; Programozás Alapjai (2008)

Ismétléses vezérlések Ismétléses vezérlésen olyan vezérlési előírást értünk, amely adott műveletnek adott feltétel szerinti ismételt végrehajtását írja elő. Az ismétlési feltétel szerint öt formáját különböztetjük meg az ismétléses vezérléseknek 1. Kezdőfeltételes 2. Végfeltételes 3. Számlálásos 4. Hurok 5. Diszkrét Programozás Alapjai (2008)

Ismétléses vezérlések Az algoritmustervezés során a leginkább megfelelő ismétléses vezérlési formát használjuk, függetlenül attól, hogy a megvalósításra használt programozási nyelvben közvetlenül megvalósítható-e ez a vezérlési mód. Ismétléses vezérlés képzését ciklusszervezésnek is nevezik, így az ismétlésben szereplő műveletet ciklusmagnak hívjuk. Programozás Alapjai (2008)

Kezdőfeltételes ismétléses vezérlés Legyen F logikai kifejezés, M pedig tetszőleges művelet. Az F ismétlési feltételből és az M műveletből (a ciklusmagból) képzett kezdőfeltételes ismétléses vezérlés a következő vezérlési előírást jelenti 1.) Értékeljük ki az F feltételt és folytassuk a 2.) lépéssel. 2.) Ha F értéke hamis, akkor az ismétlés és ezzel együtt az összetett művelet végrehajtása befejeződött. 3.) Egyébként, vagyis ha az F értéke igaz, akkor hajtsuk végre az M műveletet, majd folytassuk az 1.) lépéssel. Programozás Alapjai (2008)

Kezdőfeltételes ismétléses vezérlés A kezdőfeltételes ismétléses vezérlés szerkezeti ábrája F M Programozás Alapjai (2008)

Kezdőfeltételes ismétléses vezérlés Az algoritmus tervezésekor a ciklusmag olyan részprobléma megoldása is lehet, aminek a megoldását a tervezés adott stádiumában még nem ismerjük. Ekkor a ciklusmag helyére a részprobléma megnevezését írjuk, majd ehhez kapcsoljuk a tervezés során a ciklusmagot megfogalmazó szerkezeti ábrarészt. Programozás Alapjai (2008)

Kezdőfeltételes ismétléses vezérlés Ha az F értéke hamis, az összetett művelet végrehajtása befejeződik anélkül, hogy az M művelet egyszer is végrehajtásra kerülne Ha az F értéke igaz, és az M művelet nincs hatással az F feltételre, akkor F igaz is marad, tehát az összetett művelet végrehajtása nem tud befejeződni. Ilyenkor végtelen ciklus végrehajtását írtuk elő. Fontos tehát, hogy az M művelet hatással legyen az F feltételre. Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimax program Problémafelvetés Határozzuk meg egy valós számsorozat legkisebb és legnagyobb elemét, valamint a sorozat átlagát! Specifikáció A probléma inputja a valós számsorozat. Az input számsorozat végét egy végjel fogja jelezni, amit a felhasználó ad meg inputként, nyilván a számsorozat előtt. Az output a sorozat legkisebb és legnagyobb eleme, valamint az átlaga. Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimax program Algoritmustervezés Elsőre talán az tűnne a legegyszerűbb megoldásnak, ha beolvasnánk az összes számot, majd ezek között keresgélnénk. Ez a megoldás egy összetett adatszerkezetet (tömböt) igényelne. Ha viszont végiggondoljuk, a „következő” elem beolvasásakor elegendő az eddigi sorozatból csak a lényeges információkat tárolni: a legkisebb elem értékét, a legnagyobb elem értékét, az elemek összegét, és az elemek darabszámát. Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimax program Algoritmustervezés Minimax Szám!=Végjel Összeg=Összeg+Szám Db=Db+1 Inicializálás Szám feldolgozása Be(Szám) Szám<Min i n Min=Szám Kiíratás Szám>Max Max=Szám Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimax program Algoritmustervezés Inicializálás Összeg=0 Be(Szám) Min=Szám Be(Végjel) Max=Szám Db=0 Db==0 i n Kiíratás Ki(„Üres sorozat”) Ki(Min,Max,Átlag) Programozás Alapjai (2008)

Programozás Alapjai (2008) A while utasítás Ha valamilyen műveletet mindaddig végre kell hajtani, amíg egy feltétel igaz. Ha a feltétel kezdetben hamis volt, a műveletet egyszer sem hajtjuk végre. (A feltétel ellenőrzése a művelet előtt történik.) Szintaxis Logikai kifejezés while Utasítás ( ) Programozás Alapjai (2008)

A kezdőfeltételes vezérlés megvalósítása A kezdőfeltételes ismétléses vezérlés szerkezeti ábrája és C megvalósítása Az M utasítás tetszőleges, összetett utasítás lehet. F M while ( F ) { M; } Programozás Alapjai (2008)

Programozás Alapjai (2008) A C értékadó műveletei Mielőtt elhamarkodottan lekódolnánk a szerkezeti ábrán található programot, megismerkedünk a C nyelv azon műveleteivel, amelyek használata tömörré teszi a programok kódját. Programozás Alapjai (2008)

Inkrementáló és dekrementáló műv. A C nyelv tartalmaz két operátort, amelyekkel változók inkrementálhatók és dekrementálhatók. A ++ inkrementáló operátor az operandusához 1-et ad hozzá A -- dekrementáló operátor az operandusából 1-et von le A ++ és a -- egyaránt használható prefix operátorként (++i, --i ) postfix operátorként (i++, i--) Programozás Alapjai (2008)

Inkrementáló és dekrementáló műv. Az i változó a prefix és postfix használat esetén is pontosan eggyel nő (csökken) A különbség a kétféle használat között az, hogy prefix művelet esetén a ++i (--i) kifejezés értéke az i változó új, azaz eggyel megnövelt (csökkentett) értéke postfix esetben az i++ (i--) kifejezés értéke az i eredeti értéke Tehát ha nem csak a művelet inkrementáló (dekrementáló) tulajdonságát, hanem a kifejezés értékét is felhasználjuk, akkor a pre- és postfix használat között különbség van. Programozás Alapjai (2008)

Inkrementáló és dekrementáló műv. Például, ha i értéke 5, akkor az x-et 5-re állítja, de x-et 6-ra állítja. i értéke mindkét esetben 6 lesz. Ezek az operátorok csak változókra (l-value) alkalmazhatók; az olyan kifejezés, mint nem megengedett! x = i++; x = ++i; (i + j)++ Programozás Alapjai (2008)

Értékadó műveletek és kifejezések Az olyan kifejezések, mint például a += értékadó operátor segítségével az tömörített alakban is írhatók. A C-ben a legtöbb operátornak megvan az op= alakú megfelelője, ahol az op egy műveleti szimbólum. Az eddig megismertek közül op lehet: + - * / % i = i + 2 i += 2 Programozás Alapjai (2008)

Értékadó műveletek és kifejezések Ha e1 és e2 kifejezés, akkor e1 op= e2 jelentése e1 = (e1) op (e2) Ügyeljünk az e2 körüli zárójelekre: nem pedig x *= y + 1 x = x * (y + 1) x = (x * y) + 1 Programozás Alapjai (2008)

Értékadó műveletek és kifejezések Illesszük be a prioritási sorba a ++ és -- valamint az értékadó műveleteket! a egyoperandusú műveletek (prefix -, ++, --, ! ) a multiplikatív műveletek ( *, /, % ) az additív műveletek ( +, - ) a kisebb-nagyobb relációs műveletek ( <=, >=, <, > ) az egyenlő-nem egyenlő relációs műveletek ( ==, != ) a logikai 'és' művelet ( && ) a logikai 'vagy' művelet ( || ) a feltételes művelet ( ? : ) értékadó művelet ( =, +=, -=, *=, /=, %= ) Programozás Alapjai (2008)

Értékadó műveletek és kifejezések Az értékadó műveletek természetesen mind jobb-asszociatívak. Óvatosan és csak a céljának megfelelően szabad használni ezeket a műveleteket. Nézzünk néhány példát! Programozás Alapjai (2008)

Értékadó műveletek és kifejezések Mi lesz a kiírt érték? Nálunk ez 49, de lehetne 42 vagy 56 is. Az ANSI szabvány szerint az aritmetikai részkifejezések kiértékelésének sorrendje tetszőleges. Tehát i értékét csak akkor inkrementáljuk, ha i sehol máshol nem szerepel az egész kifejezésben. int i = 7; printf("%d\n", i-- * i++); Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimax program /* Határozzuk meg egy valós számsorozat legkisebb * és legnagyobb elemét, valamint a sorozat átlagát! * 1997. Október 25. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> main() { double Vegjel, Szam, Osszeg, Min, Max, Atlag; int Db; /* az összegzett elemek száma */ printf("Ez a program valós számsorozat minimális,\n"); printf("maximális elemét és átlagát számolja.\n"); printf("Az input sorozatot végjel zárja.\n"); printf("Kérem a végjelet!\n"); /* inicializálás */ scanf("%lf", &Vegjel); >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimax program printf("Kérem az input számsorozatot!\n"); printf("? "); scanf("%lf", &Szam); Min = Max = Szam; Osszeg = 0.0; Db = 0; while (Szam != Vegjel) { /* a ciklus kezdete */ Osszeg += Szam; /* összegzés */ Db++; /* számláló növelés */ if (Szam < Min) { /* min-max számítás */ Min = Szam; } else if (Szam > Max) { Max = Szam; } /* a következő szám beolvasása */ } /* a ciklus vége */ >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Minimax program if (Db == 0) { printf("Üres számsorozat érkezett.\n"); } else { Atlag = Osszeg / Db; printf("Minimum = %10.3f Maximum= %10.3f\n", Min, Max); printf("Az átlag = %10.3f\n", Atlag); } Programozás Alapjai (2008)

Végfeltételes ismétléses vezérlés Az F ismétlési feltételből és M műveletből (ciklusmagból) képzett végfeltételes ismétléses vezérlés a következő vezérlési előírást jelenti 1.) Hajtsuk végre az M műveletet majd folytassuk a 2.) lépéssel. 2.) Értékeljük ki az F feltételt és folytassuk a 3.) lépéssel. 3.) Ha F értéke igaz, akkor az ismétléses vezérlés és ezzel együtt az összetett művelet végrehajtása befejeződött. 4.) Egyébként, vagyis ha az F értéke hamis, akkor folytassuk az 1.) lépéssel. Programozás Alapjai (2008)

Végfeltételes ismétléses vezérlés A végfeltételes ismétléses vezérlés szerkezeti ábrája F M Programozás Alapjai (2008)

Végfeltételes ismétléses vezérlés Látható, hogy a végfeltételes ismétléses vezérlés alapvetően abban különbözik a kezdőfeltételes ismétléses vezérléstől, hogy a ciklusmag legalább egyszer végrehajtódik. Programozás Alapjai (2008)

Végfeltételes ismétléses vezérlés Ha az M művelet nincs hatással az F feltételre, akkor Ha az F értéke igaz, igaz is marad, így az M művelet egyszer került végrehajtásra és az összetett művelet végrehajtása befejeződik Ha az F értéke hamis, hamis is marad, tehát az összetett művelet végrehajtása nem tud befejeződni. Ilyenkor végtelen ciklus végrehajtását írtuk elő Fontos tehát, hogy az M művelet hatással legyen az F feltételre. Programozás Alapjai (2008)

Ismétléses vezérlések kapcsolata A kezdő és végfeltételes ismétléses vezérlések kifejezhetőek egymás segítségével. F M !F F M !F i n Programozás Alapjai (2008)

Ismétléses vezérlések kapcsolata Az algoritmus tervezésekor előfordulhat, hogy mind a kezdőfeltételes ismétléses vezérlés, mind a végfeltételes ismétléses vezérlés alkalmasnak látszik a probléma megoldására. Ilyenkor érdemes megvizsgálni, hogy az F feltétel szükséges feltétele-e az M művelet végrehajtásának? Ha igen, akkor a kezdőfeltételes ismétléses vezérlést kell választani. Programozás Alapjai (2008)

Programozás Alapjai (2008) Szinusz Problémafelvetés Szinusz(x) közelítő értékének kiszámítása Specifikáció Input X valós szám Outputja sin(X) Nem hívhatjuk meg a C standard sin(x) függvényét Programozás Alapjai (2008)

Programozás Alapjai (2008) Szinusz Algoritmustervezés Ismeretes, hogy sin(x) értéke az x - x3/3! + x5/5! - ... +(-1)(i-1)*x(2i-1)/(2i-1)! +... végtelen sor összege. Ezen végtelen sor kezdőszeletének összegével közelítjük sin(x) értékét, úgy, hogy az összegzés befejeződik, ha az utolsó tag abszolút értéke kisebb, mint a konstansként megadott epsz pontosság. Programozás Alapjai (2008)

Programozás Alapjai (2008) Szinusz Algoritmustervezés Nyilvánvaló, hogy nem célszerű a számolást úgy szervezni, hogy i minden értékére külön kiszámoljuk a tagot, hiszen az i. tag kiszámolható az (i-1)-ik tagból. A tag számlálójának és nevezőjének külön számolása egyébként is pontatlanná tenné a számítást, mert mindkettő, különösen a nevező rohamosan növekedik i függvényében. Programozás Alapjai (2008)

Szinusz Struktúradiagram Szinusz Abs(Tag)<Epsz Összeg=Összeg+Tag Inicializálás Következő tag kiszámítása j+=2 Tag= -Tag*XX/j/(j+1) Ki(Összeg) Programozás Alapjai (2008)

Programozás Alapjai (2008) Szinusz A float típus tulajdonságai miatt nem érdemes abszolút értékben nagy X értékekkel számolni. Kihasználjuk, hogy a sin(x) függvény periodikus. Inicializálás Tag=X X transzf. Osszeg=0.0 Be(X) j=2 XX=X*X Xorig=X X<-Pi X+=2.0*Pi Pi<X X-=2.0*Pi Programozás Alapjai (2008)

Programozás Alapjai (2008) A do while utasítás Ha valamilyen műveletet mindaddig végre kell hajtani, amíg egy feltétel igaz. A műveletet legalább egyszer végrehajtjuk akkor is, ha a feltétel kezdetben hamis volt. (A feltétel ellenőrzése a művelet után történik.) Szintaxis Logikai kifejezés while Utasítás ( ) do Programozás Alapjai (2008)

A végfeltételes vezérlés megvalósítása A végfeltételes ismétléses vezérlés szerkezeti ábrája és C megvalósítása Az M utasítás tetszőleges, összetett utasítás lehet. F M do { M; } while ( !F ) Programozás Alapjai (2008)

Programozás Alapjai (2008) Szinusz /* sin(x) közelítő értékének kiszámítása a beépített sin(x) * függvény alkalmazása nélkül. * X értékét transzformáljuk a (-Pi,Pi) intervallumba. * 1997. Október 25. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> #include <math.h> #define EPSZ 1e-10 /* a közelítés pontossága */ main() { double Osszeg; /* a végtelen sor kezdőösszege */ double Tag; /* a végtelen sor aktuális tagja */ double X; /* argumentum */ double Xorig; /* az argumentum értékének megőrzése*/ double XX; /* sqr(x) */ int j; /* a nevező kiszámításához */ >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Szinusz printf("Kérem sin(x)-hez az argumentumot\n"); scanf("%lg%*[^\n]", &X); getchar(); /* ez most már ReadLn */ Xorig = X; while (X < -M_PI) { /* transzformálás */ X += 2 * M_PI; } while (M_PI < X) { X -= 2 * M_PI; Osszeg = 0.0; j = 2; /* inicializálás */ Tag = X; XX = X * X; >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Szinusz do { /* ciklus kezdete */ Osszeg += Tag; Tag = -(Tag * XX / j / (j + 1)); /* következő tag */ j += 2; } while (fabs(Tag) >= EPSZ); /* végfeltétel, ciklus vége */ printf("sin(%8.5f)= %13.10f\n", Xorig, Osszeg); } Programozás Alapjai (2008)

Programozás Alapjai (2008) Eljárásvezérlés Adott művelet alkalmazása adott argumentumokra, ami az argumentumok értékének pontosan meghatározott változását eredményezi Az eljárásvezérlés fajtái Eljárásművelet Függvényművelet Programozás Alapjai (2008)

Programozás Alapjai (2008) Eljárásművelet Eljárásműveleten olyan tevékenységet értünk, amelynek alkalmazása adott argumentumokra az argumentumok értékének pontosan meghatározott megváltozását eredményezi. Minden eljárásműveletnek rögzített számú argumentuma van, és minden argumentum rögzített adattípusú. Az argumentumok lehetnek Bemenő argumentumok Kimenő argumentumok Be- és kimenő argumentumok Programozás Alapjai (2008)

Argumentumok kezelési módjai Bemenő argumentum Ha a művelet bármely végrehajtása nem változtatja meg az adott argumentum értékét. Kimenő argumentum Ha a művelet hatása nem függ az adott argumentumnak a végrehajtás előtti értékétől, azonban az adott argumentum értéke a művelet hatására megváltozhat. Be- és kimenő argumentum Ha a művelet hatása függ az adott argumentumnak a végrehajtás előtti értékétől, és az adott argumentum értéke a művelet hatására megváltozhat. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A matematikai függvény fogalmának általánosítása. Ha egy részprobléma célja egy érték kiszámítása adott értékek függvényében, akkor a megoldást megadhatjuk függvényművelettel. A függvényművelet argumentumai ugyanúgy lehetnek kimenő és be- és kimenő módúak is, mint az eljárásműveletek esetén, tehát a függvényművelet végrehajtása az aktuális argumentumok megváltozását is eredményezheti. Programozás Alapjai (2008)

Eljárás és függvény specifikációja Eljárásművelet specifikációja tartalmazza: A művelet elnevezését A formális argumentumok felsorolását Mindegyik argumentum adattípusát és kezelési módját A művelet hatásának leírását A függvényművelet specifikációja a fentieken túl tartalmazza még: A függvényművelet eredménytípusát Programozás Alapjai (2008)

Eljárásművelet általános jelölése Eljárásműveletek (általános) jelölése: P(m1 X1:T1; ... ;mn Xn:Tn) ahol P az eljárásművelet neve Xi az i-edik formális argumentum azonosítója mi az i-edik formális argumentum kezelési módja -> bemenő mód <- kimenő mód <-> be- és kimenő mód. Ti az i-edik formális argumentum adattípusa Programozás Alapjai (2008)

Eljárásművelet általános jelölése Az eljárásműveletnek adott A1, ... ,An aktuális argumentumokra történő végrehajtását eljárásutasításnak (eljáráshívásnak) nevezzük Jelölése P(A1, ... ,An) Ha az i-edik argumentum módja kimenő vagy be- és kimenő, akkor az Ai aktuális argumentum csak változó lehet. Programozás Alapjai (2008)

Programozás Alapjai (2008) Eljárásművelet Algoritmustervezés során nem csak elemi (eleve definiált) eljárásműveleteket használhatunk. Részproblémák megoldását is kifejezhetjük olyan eljárásműveletekkel, melyek megvalósítását részprogrammal adjuk meg. A részprogramot különálló szerkezeti ábrával írjuk le, amelynek feje P(m1 X1:T1; ... ;mn Xn:Tn) Programozás Alapjai (2008)

Függvényművelet általános jelölése Függvényműveletek (általános) jelölése F(m1 X1:T1; ... ;mn Xn:Tn):T ahol F az függvényművelet neve Xi az i-edik formális argumentum azonosítója mi az i-edik formális argumentum kezelési módja Ti az i-edik formális argumentum adattípusa T a függvényművelet eredménytípusa Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A fent jelölt függvényműveletnek adott A1, ... ,An aktuális argumentumokra történő végrehajtását függvényhívásnak nevezzük Jelölése F(A1, ... ,An) Részproblémák megoldását függvényművelettel is kifejezhetjük, ekkor a szerkezeti ábra feje F(m1 X1:T1; ... ;mn Xn:Tn):T Programozás Alapjai (2008)

Eljárásvezérlés megvalósítása Vannak olyan programozási nyelvek, ahol a függvény és eljárásműveletek meg vannak különböztetve, valamint a paraméterek módjaira sincs megkötés. Mivel azonban e kurzus keretében csak a C nyelvről lesz szó, a szerkezeti ábrán a továbbiakban (is) igazodni fogunk a C nyelvhez. Programozás Alapjai (2008)

Eljárásvezérlés megvalósítása A C nyelvben lényegében csak függvényművelet van. C nyelvben a függvényművelet argumentumai bemenő módúak, tehát alapvetően a függvényművelet végrehajtása az aktuális argumentumok megváltozását nem eredményezheti. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A függvényművelet jelölésére a továbbiakban a T F(T1 X1, ... ,Tn Xn) formát használjuk, ahol T a függvényművelet eredménytípusa F a függvényművelet neve Ti az i-edik formális argumentum adattípusa Xi az i-edik formális argumentum azonosítója A zárójeleket üres paraméterlista esetén is ki kell tenni. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A C jelölésmódhoz igazodva, a függvényművelet szerkezeti ábrájának a feje így néz ki: Továbbá a szerkezeti ábrában lennie kell (legalább) egy olyan return utasításnak, amely visszaadja a függvény által kiszámított értéket. T F(T1 X1, ... ,Tn Xn) Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet A fent jelölt függvényműveletnek adott A1, ... ,An aktuális argumentumokra történő végrehajtását függvényhívásnak nevezzük és az F(A1, ... ,An) jelölést használjuk. A függvényhívás kifejezés. A zárójeleket paraméter nélküli függvény hívása esetén is ki kell tenni. Programozás Alapjai (2008)

Függvények szintaxisa C-ben Függvény deklaráció Függvény definíció (egyben deklaráció is) Függvény fejléc Függvény fejléc ; Függvény fejléc { Utasítások } Azonosító Típus ( ) , Programozás Alapjai (2008)

Függvények szintaxisa C-ben A return utasítás Minden függvényben szerepelnie kell legalább egy return utasításnak, amely kiszámítja a megadott kifejezés értékét, majd visszatér a függvényből. A hívás helyén a függvény a return által kiszámított értéket veszi fel. Kifejezés return ; Programozás Alapjai (2008)

Függvényhívás szintaxisa C-ben Természetesen egy függvénynek a híváskor pontosan annyi és olyan típusú paramétert kell átadni, amennyi és amilyen paraméterekkel deklarálva lett. Azonosító ( ) Kifejezés , Programozás Alapjai (2008)

Függvény megvalósítása Ha a függvény szerkezeti ábrája ez: Akkor a függvénydefiníció C-ben: T F(T1 X1, ... ,Tn Xn) M T F(T1 X1, ..., Tn Xn) { M; } Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvényművelet Például Régen C-ben a így kellett függvényt deklarálni: float atlag(float a, float b) { return (a + b)/2; } float atlag(a,b) float a, float b; { return (a + b)/2; } Programozás Alapjai (2008)

Programozás Alapjai (2008) Eljárásművelet Ha eljárást szeretnénk készíteni, akkor a függvényművelet eredménytípusa void és ebben az esetben nem kötelező a return utasítás, illetve ha mégis van ilyen, akkor nem adható meg utána kifejezés. Programozás Alapjai (2008)

Vegyes és kimenő módú arg. Mint említettük, C-ben csak bemenő módú argumentumok vannak. De mi magunk kezelhetjük a be- és kimenő illetve kimenő módú argumentumokat pointerek segítségével. Az alábbiakban egy, az alaptípusokra működő megoldást mutatunk. Programozás Alapjai (2008)

Vegyes és kimenő módú arg. Ha az i. paramétert kimenő módúnak szeretnénk, akkor a függvény deklarációjában Ti Xi helyett Ti *Xi deklarációt, a függvénytörzsben pedig Xi helyett mindenhol (*Xi) változóhivatkozást használunk. Programozás Alapjai (2008)

Vegyes és kimenő módú arg. Továbbá a függvény meghívásakor az Ai paraméter helyett az &Ai paramétert írjuk. Részletesebb magyarázatot és összetettebb típusokra működő megvalósítást a pointerek megismerése után adunk. Programozás Alapjai (2008)

Kamatos-kamat számítás Problémafelvetés Számítsunk kamatos kamatot Specifikáció Input Osszeg valós, a betett összeg Kamatláb egész, az éves alapkamat Ev egész, az eltelt évek száma Output Ujosszeg a kamatos-kamattal növelt érték Programozás Alapjai (2008)

Kamatos-kamat számítás Algoritmustervezés A kamatos-kamat számításhoz készítünk egy általános hatványozó függvényt és ezt hívjuk meg a kamatos-kamat számítás alapképletével. double hatvany(double X, int n) ? hatv= 1.0 n==0 hatv= 0.0 X==0 hatv= exp(n*ln(X)) X>0 hatv= -exp(n*ln(-X)) Odd(n) hatv= exp(n*ln(-X)) return hatv Programozás Alapjai (2008)

Bitenkénti logikai műveletek A C nyelvben több bitmanipulációs operátor van, ezek a float és double típusú változókra nem alkalmazhatók. & bitenkénti ÉS, | bitenkénti megengedő (inkluzív) VAGY, ^ bitenkénti kizáró (exkluzív) VAGY, << bitléptetés (shift) balra, >> bitléptetés (shift) jobbra, ~ egyes komplemens (egyoperandusú). Programozás Alapjai (2008)

Bitenkénti logikai műveletek A bitenkénti ÉS operátort gyakran használjuk valamely bithalmaz maszkolására. Például a páratlan(x) függvényt az ((x & 1) == 1) valósítja meg. A műveletekről később részletesen is lesz szó. Programozás Alapjai (2008)

Bitenkénti logikai műveletek Illesszük be prioritási sorba a műveleteket! a egyoperandusú műveletek ( -, ++, --, !, ~ ) a multiplikatív műveletek ( *, /, % ) az additív műveletek ( +, - ) bitléptetés ( <<, >> ) a kisebb-nagyobb relációs műveletek ( <=, >=, <, > ) az egyenlő-nem egyenlő relációs műveletek ( ==, != ) bitenkénti 'és' művelet ( & ) bitenkénti 'kizáró vagy' művelet ( ^ ) bitenkénti 'vagy' művelet ( | ) a logikai 'és' művelet ( && ) a logikai 'vagy' művelet ( || ) a feltételes művelet ( ? : ) értékadó művelet ( =, +=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |= ) Programozás Alapjai (2008)

Kamatos-kamat számítás /* Kamatos-kamat számítás a hatványozás függvény segítségével. * 1997. Október 31. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> #include <math.h> >>> Programozás Alapjai (2008)

Kamatos-kamat számítás double hatvany(double x, int n) { /* x n-edik hatványát kiszámító függvény */ double hatv; if (n == 0) { hatv = 1.0; } else if (x == 0.0) { hatv = 0.0; } else if (x > 0.0) { hatv = exp(n * log(x)); } else if (n & 1) { hatv = (-exp(n * log(-x))); } else { hatv = exp(n * log(-x)); } return(hatv); >>> Programozás Alapjai (2008)

Kamatos-kamat számítás main() { double Osszeg, Ujosszeg; int Kamatlab, Ev; printf(" A kamatozó összeg ? "); scanf("%lg%*[^\n]", &Osszeg); getchar(); printf(" A kamatláb ? "); scanf("%d%*[^\n]", &Kamatlab); getchar(); printf(" A kamatozási évek száma ? "); scanf("%d%*[^\n]", &Ev); getchar(); Ujosszeg = Osszeg * hatvany(1.0 + Kamatlab / 100.0, Ev); printf("A kamatos kamattal növelt összeg:"); printf("%10.2f\n", Ujosszeg); } Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben A C nyelvben blokkon {} zárójelpárba zárt blokkot értünk. Egy C program blokkjai mellérendeltségi és alárendeltségi viszonyban vannak. Ezt a viszonyt az ide vonatkozó szabályokkal együtt blokkstruktúrának nevezzük. Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben 1. Sorrendiségi szabály A program egy adott helyén csak olyan azonosítóra hivatkozhatunk, amely a hivatkozás helyét megelőzően deklarálva lett. Változó azonosító, függvény azonosító és típus azonosító megjelenése helyén deklaráltnak minősül. 2. Egyediségi szabály Egy adott blokkban deklarált minden azonosító csak egyszer deklarálható, nem számítva az alárendelt blokkokat. Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben main() { int b, b; a = 0; printf("? "); scanf("%d", &b); b = f(b); printf("%d (%d)\n", b, a); } int a; int f(int n) { a++; return (n>1) ? f(n-1) + f(n-2) : 1; Itt egyszerre két változót deklarálunk, és mindkettőnek a b nevet adjuk. Ha ezt megtehetnénk, hogy döntené el a fordító, hogy melyik esetben melyik változóval kellene dolgoznia? Itt pedig használjuk az f és az a azonosí- tókat, holott még azt sem tudjuk, hogy melyik micsoda. Itt már jogos az f és az a használata is, mert ezeken a pontokon már mindkettő deklarálva van, még ha f definíciója még nincs is teljesen befejezve. Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben 3. Láthatósági szabály Egy B1 blokkban deklarált A azonosító akkor és csak akkor látható (hivatkozható) egy B2 blokkban, ha teljesül az alábbi két feltétel: a.) B1 megegyezik B2-vel, vagy B2 alárendeltje B1-nek és az A azonosító előbb van deklarálva, mint B2 b.) Az A azonosító nincs deklarálva egyetlen olyan C blokkban sem, amely alárendeltje B1-nek és amelynek B2 alárendeltje (beleértve azt, hogy B2 vagy megegyezik C-vel) Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben int a, b, c; { /* 2. BLOKK */ float c; a = 2; } c = 1; { /* 3. BLOKK */ float b; { /* 4. BLOKK */ b = 3.4; A fent deklarált a változó használható ezen a ponton, hiszen: a 2. blokk alárendeltje az 1. blokknak, a előbb van deklarálva mint a 2. blokk, nincs olyan blokk a kettő között, amelyben a deklarálva lenne. Ezen a ponton az 1. blokkban deklarált c változó használható. A 2. blokkban deklarált c ezen a ponton NEM használható, hiszen az 1. blokk nem alárendeltje a 2. blokknak. Így az itt leírt c az 1. blokkban deklarált c változót jelenti. Az 1. blokkban deklarált b ezen a ponton NEM használható, mert a 4. blokk ugyan alárendeltje az 1. blokknak, és később fordul elő, mint b 1. blokkbeli deklarációja, de van közben egy 3. blokk, amelynek a 4. blokk szintén alárendeltje, és amiben b szintén deklarálva van. A 3. blokkban deklarált b viszont használható, így azután a 4. blokkban leírt b a 3. blokk változóját jelenti. Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben Azon blokkok összességét, amelyből egy A azonosító látható, az A azonosító hatáskörének nevezzük. Egy azonosítót lokálisnak nevezünk egy blokkra nézve, ha az azonosító az adott blokkban van deklarálva. Azt mondjuk, hogy egy A azonosító globális egy B blokkra nézve, ha nem B-ben van deklarálva, de látható B-ben. Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben A blokkstruktúra alapján látható, hogy a C nyelvben vannak úgynevezett lokális változók, sőt általában ezeket használjuk. Látható azonban az is, hogy a programfájlban deklarált programegységek globálisak az összes függvénydeklarációra nézve, vagyis ezek minden blokkban láthatóak a deklarálásuktól kezdve az újradeklarálásukig. Ezeket csak nagyon indokolt esetben szoktuk használni. Programozás Alapjai (2008)

Blokkstruktúra a C nyelvben Megjegyzések gcc-hez: A gcc néha elviseli, ha egy függvényt hamarabb használunk, mint ahogyan deklarálnánk (tehát megsértjük a sorrendiségi szabályt). A hívásból ugyanis ki tudja deríteni a paraméterek számát és típusát, a visszatérési értéket viszont ilyen esetekben int-ként kezeli. Az ansi C nem engedi meg a deklarációk és utasítások keveredését, tehát már a blokk elején deklarálni kell az összes változót. A gcc ennél rugalmasabb, már warningot is csak a –pedantic kapcsolóval ad ilyen esetekre. Programozás Alapjai (2008)

Programozás Alapjai (2008) Tárolási osztályok auto Az auto az automatikus memóriafoglalásra utal. Ezt az alapszót nem szoktuk kiírni. static A lokális változó értéke megmarad a blokk végrehajtása után is és az újabb függvényművelet végrehajtásakor a megőrzött érték felhasználható. extern A programegységet csak deklaráljuk, de nem ebben a fájlban kerül definiálásra. A szerkesztőprogram feladata lesz a külső hivatkozás feloldása. Programozás Alapjai (2008)

Programozás Alapjai (2008) Tárolási osztályok /* A static változót mutatjuk be. * 1997. November 7. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> void stat(); main() { int i; /* ciklusváltozó */ for (i = 0; i < 5; i++) { stat(); } >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Tárolási osztályok void stat() { int ideiglenes = 1; static int allando = 1; printf("ideiglenes = %d allando = %d\n", ideiglenes, allando); ideiglenes++; allando++; } Programozás Alapjai (2008)

Programozás Alapjai (2008) Tárolási osztályok A példaprogram ezt írja ki: ideiglenes = 1 allando = 1 ideiglenes = 1 allando = 2 ideiglenes = 1 allando = 3 ideiglenes = 1 allando = 4 ideiglenes = 1 allando = 5 Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai Problémafelvetés: Egy oszlopon egyre csökkenő átmérőjű korongok vannak. Pakoljuk át a korongokat egy másik oszlopra úgy, hogy Egyszerre csak egy korongot mozgatunk, amelyik valamelyik oszlop tetején van Nagyobb átmérőjű korong nem kerülhet kisebbre Rendelkezésre áll egy kezdetben szabad oszlop is Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai Specifikáció: Input Db pozitiv egész szám, a torony magassága Két különböző, pozitiv egész szám: Honnan és Hova (1<=Honnan, Hova<=3), melyek jelentése, hogy melyik toronyról melyik toronyra kell átpakolni. Output Egy tevékenységsorozat szövegesen, amit mechanikusan végrehajtva ténylegesen átpakolhatjuk a tornyot. Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai Algoritmustervezés: Készítsünk egy rekurzív eljárást, amelyik az N magasságú torony átpakolását visszavezeti az N-1 magasságú torony átpakolására. Az 1 magasságú torony átpakolása nem igényel előkészületet, azonnal elvégezhető. Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai Algoritmustervezés: Az N magasságú torony átpakolását visszavezetjük az N-1 magasságú torony átpakolására. Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai Megjegyzés: Mivel az X magasságú torony, amit az egyik rúdról a másikra pakolunk mindig az X legkisebb korongból áll, a harmadik rudat akkor is használhatjuk segédrúdként, ha azon van korong, mivel ez biztosan nagyobb, mint a legnagyobb, amit mi át szeretnénk pakolni. Programozás Alapjai (2008)

Hanoi tornyai Algoritmustervezés: void Hanoi( int N, int Rol, int Ra) Mozgat(Rol, Ra) Hanoi(N-1,Rol,6-Rol-Ra) N-1 magas tornyot tegyük a segédre Hanoi(N-1,6-Rol-Ra,Ra) n N-1 magas tornyot tegyük a helyére Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai /* A Hanoi tornyai játék megvalósítása rekurzív eljárással. * 1997. Október 31. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> int Honnan; /* erről a toronyról kell átrakni */ int Hova; /* erre a toronyra */ int Db; /* a torony ennyi korongból áll */ void Mozgat(int Innen, int Ide) { /* Átrak egy korongot Innen Ide */ printf(" Tegyünk át egy korongot"); printf(" a %d. oszlopról a %d. oszlopra!\n", Innen, Ide); } >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai void Hanoi(int N, /* ilyen magas a torony */ int Rol, /* erről a toronyról */ int Ra) /* erre a toronyra */ { if (N == 1) { Mozgat(Rol, Ra); } else { Hanoi(N - 1, Rol, 6 - Ra - Rol); Hanoi(N - 1, 6 - Ra - Rol, Ra); } >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Hanoi tornyai main(int argc, char *argv[]) { printf("Kérem adja meg a torony magasságát: "); scanf("%d%*[^\n]", &Db); getchar(); printf("Kérem adja meg, hogy a torony hol áll? (1,2,3) "); scanf("%d%*[^\n]", &Honnan); printf("Kérem adja meg, hogy melyik oszlopra tegyük át? "); scanf("%d%*[^\n]", &Hova); if (Db > 0 && 1 <= Honnan && Honnan <= 3 && 1 <= Hova && Hova <= 3 && Honnan != Hova) { Hanoi(Db, Honnan, Hova); } else { printf("Hibás adat\n"); } Programozás Alapjai (2008)

Programozás Alapjai (2008) Rekurzió Az előző példában rekurzív függvénydeklarációt láthattunk. A C nyelven bármelyik függvény lehet rekurzív illetve részt vehet rekurzív függvényrendszerben. Programozás Alapjai (2008)

Programozás Alapjai (2008) Végrehajtás Az F(A1, ... ,An) függvényművelet végrehajtása sorrendben a következő tevékenységeket jelenti 1.) Memória helyfoglalás a függvényblokk paraméterei és lokális változói számára. int A(int X) { int i, k; ... i=3; k=A(X-1); X=5; } int E,F; int main() { ... E=A(E+F); } X k i E=2 E=2 F=8 F=8 Programozás Alapjai (2008)

Programozás Alapjai (2008) Végrehajtás 2.) Paraméterátadás. Először tetszőleges sorrendben kiértékelődnek az aktuális paraméterek. Mivel mind értékparaméter, az i-edik kiértékelt aktuális paraméter értéke átadódik az i-edik formális paraméternek, vagyis az aktuális paraméter értéke bemásolódik a formális paraméter számára foglalt memóriahelyre. int A(int X) { int i, k; ... i=3; k=A(X-1); X=5; } int E,F; int main() { ... E=A(E+F); } X X=10 k k i i E=2 E=2 F=8 F=8 Programozás Alapjai (2008)

Programozás Alapjai (2008) Végrehajtás 3.) A függvényblokk utasításrészének végrehajtása. int A(int X) { int i, k; ... i=3; k=A(X-1); X=5; } int E,F; int main() { ... E=A(E+F); } X=10 X=5 k k=34 i i=3 E=2 E=2 F=8 F=8 Programozás Alapjai (2008)

Programozás Alapjai (2008) Végrehajtás 4.) A függvényblokk formális paraméterei és lokális változói számára foglalt memória felszabadítása. int A(int X) { int i, k; ... i=3; k=A(X-1); X=5; } int E,F; int main() { ... E=A(E+F); } X=5 k=34 i=3 E=2 E=65 F=8 F=8 Programozás Alapjai (2008)

Végrehajtás (rekurzió) R:1-2.) Rekurzió esetén (mint bármely függvényhívásnál) ugyanezek a lépések fognak végrehajtódni, tehát minden függvényhíváshoz saját változók tartoznak. X X=9 k k int A(int X) { int i, k; ... i=3; k=A(X-1); X=5; } i int E,F; int main() { ... E=A(E+F); } i X=10 X=10 X=10 k k k i=3 i=3 i=3 E=2 E=2 E=2 F=8 F=8 F=8 Programozás Alapjai (2008)

Végrehajtás (rekurzió) R:3-4.) A rekurzióból (mint bármely függvényhívásból) visszatérve az elhagyott függvény paraméterei és lokális változói szűnnek meg, majd a hívó függvény folytatódik. X=9 X=5 k k=21 i int A(int X) { int i, k; ... i=3; k=A(X-1); X=5; } i=3 int E,F; int main() { ... E=A(E+F); } X=10 X=10 X=5 k k k=34 i=3 i=3 i=3 E=2 E=2 E=2 F=8 F=8 F=8 Programozás Alapjai (2008)

Programozás Alapjai (2008) Végrehajtás A C nyelven blokknak hívjuk a program {} zárójelek közötti részét is, és itt is lehet programelemeket deklarálni. Egy ilyen blokk végrehajtása a következő három tevékenységet jelenti: 1.) Memória helyfoglalás a blokk lokális változói számára. 2.) A blokk utasításrészének végrehajtása. 3.) A blokk lokális változói számára foglalt memória felszabadítása. A memória azon részét, ahol a fenti tevékenységek lezajlanak, veremnek nevezzük. Programozás Alapjai (2008)

Függvények mellékhatása Függvény mellékhatásán azt értjük, hogy a függvényhívás hatására nem csak a függvényérték számítódik ki, hanem megváltozhat egy globális változó értéke is. Mellékhatás következménye, hogy az összeadás kommutativitása nem feltétlenül teljesül, ha a tagok függvényhívások. Programozás Alapjai (2008)

Függvények mellékhatása Vegyük az alábbi példát int A,B,Z; int f(int x) { int r; r = x + A; A = x + 1; return r; } main () { A = 1; B = 2; Z = f(A) + f(B); /* f(A)+f(B) == 6 */ /* f(B)+f(A) == 9 */ Programozás Alapjai (2008)

Függvények mellékhatása A mellékhatást kerülni kell! Egy változót tehát vagy globális változóként használjunk, vagy aktuális paraméterként, de egyszerre mindkét céllal ne! A C-ben nincs meghatározva, hogy két részkifejezés közül melyiket kell előbb kiértékelni, tehát az sem világos, hogy ha mindkettőben van függvényhívás, melyik hajtódik végre előbb. Programozás Alapjai (2008)

Programozás Alapjai (2008) Függvények előnyei Függvények használata programozás során a következő előnyöket biztosítja Többszörös felhasználás. Hasonló részproblémák megoldására elég egy függvényt készíteni és a különböző adatokra végrehajtatni a részalgoritmust. Így a program méretét csökkenteni lehet. Memória igény csökkentése. Az függvények lokális változói számára csak az függvény végrehajtása idejére foglalódik memória. Függvények használatával a program áttekinthetőbb lesz. A tervezés során a részproblémák függvénnyel történő megoldása lehetővé teszi a figyelem lokalizálását. Függvények alkalmazása megkönnyíti a bizonyítást, a program tesztelését, a hibakeresést, a javítást és a program módosítását. Programozás Alapjai (2008)

Számlálásos ismétléses vezérlés Számlálásos ismétléses vezérlésről beszélünk, ha olyan ismétlést írunk elő, amely szerint a ciklusmagot végre kell hajtani egy változó minden olyan értékére (növekvő vagy csökkenő sorrendben), amely egy adott intervallumba esik. Legyen a és b valamely egész érték i egész típusú változó M tetszőleges művelet Programozás Alapjai (2008)

Növekvő számlálásos vezérlés Szerkezeti ábra A növekvő számlálásos ismétléses vezérlés a következő vezérlési előírást jelenti i = a -> b M i=a i <= b M i++ Programozás Alapjai (2008)

Növekvő számlálásos vezérlés Szokásos elnevezések i változó, a ciklusváltozó a kifejezés, az ismétlés kezdőértéke b kifejezés, az ismétlés végértéke M utasítás (művelet), a ciklusmag i = a -> b az ismétlési előírás Fontos, hogy az M művelet nem lehet hatással az ismétlési előírás egyik elemére sem. Programozás Alapjai (2008)

Csökkenő számlálásos vezérlés Szerkezeti ábra A csökkenő számlálásos ismétléses vezérlés a következő vezérlési előírást jelenti i = a <- b M i=b i >= a M i-- Programozás Alapjai (2008)

Csökkenő számlálásos vezérlés Szokásos elnevezések i változó, a ciklusváltozó b kifejezés, az ismétlés kezdőértéke a kifejezés, az ismétlés végértéke M utasítás (művelet), a ciklusmag i = a <- b az ismétlési előírás Fontos, hogy az M művelet nem lehet hatással az ismétlési előírás egyik elemére sem. Programozás Alapjai (2008)

Programozás Alapjai (2008) n alatt k Problémafelvetés n alatt k kiszámítása Specifikáció Input n és k nemnegatív egész számok Output n alatt k értéke Programozás Alapjai (2008)

Programozás Alapjai (2008) n alatt k Algoritmustervezés Készítsünk az n alatt k kiszámolására egy függvénydeklarációt Ismeretes, hogy n alatt k = n!/(k!*(n-k)!). Nyilvánvaló, hogy nem célszerű a számolást úgy szervezni, hogy a faktoriálisokat egyenként kiszámoljuk, hiszen ezek nagy értékek lehetnek és így kiléphetünk az Integer értékkészletből. A nevező egyik tényezőjével egyszerűsítve egy törtet kapunk, amelynek a számlálója is és a nevezője is azonos számú tényezőből álló szorzat. Ez indokolja a számlálásos ismétléses vezérlés alkalmazását. Programozás Alapjai (2008)

Programozás Alapjai (2008) n alatt k int nAlk(int n, int k) (n>=k) && (k>=0) i n i = 1 -> k nak = 0 nak = nak*(n-i+1) / i nak =1 return nak Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás Ha valamilyen műveletet sorban több értékére is végre kell hajtani, akkor ezt érdemes használni. Szintaxis Kifejezés for Utasítás ( ) ; Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás A C-ben a for utasítás általános alakja így néz ki: ami egyenértékű a alakkal. for (kif1; kif2; kif3) utasítás kif1; while (kif2) { utasítás kif3; } Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás Többnyire kif1 és kif3 értékadás vagy függvényhívás, kif2 pedig relációs kifejezés. A három kifejezés bármelyike elhagyható, de a pontosvesszőknek meg kell maradniuk. Ha kif1 vagy kif3 marad el, akkor a ; egyszerűen elmarad a kifejtésből. Ha a kif2 vizsgálat nem szerepel, akkor állandóan igaznak tekintjük, így végtelen ciklus, amelyből más módon kell kiugrani (pl. return vagy break révén). for (;;) { /* ... */ } Programozás Alapjai (2008)

Programozás Alapjai (2008) A , művelet Előfordulhat, hogy a ciklus előkészítése nem egy kifejezés kiértékeléséből áll, illetve minden egyes ciklusmenetben több adminisztrativ lépés is lehet. A for utasításban ekkor alkalmazhatjuk a , műveletet, (sequential expression) amely végülis szekvenciális vezérlést ír elő. Programozás Alapjai (2008)

Programozás Alapjai (2008) A , művelet A egyenértékű a utasítással. for (kif11, kif12, kif13; kif2; kif31, kif32, kif33) { utasítás } kif11; kif12; kif13; while (kif2) { utasítás kif31; kif32; kif33; } Programozás Alapjai (2008)

Programozás Alapjai (2008) A , művelet A , műveletet nyilvánvalóan a prioritási sor aljára kell helyeznünk a egyoperandusú műveletek ( -, ++, --, !, ~ ) a multiplikatív műveletek ( *, /, % ) az additív műveletek ( +, - ) bitléptetés ( <<, >> ) a kisebb-nagyobb relációs műveletek ( <=, >=, <, > ) az egyenlő-nem egyenlő relációs műveletek ( ==, != ) bitenkénti 'és' művelet ( & ) bitenkénti 'kizáró vagy' művelet ( ^ ) bitenkénti 'vagy' művelet ( | ) a logikai 'és' művelet ( && ) a logikai 'vagy' művelet ( || ) a feltételes művelet ( ? : ) értékadó művelet ( =, +=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |= ) szekvencia művelet ( , ) Programozás Alapjai (2008)

Programozás Alapjai (2008) Ábécé A feladat: írassuk ki felváltva az ábécé kis és nagybetűit Egy karakter tárolására C-ben a char típus használható. Programozás Alapjai (2008)

Programozás Alapjai (2008) Ábécé /* Az ábécé kis- és nagybetűinek kiíratása összefésülve. * A for ciklusban a , műveletet alkalmazzuk. * 1997. November 7. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> main() { char cha; /* az ábécé kisbetűinek */ char chA; /* az ábécé nagybetűinek */ for ( cha = 'a', chA = 'A'; cha <= 'z'; cha++, chA++ ) { printf ( "%c%c", cha, chA ); } printf ( "\n" ); Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás A növekvő számlálásos ismétléses vezérlés szerkezeti ábrája és megvalósítása C-ben i = a -> b M for (i = a; i <= b; ++i) { M; } Programozás Alapjai (2008)

Programozás Alapjai (2008) A for utasítás A csökkenő számlálásos ismétléses vezérlés szerkezeti ábrája és megvalósítása C-ben i = a <- b M for (i = b; i >= a; --i) { M; } Programozás Alapjai (2008)

Programozás Alapjai (2008) n alatt k int nAlk(int n, int k) { /* n alatt k értéke nem rekurzív függvénnyel */ int i, nak; if (n >= k && k >= 0) { /* input adatok jók-e? */ nak = 1; /* inicializálás */ for (i = 1; i <= k; i++) { /* ciklus */ nak = nak * (n - i + 1) / i; } } else { nak = 0; return nak; Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög Problémafelvetés Pascal háromszög kiszámolása és megjelenítése 0 0 1 1 0 1 1 1 1 2 0 2 1 2 2 1 2 1 3 0 3 1 3 2 3 3 1 3 3 1 Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög Specifikáció: Input n nemnegatív egész szám, a kiírandó sorok száma Output (n+1) db sor, rendre a Pascal háromszög sorai Algoritmustervezés: A főprogram feladata a beolvasás, input ellenőrzése, majd a nAlk függvényt alkalmas paraméterekkel aktivizálva a soronkénti kiíratás. Programozás Alapjai (2008)

Pascal háromszög P3szog Be(N) Kifér a képernyőre? i n Pozícionálás Ki(nAlk(I,J)) Ki(‘Nem’) Sortörés I = 0 -> N J = 0 -> I Ki ((KepSz / 2) - (I + 1) * SZ / 2 - 1) db ‘ ‘ Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög /* n alatt k értékének kiszámítása egy nemrekurzív függvénnyel és * az értékek elrendezése a Pascal háromszögben. * 1997. Október 31. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> #define SZAMSZ 5 /* egy szám kiírási szélessége */ #define KEPSZ 80 /* a képernyő szélessége */ >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög int nAlk(int n, int k) { /* n alatt k értékének kiszámítása nemrekurzív függvénnyel */ int i, nak; if (n >= k && k >= 0) { /* input adatok jók-e? */ nak = 1; /* inicializálás */ for (i = 1; i <= k; i++) /* ciklus */ nak = nak * (n - i + 1) / i; } else { nak = 0; } return (nak); main() { int n; /* a sorok száma */ int i, j; /* ciklusváltozók */ >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög printf("Kérem a Pascal háromszög sorainak számát\n"); scanf("%d%*[^\n]", &n); /* beolvasás */ getchar(); /* kifér-e a képernyőre? */ if (0 <= n && n <= KEPSZ / SZAMSZ - 2) { for (i = 0; i <= n; i++) { /* pozicionálás */ printf("%*c", KEPSZ / 2 - (i + 1) * SZAMSZ / 2 - 1, ' '); for (j = 0; j <= i; j++) { printf("%5d", nAlk(i, j)); /* kiíratás */ } putchar('\n'); } else { /* hibaüzenet */ printf("%d sor nem fér ki a képernyőre\n", n); Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög Problémafelvetés Pascal háromszög kiszámolása és megjelenítése Specifikáció: Input n nemnegatív egész szám, a kiírandó sorok száma Output (n+1) db sor, rendre a Pascal háromszög sorai Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög Algoritmustervezés: Készítsünk az n alatt k kiszámolására egy rekurzív függvényt. Ehhez felhasználjuk, hogy a Pascal háromszög szélén lévő érték 1, a belsejében lévő érték pedig a felete lévő két érték összege. A főprogram feladata a beolvasás, input ellenőrzése, majd a nAlk függvényt alkalmas paraméterekkel aktivizálva a soronkénti kiíratás. N-1 K-1 N-1 K N K Programozás Alapjai (2008)

n alatt k rekurzívan int nAlk(int n, int k) (n>=k) && (k>=0) i n nak = 0 nak = 1 (n<=1) || (k==0) || (n==k) nak = nAlk(n-1,k-1) + nAlk(n-1,k) return nak Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög /* n alatt k értékének kiszámítása egy rekurzív függvénnyel és * az értékek elrendezése a Pascal háromszögben. * 1997. Október 31. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> #define SZAMSZ 5 /* egy szám kiírási szélessége */ #define KEPSZ 80 /* a képernyő szélessége */ >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög int nAlk(int n, int k) { /* n alatt k értékének kiszámítása rekurzív függvénnyel */ int nak; if (n >= k && k >= 0) { /* input adatok jók-e? */ if (n <= 1 || n == k || k == 0) { /* alapesetek */ nak = 1; } else { /* rekurzív hívás */ nak = (nAlk(n - 1, k - 1) + nAlk(n - 1, k)); } } else { nak = 0; return (nak); main() { int n; /* a sorok száma */ int i, j; /* ciklusváltozók */ >>> Programozás Alapjai (2008)

Programozás Alapjai (2008) Pascal háromszög printf("Kérem a Pascal háromszög sorainak számát\n"); scanf("%d%*[^\n]", &n); /* beolvasás */ getchar(); /* kifér-e a képernyőre? */ if (0 <= n && n <= KEPSZ / SZAMSZ - 2) { for (i = 0; i <= n; i++) { /* pozicionálás */ printf("%*c", KEPSZ / 2 - (i + 1) * SZAMSZ / 2 - 1, ' '); for (j = 0; j <= i; j++) { printf("%5d", nAlk(i, j)); /* kiíratás */ } putchar('\n'); } else { /* hibaüzenet */ printf("%d sor nem fér ki a képernyőre\n", n); Programozás Alapjai (2008)

Hurok ismétléses vezérlés Az ismétléses vezérlésnek azt a módját, amikor a ciklusmag ismétlését a ciklusmagon belül vezéreljük, úgy, hogy ha adott feltétel, a kijárati feltétel teljesül, akkor a ciklusmag és ezzel együtt az összetett művelet végrehajtása befejeződik, hurok ismétléses vezérlésnek nevezzük. A ciklusmagban több kijárati feltételt is megadhatunk. Legyenek Fi (1<=i<=n) logikai kifejezések, Ki és Mi (0<=i<=n) pedig tetszőleges, (esetleg üres) műveletek. Programozás Alapjai (2008)

Hurok ismétléses vezérlés Az Fi kijárati feltételekből, a Ki kijárati műveletekből és az Mi műveletekből képzett hurok ismétléses vezérlés a következő vezérlési előírást jelenti: 1.) A ciklusmag egységei szekvenciális vezérlést képeznek a felírásuk sorrendjében. 2.) Az ismétléses vezérlés a ciklusmag első egységének végrehajtásával kezdődik. Programozás Alapjai (2008)

Hurok ismétléses vezérlés 3.) A ciklusmag i-dik egységének végrehajtása azt jelenti, hogy Ha az művelet, akkor végrehajtódik a művelet, és a ciklusmag következő egysége kap vezérlést. Ha az kijárat és a kijárati feltétel igaz, akkor a Ki kijárati művelet végrehajtódik és a hurok ismétléses vezérlés végrehajtása véget ér Ha az kijárat és a kijárati feltétel hamis, akkor a kijárat hatástalan és a ciklusmag következő egysége kap vezérlést. 4.) Ha a ciklusmag utolsó egységének végrehajtása után, az az előírás, hogy a következő egység kap vezérlést, akkor a ciklusmag első egysége kap vezérlést. Programozás Alapjai (2008)

Hurok ismétléses vezérlés Szerkezeti ábra M0 M1 Mn Mn-1 K1 K2 Kn F1 F2 Fn Programozás Alapjai (2008)

Hurok ismétléses vezérlés Ha egyetlen Mi művelet sincs hatással egyetlen feltételre sem, akkor Vagy van olyan Fj, amelynek értéke igaz, és így az összetett művelet végrehajtása befejeződik mielőtt minden Mi művelet egyszer is végrehajtásra kerülne. Vagy az összes Fj értéke hamis, és mivel feltettük, hogy az Mi műveleteknek nincs hatása az Fj feltételekre, ezért az összes Fj értéke hamis is marad, tehát az összetett művelet végrehajtása nem tud befejeződni. Ilyenkor végtelen ciklus végrehajtását írtuk elő. Fontos tehát, hogy legyen olyan Mi, amelyik valamelyik kijárati feltételre hat. Programozás Alapjai (2008)

Hurok ismétléses vezérlés A kezdő- és végfeltételes ismétléses vezérlések speciális esetei a hurok ismétléses vezérlésnek. F M Not F Programozás Alapjai (2008)

Legnagyobb közös osztó Problémafelvetés: Pozitív egész számok legnagyobb közös osztójának meghatározása Specifikáció: Input Számsorozat melyet a 0 szám zár Output A számok legnagyobb közös osztója Programozás Alapjai (2008)

Legnagyobb közös osztó Algoritmustervezés: Az algoritmus lényege egy olyan ismétléses vezérlés, amely ciklusmagjának egyszeri végrehajtása kiszámítja a már feldolgozott input számsor és a beolvasott következő szám legnagyobb közös osztóját. Látható, hogy a ciklusmag ismétlését célszerű a ciklusmagban vezérelni, mert az ismétlés befejeződhet úgy, hogy Végére értünk az inputnak A feldolgozott sorozat legnagyobb közös osztója 1 Programozás Alapjai (2008)

Legnagyobb közös osztó Szerkezeti ábra a=LegNKO(a,b) b==0 a==1 Be(a) Ki(a) Be(b) LegNKOszt Programozás Alapjai (2008)

Legnagyobb közös osztó Problémafelvetés Legnagyobb közös osztó kiszámítása Specifikáció Függvényműveletet készítünk Input x és y nemnegatív egész számok (bemenő argumentumok) Output Az LegNKO függvényművelet int típusú eredményt szolgáltat Tehát int LegNKO(int x, int y) Programozás Alapjai (2008)

Legnagyobb közös osztó Algoritmustervezés Euklidesz algoritmusát valósítjuk meg. Mivel LegNKO(x,0)=x, így a következő algoritmus a probléma megoldását adja. A ciklusmag helyes megoldása biztosítja, hogy az ismétlés véges sok lépésben befejeződik. Programozás Alapjai (2008)

Legnagyobb közös osztó Szerkezeti ábra m = x % y return x int LegNKO(int x, int y) y!=0 x = y y = m x módosítása és y csökkentése úgy, hogy LegNKO(x,y) értéke ne változzon és y maradjon nem negatív Programozás Alapjai (2008)

Legnagyobb közös osztó A ciklusmag kivitelezéséhez vegyük figyelembe: LegNKO(x,y) = LegNKO(y,x % y), ha y>0 Ugyanis a % és / műveletek definíciója miatt x = y * (x / y) + x % y Tehát, Ha d osztója x-nek és y-nak, akkor osztója (x % y)-nak is Ha d osztója y-nak és (x % y)-nak, akkor x-nek is, Továbbá 0 <= (x % y) < y Ha a ciklusmagot így finomítjuk, akkor a megfogalmazott feltételek teljesülnek. Programozás Alapjai (2008)

Hurok vezérlés megvalósítása #1 A C nyelvben nincs olyan vezérlési forma, amellyel közvetlenül megvalósíthatnánk a hurok ismétléses vezérlést, de a kezdőfeltételes ismétléses vezérlés felhasználásával megtehetjük. A megvalósítás lényege, hogy választunk egy logikai változót (legyen az a tovabb), ez lesz az ismétlés feltétele és a ciklusmagban a feltételes kijáratokat úgy alakítjuk át, hogy Ha a feltétel igaz, akkor a tovabb hamis értéket kap Egyébként végrehajtódik a ciklusmag további része Programozás Alapjai (2008)

Hurok vezérlés megvalósítása #1 A LNKOszt algoritmusban szereplő hurok ciklus tehát a következőképpen valósítható meg tovabb Be(B) B==0 i n tovabb=false A=LegNKO(A,B) A==1 tovabb=true Programozás Alapjai (2008)

Legnagyobb közös osztó #1 /* Pozitív egész számok legnagyobb közös osztójának meghatározása. * A hurok ismétléses vezérlés megvalósítása break utasítással. * 1997. November 7. Dévényi Károly, devenyi@inf.u-szeged.hu * 2006. Augusztus 8. Gergely Tamás, gertom@inf.u-szeged.hu */ #include <stdio.h> >>> Programozás Alapjai (2008)

Legnagyobb közös osztó #1 int LegNKO(int x, int y) { /* x és y legnagyobb közös osztójának meghatározása * Euklidesz algoritmusával. */ int m; while (y != 0) { m = x % y; x = y; y = m; } return x; >>> Programozás Alapjai (2008)

Legnagyobb közös osztó #1 main() { int a, b; int tovabb; /* logikai változó a ciklus megvalósításához */ printf("A program pozitív egész számok legnagyobb\n"); printf("közös osztóját számítja.\n"); printf("Kérem a számok sorozatát, amit 0 zár!\n"); printf("? "); scanf("%d%*[^\n]", &a); getchar(); >>> Programozás Alapjai (2008)

Legnagyobb közös osztó #1 tovabb = !0; while (tovabb) { /* a hurok ciklus kezdete */ printf("? "); scanf("%d%*[^\n]", &b); getchar(); if (b == 0) { /* első kijárat */ tovabb = 0; } else { a = LegNKO(a, b); if (a == 1) { /* második kijárat */ } } /* a hurok ciklus vége */ printf(" A számok legnagyobb közös osztója: %d\n",a); Programozás Alapjai (2008)

Hurok vezérlés megvalósítása #2 A hurok ismétléses vezérlés második megvalósítása a C nyelv break utasítását használja. A break utasítás „megtöri” az aktuális ismétléses (vagy mint láttuk, esetkiválasztásos szelekciós) vezérlést, és a vezérlési szerkezet utáni első utasításnál folytatja a programot. Programozás Alapjai (2008)

Hurok vezérlés megvalósítása #2 Mn Mn-1 K1 K2 Kn F1 F2 Fn while (1) { M0; if (F1) { K1; break; } M1; ... if (Fn) { Kn; break; } Mn; Programozás Alapjai (2008)

Hurok vezérlés megvalósítása #2 végtelen ciklus helyett alkalmazhatjuk a végtelen ciklus utasítást is. while (1) {} for (;;) {} Programozás Alapjai (2008)

Legnagyobb közös osztó #2 /* Pozitív egész számok legnagyobb közös osztójának meghatározása. * A hurok ismétléses vezérlés megvalósítása break utasítással. * 1997. November 7. Dévényi Károly, devenyi@inf.u-szeged.hu */ #include <stdio.h> >>> Programozás Alapjai (2008)

Legnagyobb közös osztó #2 int LegNKO(int x, int y) { /* x és y legnagyobb közös osztójának meghatározása * Euklidesz algoritmusával. */ int m; while (y != 0) { m = x % y; x = y; y = m; } return x; >>> Programozás Alapjai (2008)

Legnagyobb közös osztó #2 main() { int a, b; printf("A program pozitív egész számok legnagyobb\n"); printf("közös osztóját számítja.\n"); printf("Kérem a számok sorozatát, amit 0 zár!\n"); printf("? "); scanf("%d%*[^\n]", &a); getchar(); >>> Programozás Alapjai (2008)

Legnagyobb közös osztó #2 while (1) { /* a hurok ciklus kezdete */ printf("? "); scanf("%d%*[^\n]", &b); getchar(); if (b == 0) { /* első kijárat */ break; } a = LegNKO(a, b); if (a == 1) { /* második kijárat */ } /* a hurok ciklus vége */ printf(" A számok legnagyobb közös osztója: %d\n",a); Programozás Alapjai (2008)

Programozás Alapjai (2008) break, continue A C nyelvben a ciklusmag folyamatos végrehajtásának megszakítására két utasítás használható: break Megszakítja a ciklust, a vezérlés a ciklusmag utáni első utasítással foglalkozik continue Megszakítja a ciklus aktuális lefutását, a vezérlés a ciklus feltételének kiértékelésével folytatódik Programozás Alapjai (2008)

Diszkrét ismétléses vezérlés Diszkrét ismétléses vezérlésről beszélünk, ha azt a vezérlési előírást tesszük, hogy az x ciklusváltozó egy adott H véges halmaz minden elemét tetszőleges sorrendben felvéve hajtsuk végre az M ciklusmagot. Programozás Alapjai (2008)

Diszkrét ismétléses vezérlés Fontos, hogy az M művelet nem lehet hatással az ismétlési előírás egyik elemére sem. A H halmaz számossága határozza meg tehát, hogy az M művelet hányszor hajtódik végre. Ha a H az üres halmaz, akkor a diszkrét ismétléses vezérlés az M művelet végrehajtása nélkül befejeződik. Programozás Alapjai (2008)

Diszkrét ismétléses vezérlés x in H M A diszkrét ismétléses vezérlésnek nincs közvetlen megvalósítása a C nyelvben. Programozás Alapjai (2008)

Diszkrét vezérlés megvalósítása A megvalósítás elsősorban attól függ, hogy az ismétlési feltételben megadott halmazt hogyan reprezentáljuk. Algoritmustervezés során szabadon használjuk a diszkrét ismétléses vezérlést, ha erre van szükség a probléma megoldásához. A halmaz reprezentálásáról pedig akkor döntsünk, amikor elegendő információ áll rendelkezésünkre, hogy a legmegfelelőbbet kiválaszthassuk. Programozás Alapjai (2008)

Programozás Alapjai (2008) Folyamatábra Szerkezeti ábrával az algoritmusok tervezése során a lépésenkénti finomításokat és a kifejlesztett algoritmust egyaránt kifejezhetjük. Ha csak a kész algoritmus vezérlési szerkezetét akarjuk leírni, akkor használhatjuk a folyamatábrát, mint leíró nyelvezetet. Ez olyan ábra, amelyben az algoritmus egyes lépéseit és a lépések közötti vezérlési viszonyt szemléltethetjük irányított vonalakkal. Programozás Alapjai (2008)

Programozás Alapjai (2008) Folyamatábra Legyen M={M1, ... ,Mk} műveletek és F={F1, ... ,Fl} feltételek. Az (M,F) feletti folyamatábrán olyan irányított gráfot értünk, amelyre teljesül a következő 5 feltétel: 1.) Egy olyan pontja van, amely a Start üres művelettel van címkézve és ebbe a pontba nem vezet él. 2.) Egy olyan pontja van, amely a Stop üres művelettel van címkézve és ebből a pontból nem indul él. Programozás Alapjai (2008)

Programozás Alapjai (2008) Folyamatábra 3.) Minden pontja M-beli művelettel vagy F-beli feltétellel van címkézve, kivéve a Start és a Stop pontokat. 4.) Ha egy pont M-beli művelettel van címkézve, akkor belőle egy él indul ki F-beli feltétellel van címkézve, akkor belőle két él indul ki és ezek az i(igen) illetve n(nem) címkét viselik 5.) A gráf miden pontja elérhető a Start címkéjű pontból. Programozás Alapjai (2008)

Programozás Alapjai (2008) Folyamatábra Egy folyamatábra a következő összetett vezérlési előírást jelenti i.) A végrehajtás a Start pontból indul. Az összetett művelet végrehajtása akkor ér véget, ha a Stop pont kap vezérlést. ii.) A gráf egy pontjának végrehajtása azt jelenti, hogy Ha a pontban M-beli művelet van, akkor a művelet végrehajtódik és a vezérlés a gráf azon pontjára kerül, amelybe a pontból kiinduló él vezet Ha a pont F-beli feltétellel van címkézve, akkor kiértékelődik a feltétel. Ha értéke igaz, akkor az a pont kap vezérlést, amelybe az i(igen) címkéjű él vezet, egyébként az a pont kap vezérlést, amelybe az n(nem) címkéjű él vezet. Programozás Alapjai (2008)

Programozás Alapjai (2008) Folyamatábra Példa M={M1, M2} F={F1} M1 Stop Start M2 F1 i n Programozás Alapjai (2008)

Folyamatábra és struktúradiagram Nevezzük szabályosnak az eddig bevezetett vezérlési módokat, ezen belül alapvetőnek a szekvenciális, egyszerű szelekciós és a kezdőfeltételes ismétléses vezérlést. Beláttuk, hogy a szabályos vezérlési módok megvalósíthatók az alapvető vezérlési módokkal. Programozás Alapjai (2008)

Folyamatábra és struktúradiagram Az alapvető vezérlési módokat használó algoritmusok kifejezhetők folyamatábrával is. M1 Stop Start Mn i n F Stop Start A B i n F Stop Start M Programozás Alapjai (2008)

Folyamatábra és struktúradiagram Megmutatjuk, hogy fordítva is igaz, tehát a folyamatábrával leírt algoritmusok megadhatók szabályos és így alapvető vezérlési módokat használva, feltéve, hogy bevezethetünk egész típusú segédváltozót. Programozás Alapjai (2008)

Folyamatábra és struktúradiagram Legyen G egy folyamatábra (M,F) felett, amely pontjainak száma n. Sorszámozzuk meg a gráf pontjait úgy, hogy a Start pont sorszáma 1 és a Stop pont sorszáma n legyen. Vegyünk fel egy olyan új egész típusú változót. Legyen ennek az azonosítója pont. Programozás Alapjai (2008)

Folyamatábra és struktúradiagram Tekintsük az alábbi C programot { pont = 1; while (pont != n) { switch (pont) { case 1 : U1; break; ... case n-1: Un-1; break; case n : /* Stop */ break; } /* switch */ } Programozás Alapjai (2008)

Folyamatábra és struktúradiagram Ahol az Ui utasítás: Ha az i. pontban az Mi művelet volt és a belőle kiinduló él a j. pontba vezetett: Ha az i. pontban az Fi feltétel volt és az igennel címkézett él a j., a nemmel címkézett él pedig a k. pontba vezetett Az így megalkotott program a G folyamatábrával adott algoritmussal ekvivalens algoritmus kódolása lesz. { Mi; pont = j; } { if (Fi) { pont = j; } else { pont = k; } } Programozás Alapjai (2008)