Algoritmus Algoritmus Az algoritmus szó eredete a középkori arab matematikáig nyúlik vissza, egy a i.sz. IX. században élt perzsa tudós nevének pontatlan fordítása. Az algoritmus szó eredete a középkori arab matematikáig nyúlik vissza, egy a i.sz. IX. században élt perzsa tudós nevének pontatlan fordítása. Az algoritmus problémamegoldásra szolgáló elemi lépések olyan sorozata, amely: Az algoritmus problémamegoldásra szolgáló elemi lépések olyan sorozata, amely: véges – azaz véges számú lépés után befejeződik, és eredményt szolgáltat; véges – azaz véges számú lépés után befejeződik, és eredményt szolgáltat; egyértelmű – a lépések sorozatát úgy határozzuk meg, hogy bármely végrehajtott lépés után egyértelműen adódik a következő; egyértelmű – a lépések sorozatát úgy határozzuk meg, hogy bármely végrehajtott lépés után egyértelműen adódik a következő; determinisztikus – ugyanazon kiindulási adatokra tetszőleges számú végrehajtás esetén ugyanazt az eredményt szolgáltatja; determinisztikus – ugyanazon kiindulási adatokra tetszőleges számú végrehajtás esetén ugyanazt az eredményt szolgáltatja; teljes – nemcsak egy konkrét esetre alkalmazható, hanem az összes azonos jellegű feladatra. teljes – nemcsak egy konkrét esetre alkalmazható, hanem az összes azonos jellegű feladatra.
Szemléltetése Az algoritmusok tervezésére, szemléltetésé- re sokféle eszköz létezik, pl. folyamatábra: az algoritmus szerkezetét, a lépések sorrendjét teszi áttekinthetővé; folyamatábra: az algoritmus szerkezetét, a lépések sorrendjét teszi áttekinthetővé; leíró nyelv (mondatszerű leírás): az így meg- fogalmazott algoritmus közvetlenül átírható egy általános célú programozási nyelvre. leíró nyelv (mondatszerű leírás): az így meg- fogalmazott algoritmus közvetlenül átírható egy általános célú programozási nyelvre. Struktogram: négyszögek, (háromszögek)jelzik az egyes utasításokat Struktogram: négyszögek, (háromszögek)jelzik az egyes utasításokat
A folyamatábra szimbólumai Start Be: változóKi: kifejezés Feltétel Stop változó:=kifejezés az algoritmus kezdete adat be- és kivitel értékadás kétirányú elágazás (döntés) a lépések sorrendje az algoritmus vége
Folyamatábra példa
Struktogram példa
Vezérlési szerkezetek A folyamatábrák készítése során a lépések sor- rendjét vezérlő folyamatvonal szinte tetszőleges helyre irányítható. A folyamatábrák készítése során a lépések sor- rendjét vezérlő folyamatvonal szinte tetszőleges helyre irányítható. Így olyan bonyolult szerkezeteket kaphatunk, amelyeket nagyon körülményes kódolni bármely programozási nyelvre. Így olyan bonyolult szerkezeteket kaphatunk, amelyeket nagyon körülményes kódolni bármely programozási nyelvre. A hatékony programíráshoz szükségessé vált kevés számú, áttekinthető vezérlési szerkezet definiálása, melyek felhasználásával minden algoritmus megvalósítható. A hatékony programíráshoz szükségessé vált kevés számú, áttekinthető vezérlési szerkezet definiálása, melyek felhasználásával minden algoritmus megvalósítható.
Vezérlési szerkezetek Az 1960-as években bebizonyították (Dijkstra, strukturált programozás), hogy bármely algorit- mus leírható szekvencia, szelekció és iteráció segítségével. Az 1960-as években bebizonyították (Dijkstra, strukturált programozás), hogy bármely algorit- mus leírható szekvencia, szelekció és iteráció segítségével. szekvencia: utasítások egymás utáni végrehajtási sorrendje, külön utasítást nem használunk a jelölé- sére; szekvencia: utasítások egymás utáni végrehajtási sorrendje, külön utasítást nem használunk a jelölé- sére; szelekció: egy feltétel igaz vagy hamis voltától függ, hogy bizonyos utasítások végrehajtódnak-e vagy sem; szelekció: egy feltétel igaz vagy hamis voltától függ, hogy bizonyos utasítások végrehajtódnak-e vagy sem; iteráció: lehetővé teszi meghatározott utasítások tet- szőleges számú ismételt végrehajtását. iteráció: lehetővé teszi meghatározott utasítások tet- szőleges számú ismételt végrehajtását.
Konstansok (állandók) A program futtatása alatt értéküket nem változtatják A program futtatása alatt értéküket nem változtatják Típussal rendelkeznek, mint a változók Típussal rendelkeznek, mint a változók Példa: Const int arfolyam=312; const float pi=3,14; const char jel= ’ C’; Példa: Const int arfolyam=312; const float pi=3,14; const char jel= ’ C’;
A változókról A C típusos programnyelv. Ez azt jelenti, hogy mielőtt egy változót használni szeretnénk deklarálnunk kell azt. Figyeljünk arra, hogy a a fordítóprogram a változó nevekben is különbséget tesz a kis és a nagy betűk között. A névre a következő megkötések érvényesek: csak betűket, számjegyeket és aláhúzás karaktert tartalmazhat betűvel kell kezdődnie hossza legfeljebb 32 karakter (implementáció függő) A változó deklaráció szabálya C-ben a következő: Típus nev1,nev2,…; Például: int s; float f,k; Egy változót kezdőértékkel is elláthatunk. int s=10;
Az adatoknak a C-ben négy alaptípusa van: egész (int), karakter (char), valós (float, double). Az alaptípusokat elláthatjuk módosító jelzőkkel is, ekkor az értékkészlet módosul. Pl. int a unsigned[1] int b[1] Az első esetben az a értéke –32768 és között lehet, míg a második esetben a b értéke 0 és közötti szám lehet. A signed[2] módosító jelző is használható, de alapértelmezés szerint minden egész változó ilyen lesz.[2] [1][1] Előjel nélküli [2][2] Előjeles Adattípusok
AdattípusÉrtékkészlet Méret (byte) Pontosság( jegy) char unsigned char int unsigned int long int unsigned long int float3.4e e+3846 double1.7e e long double3.4e e
Az általunk használt leírónyelv szintaxisa Változódeklarálás: Változódeklarálás: változó változónév1, változónév2...: típus pl: pl: változó Darabszám: egész változó Összeg, Átlag: valós Értékadó utasítás: Értékadó utasítás: változó=kifejezés pl: pl: ar=540; atlag=osszeg/darabszam
Operátorok (műveleti jelek) () operátor: zárójelezés [] operátor: tömbindexelés ! operátor: logikai tagadás: !kif esetén, ha a kif értéke 0 (hamis), akkor az eredmény 1 (igaz), ha a kif értéke nem 0 (igaz), akkor az eredmény 0 (hamis)
Operátorok ++ operátor: növelő operátor: valt++ kifejezés értéke valt, majd utána megnő a valt értéke. A ++valt esetén valt értéke megnő és a kifejezés értéke valt új értéke lesz. Pl. a=5; b=a++;//egyenértékű: b=a; a++; utasításokkal utasítások után a értéke 6, b értéke 5, a=5; b=++a;//egyenértékű: ++a; b=a; utasításokkal utasítások után a értéke 6, b értéke 6.
-- operátor: csökkentő operátor: használata ugyanaz, mint a ++ operátoré, de növelés helyett csökkent 1-el. & operátor: címképző operátor: &valt esetén az eredmény valt memóriacíme. * operátor: szorzás: kif1*kif2 / operátor: osztás: kif1/kif2, ha mind a két kifejezés egész, akkor az eredmény is egész (lásd még típuskonverziók). Pl. 11/4 értéke 2 és 11/4.0 értéke 2.75Operátorok
% operátor: maradékképzés: kif1%kif2, mind a két kifejezésnek egésznek kell lennie. Pl. 11%4 értéke 3 + operátor: összeadás: kif1+kif2 - operátor: kivonás: kif1-kif2, >= operátorok: relációs operátorok (kisebb, kisebb egyenlő, nagyobb, nagyobb egyenlő): eredményük 0 hamis esetén, 1 igaz esetén. (Lehet használni így is, de nem célszerű: b=5*(a<8);)Operátorok
== operátor: relációs operátor (egyenlőség): kif1==kif2, eredménye 0 hamis esetén, 1 igaz esetén. != operátor: relációs operátor (nem egyenlő): kif1!=kif2, eredménye 0 hamis esetén, 1 igaz esetén. && operátor: logikai és operátor: kif1 && kif2, eredménye akkor igaz (nem 0), ha mind a két kif igaz || operátor: logikai vagy operátor: kif1 || kif2, eredménye igaz (nem 0), ha bármelyik kifejezés igaz. kifejezés igaz (nem 0), különben hamis (0).Operátorok
printf használata: A printf() függvényben a változókat csak úgy tudjuk kiíratni, hogy az idézőjelek között % jel után megadjuk a változó típusát, a kiírás formátumát majd az idézőjelek után vesszőkkel elválasztva fölsoroljuk a változók neveit %ddecimális egész %uelőjel nélküli decimális egész %flebegőpontos %ckarakter %ssztirng vagy karakter tömb %edupla valós printf(”A szam: %5.2f”,f1); Az f valós változót 5 mezőre írja ki 2 tizedes pontossággal. A szám: 3,31 Ha egy változó karakter típusú, akkor értékét egyszeres idézőjelek között kell megadnunk. char betu; betu=’A’;
A formázott adatbeolvasást a scanf függvény segítségével tehetjük meg. A függvény általános formája a következő: scanf(formátum, argumentumlista) Pl.: int a ; char c; printf(”Kérek egy egész számot és egy betűt”); scanf(”%d%c”,&a,&b) A scanf karaktereket olvas a billentyűzetről, majd a formátum alapján értelmezi azokat, ha a beolvasott karakterek megfelelők, akkor konvertálja őket. Ha az input valamilyen ok miatt nem felel meg a formátum előírásainak, akkor a scanf befejezi az olvasást, még akkor is, ha az argumentumlista szerint további karaktereket is be kellene olvasnia. Adatok beolvasása a billentyűzetről scanf használata
A C nyelvben három elágazás típust használhatunk. Az egyágú (if szerkezet), a kétágú (if-else szerkezet) és a többágú (switch szerkezet Az utasítás általános alakja: if (kifejezés) utasítás Itt az utasítás csak akkor hajtódik végre, ha a kifejezés nem nulla. (IGAZ) if-else szerkezet Az utasítás általános alakja: if (kifejezés) utasítás1 else utasítás2 Ha a kifejezés értéke nem nulla (IGAZ), akkor az utasítás1 hajtódik végre, ha pedig nulla (HAMIS) az utasítás2. Szelekciók (elágazások)
Egymásba ágyazott szelekciók (elágazások) if-else-if szerkezet Az utasítás általános alakja: if (kifejezés1) utasítás1 else if (kifejezés2) utasítás2 else utasítá3 Ha a kifejezés1 értéke nem nulla (IGAZ), akkor az utasítás1 hajtódik végre, ha pedig nulla (HAMIS) a kifejezés2-t vizsgálja, és ha az igaz, akkor az utasítás2 hajtódik végre, egyébként az utasítás3 Ezt egymásba ágyazott IF-es szerkezetnek nevezzük
Többirányú elágazás elágazás amikor feltétel1: utasítás… amikor feltétel2: utasítás… amikor feltétel3: utasítás…... különben utasítás vége
Többirányú elágazás SWITCH (szelektor) // csak egész szám vagy karakter// { CASE (szelektor1) CASE (szelektor1) { UTASÍTÁS 1} { UTASÍTÁS 1} CASE (szelektor2) CASE (szelektor2) { UTASÍTÁS 2} { UTASÍTÁS 2} default: default: {utasítás n} {utasítás n}}
Mint minden magas szintű programozási nyelvben a C-ben is vannak olyan utasítások, melyek egy feltételtől függően többször is végrehajtják ugyanazt az utasítást, vagy utasítás blokkot, (ciklusmagot). Iterációk (ciklusok)
A for ciklust a leggyakrabban akkor használjuk, ha előre tudjuk, hogy egy utasítást hányszor akarunk végrehajtani. Az utasítás általános alakja egyszerű formában a következő lehet: for ( kifejezés1;kifejezés2;kifejezés3) Utasítás A kifejezés1-ben állítjuk be a ciklusváltozó kezdő értékét, a kifejezés kettőben a ciklusba való lépés feltételét, ez a leggyakrabban egy logikai kifejezés, a kifejezés3-ban pedig léptetjük a ciklusváltozót. Számláló ciklus for ciklus
Pl.: #include main() { long osszeg; int i,n=100; osszeg=0 for (i=0;i<=n;i++) { osszeg=osszeg+i; } printf(”Az első %d szám összege: %d”,n,osszeg); }
Számláló ciklus folyamatábrája Az első 10 egész szám kiíratása Igaz Hamis
Számláló ciklus struktorgam
A while ciklus általános alakja: while (kifejezés) Utasítás A ciklusmag utasításai addig hajtódnak végre, amíg a kifejezés értéke nem nulla. (Ez a logikai „igaz”-nak felel meg, tehát, ha a kifejezés egy logikai kifejezés, akkor itt a ciklusba lépés feltételét adjuk meg) WHILE CIKLUS
Példa while ciklusra Nézzünk egy példát a while ciklusra. Adjuk össze 1-től n- ig a természetes számokat! #include<stdio.h>main(){ long osszeg=0; int i=1,n=2000; printf(”Az első %d egész szám összege: ”,n); while (i<=n) { osszeg+=i; (osszeg=osszeg+i); osszeg+=i; (osszeg=osszeg+i); i++; i++; } printf(”Az első %d szám összege:%ld”,n,osszeg); }
While ciklus folyamatábrája
While ciklus strultogramja
Ezt a ciklust igen ritkán használjuk. Minden programozási feladat megoldható az előző két ciklus alkalmazásával, van azonban néhány olyan feladat, mely rövidebb kódot eredményez, ha a do-while ciklust használjuk. (Pl. a bináris keresés) A ciklus általános alakja: do Utasítás while (kifejezés) A ciklusba itt is addig lépünk, amíg a kifejezés értéke nem 0, logikai kifejezés esetén amíg a kifejezés igaz. Alapvetően abban különbözik az előző két ciklustól, hogy itt a ciklusmag utasítása legalább egyszer végrehajtódik. Nézzük a következő példát a do-while ciklusra. Bekérünk egy egész számot és kiírjuk a fordítottját. #include main() { int szam, jegy; printf(”Kérek egy egész számot:”); scanf(”%d”,&szam); printf(”\nA fordítottja: ”); do { jegy = szam % 10; printf(”%d”,jegy); szam /= 10; } while ( szam != 0); } do-while ciklus
Az eddigiek során olyan változókat használtunk csak, melyek egy érték tárolására voltak alkalmasak. Gyakran van azonban szükségünk arra, hogy ugyanazzal a változónévvel több értékre is tudjunk hivatkozni. Ebben az esetben használjuk a tömböket. (Egy osztály minden tanulójához hozzárendeljük a magasságát, ilyenkor nyilván érdemes változónévként az osztály azonosítóját használni, a tanulókra pedig a tömb elemének sorszámával hivatkozunk.) Tömbök
Egydimenziós tömbök Egydimenziós tömböket vektoroknak is nevezzük. (egy táblázathoz lehet hasonlítani, melynek egy sora és „n” db cellája (eleme) van A deklaráció szintaxisa: Típus tömbnév[méret] Konkrét példák: int testmagassagok[5] float testsuly[5] i=0 i=2 i=? n=?
i=0 i=3 i=? n=? i elemmutató, mely megmutatja, hogy hányadik az éppen aktuális elem n az elemszám, mely megmutatja, hogy hány eleme (fiókja) van a tömbnek Egy elemre történő hivatkozás: magassagok[i] (ha i=3, akkor magassagok[i]=? int n=5, magassagok [n]
Összegzés Egy sorozat elemeit gyűjteni, összegezni kell. Eljárás összegzés (Be: tömb[], n elemszám) Összeg:=0 ciklus i:=0-tól n-ig Összeg:=Összeg+tömb[i] Ciklus vége Ki: összeg
Átlagszámítás Az átlagszámítás során egy megszámlálást és egy összegzést kell párhuzamosan végeznünk. Eljárás átlag (Be: tömb[], n elemszám) Összeg:=0 ciklus i:=1-től n-ig ciklus i:=1-től n-ig Összeg:=Összeg+tömb[i] Összeg:=Összeg+tömb[i] Ciklus vége Ciklus vége Átlag=összeg/n Átlag=összeg/n Ki: átlag
Tömb elemeinek szorzata Egy sorozat elemeit gyűjteni, összegezni kell. Eljárás Szorzat (Be: tömb[], n elemszám) szorzat:=1 ciklus i:=1-től n-ig szorzat:=szorzat*tömb[i] Ciklus vége Ki: szorzat
Eldöntés tétele Adott egy N elemű sorozat és egy, a sorozat elemein értelmezett T tulajdonság. A feladat annak az eldöntése, hogy létezik-e ilyen (T tulajdonságú)(pl:10-nál nagyobb) elem. Ha van T tulajdonságú elem, akkor egy egész típusú változó 1 értéket vesz fel, Egyébként (ha nincs, akkor 0-t.
Eldöntés tétele i:=0 Van=0 Ciklus, amíg i <= N és A(i) nem T tulajdonságú i:=i+1 Ciklus vége ha (i <= N) akkor van=1
Kiválasztás tétele Adott egy N elemű sorozat és egy, a sorozat elemein értelmezett T tulajdonság. (pl. tíznél nagyobb, páros szám) Azt is tudjuk, hogy a sorozatban van legalább egy T tulajdonságú elem. A fel- adat ezen elem sorszámának meghatározása.
Eljárás kiválasztás Be: tömb[], elemszám i:=0 Ciklus, amíg tömb[i] nem T tulajdonságú i:=i+1 Ciklus vége SORSZÁM:= i Ki: sorszám, Ki:tömb[sorszám]
Minimum- és maximum- kiválasztás Egy sorozat legkisebb, illetve legnagyobb elemét kell kiválasztanunk. Egy sorozat legkisebb, illetve legnagyobb elemét kell kiválasztanunk. Az algoritmus lényege, hogy használunk egy Min, illetve Max változót, amely első lépésként a 0. elem sorszámát, azaz 0-t tartalmaz. (min=0) Ha az éppen vizsgált elem kisebb, mint az eddig vizsgált legkisebb elem, (tömb[i] <tömb[min]), akkor ez lesz a minimum új értéke. (min=i) Hasonlóan járunk el a maximumnál. Az algoritmus lényege, hogy használunk egy Min, illetve Max változót, amely első lépésként a 0. elem sorszámát, azaz 0-t tartalmaz. (min=0) Ha az éppen vizsgált elem kisebb, mint az eddig vizsgált legkisebb elem, (tömb[i] <tömb[min]), akkor ez lesz a minimum új értéke. (min=i) Hasonlóan járunk el a maximumnál. A Min és Max kezdőértékének tehát az első, (0.) elem sorszámát választjuk. A Min és Max kezdőértékének tehát az első, (0.) elem sorszámát választjuk.
Eljárás minimum kiválasztás: Be: tömb[],n min=0; ciklus i=1-től n-ig ha a tömb[i] < tömb[min] akkor min:=i elágazás vége ciklus vége Eljárás vége Ki: min, vagy tömb[min]
Eljárás maximum kiválasztás: Be: tömb[],n max=0; ciklus i=1-től n-ig ha a tömb[i] > tömb[max] akkor max:=i elágazás vége ciklus vége Eljárás vége Ki: max, vagy tömb[max]
Megszámlálás Egy sorozat, egy tömb adott T tulajdonságú elemeinek a számát akarjuk meghatározni. Felveszünk egy számláló változót, (db) melynek az értékét növeljük, ha az elem kívánt tulajdonságú. A számlálót természetesen előzőleg le kell nulláznunk. Ha ismerjük az elemek számát, akkor számláló (FOR) ciklust használhatunk, ha nem akkor elöltesztelő (WHILE) ciklust, amíg nem értük el az utolsó elemet, de fontos, hogy minden elemet meg kell vizsgálnunk.
Megszámlálás Eljárás megszámlálás Be: tömb[], n elemszám db=0; db=0; Ciklus i=0-tól n-ig Ciklus i=0-tól n-ig ha tömb[i] T tulajdonságú, akkor ha tömb[i] T tulajdonságú, akkor db=db+1; db=db+1; elágazás cége elágazás cége Ciklus vége Ciklus vége Eljárás vége KI: db KI: db