Az algoritmusok elemei
Tartalom
- Szorgalmi: Csala Tamás gyökvonógépe
- Emlékeztető: A programozás menete
- Emlékeztető: C program
- Elemi lépések
- Programok egynél több lépésből – hogyan?
- Programvezérlés: lehetőségek
- Szekvencia: egymás utáni lépések
- Szekvencia: szám négyzete
- Elágazás: feltételes végrehajtás
- Elágazás: páros vagy páratlan
- Elágazás: pozitív, nulla vagy negatív
- Ciklus: számok 1-től 10-ig
- Ciklus: folyamatábra és struktogram
- Ciklus: számok kiírása
- Ciklus: Hérón módszere – feladat
- Ciklus: Hérón módszere – megoldás
- Ciklusszervezés: áttekinthetőség!
- Ciklus: számlálásos változat
- Ciklusok: tudnivalók
- Vezérlési szerkezetek: összefoglalás
- Vezérlési szerkezetek kombinációja
- C forráskódok
- Szintaxis (syntax)
- EBNF: Extended Backus-Naur Form
- A C nyelv elemei
- Utasítások fajtái a C nyelvben
- Kifejezések
- Változódefiníciók
- Utasításblokk és egy C program váza
- Vezérlési szerkezet:
if()
elágazás - Vezérlési szerkezet:
while()
ciklus - Elöltesztelő ciklus: Hérón módszere (példa)
- Vezérlési szerkezet:
for()
ciklus while()
ésfor()
ciklus: összehasonlítás- Számlálásos ciklus: szorzótábla
- A kód tördelése – „indentálás”
1 Szorgalmi: Csala Tamás gyökvonógépe

Használati útmutató:
1. Írj be az SZ-be azt a számot, aminek érdekel a gyöke2. Nyomd meg a T↓1 gombot
3. Nyomd meg a ↑T gombot
4. Nézd meg hogy világít-e a lámpa,
ha igen akkor lépj az 6. lépésre
5. Lépj a 3. lépésre
6. Kész, az eredmény a T-ben :)
2 Emlékeztető: A programozás menete
A feladattól a kész programig
- Specifikáció: a feladat megfogalmazása
- Algoritmizálás: a megoldás módszerének kitalálása
- Kódolás: a megoldás leírása egy programozási nyelven
- Tesztelés: a program kipróbálása
Részfeladatok
- Az algoritmizálás a bonyolultabb, ötletelést igénylő
- A kódolás többé-kevésbé szisztematikus, magától értetődő. A meglévő megoldást kell megfogalmazni az adott programnyelven.
3 Emlékeztető: C program
#include <stdio.h> int main() { double a, b, osszeg; printf("Összeadó\n\n"); printf("a="); scanf("%lf", &a); printf("b="); scanf("%lf", &b); printf("\n"); osszeg=a+b; printf("a+b=%f\n", osszeg); return 0; }
Összeadó a=1.2 b=2.5 a+b=3.700000
A program kér két számot, és kiírja az összegüket.
4 Elemi lépések
Elemi lépések, műveletek a számítógépen
- Kiírunk valamit a képernyőre
- Adatot kérünk a felhasználótól
- Kiszámolunk valamit
- Értéket adunk egy változónak
- …
Egyszerű program
PROGRAM
KIÍR: "Helló, világ!" egyetlen elemi lépés
PROGRAM VÉGE
5 Programok egynél több lépésből – hogyan?

A gyakorlaton szerepeltek algoritmusok: prímtényezős felbontás, rendezés, számlálás…
- A pszeudokódot szabadosan adtuk meg:
- Beszámoztuk a sorokat
- „Ugorj az 5. sorra”
- „Ha x<7, folytasd a 14. sornál”…
- Az ilyet úgy hívják, spagetti kód
- Az ugrásoktól áttekinthetetlen lesz a program
6 Programvezérlés: lehetőségek
Strukturált programok (structured programs)
- Amelyek szekvenciából, elágazásból és ciklusból épülnek fel
- Matematikailag bizonyított: minden megoldható így
- Tapasztalat: sokkal jobban, mint spagetti kóddal!
- Alapvetően egymás után, de ez megváltoztatható vezérlési szerkezetekkel (control structure)
- Speciális programbeli utasítások tartoznak hozzájuk: ezek a vezérlésátadó utasítások (control flow statement)
A vezérlési szerkezetek lényege az, hogy valamilyen döntés (egy feltétel teljesülése) alapján máshol folyatódik általuk a program végrehajtása – nem a pszeudokódban következő utasításnál.
8 Szekvencia: szám négyzete
Program
PROGRAM KIÍR: "Kérem a számot!" BEOLVAS: a a=a·a KIÍR: a PROGRAM VÉGE
Működés
a:
Mire használjuk itt a változót? Arra, hogy megjegyezzük a felhasználótól származó értéket – és később a négyzetét.
9 Elágazás: feltételes végrehajtás
Feladat: Írjunk programot, amely kér egy számot a felhasználótól.
Mondja meg, hogy páros vagy nem.
A programsorok végrehajtása feltételhez köthető.
Fogalmak: elágazás (conditional), feltétel (condition, predicate), igaz ág (consequent), hamis ág (alternative).
- Elágazás: az egész vezérlési szerkezet
- Feltétel: logikai kifejezés, amelynek igaz/hamis voltától függ, hogy végrehajtódik-e az adott programrészlet
- Igaz ág, következmény: az a programrészlet, amely akkor hajtódik végre, ha a feltétel igaz volt
- Hamis ág, „else” ág: akkor hajtódik végre, ha a feltétel hamis volt
10 Elágazás: páros vagy páratlan
Program
PROGRAM BEOLVAS: szam HA szam/2 maradéka 0, AKKOR KIÍR: "páros" ha teljesül EGYÉBKÉNT KIÍR: "páratlan" ha nem teljesül FELTÉTEL VÉGE PROGRAM VÉGE
Működés
szam:
11 Elágazás: pozitív, nulla vagy negatív
Ez a programrész megnézi, hogy egy szám pozitív, nulla vagy negatív. Mire jó ez? Pl. egy másodfokú egyenlet diszkussziójához használható. Ha a diszkrimináns pozitív, két valós megoldás van. Ha nulla, akkor csak egy. Ha negatív, egy sem.
PROGRAM BEOLVAS: szam HA szam>0, AKKOR KIÍR: "pozitív" FELTÉTEL VÉGE HA szam=0, AKKOR KIÍR: "nulla" FELTÉTEL VÉGE HA szam<0, AKKOR KIÍR: "negatív" FELTÉTEL VÉGE PROGRAM VÉGE
Az elágazásoknál fontos látni azt, hogy akár teljesül a feltétel, akár nem, a program folytatása mindenképp az elágazás utáni műveletnél lesz.
12 Ciklus: számok 1-től 10-ig
Feladat: írjunk programot, amelyik növekvő sorrendben kiírja a számokat.
:-(
KIÍR: 1 KIÍR: 2 KIÍR: 3 … KIÍR: 8 KIÍR: 9 KIÍR: 10
Probléma
- Egyrészt: kipontozás? Ez nem szép megoldás.
- Másrészt: mi van akkor, ha a felhasználó kellene megmondja, meddig kellenek a számok? A program kódja nem függhet a bemenetétől!

A programozásban inkább ne!
13 Ciklus: folyamatábra és struktogram
Ciklus (loop): programrész ismétlése, amíg egy feltétel fennáll
Fogalmak: ciklusmag (loop body), ciklusfeltétel (loop condition), iteráció (iteration), ciklusváltozó (iterator).
- Ciklusmag, ciklustörzs: az ismételt utasítás(ok)
- Ciklusfeltétel: amely kifejezés igaz/hamis értéke alapján eldől, hogy végrehajtódik-e a ciklus törzse
- Iteráció: a ciklustörzs egy végrehajtása
- Ciklusváltozó, iterátor: a ciklust vezérlő változó, itt az
i
- Elöltesztelő ciklus (pre-test loop): a feltételt a ciklustörzsbe lépés előtt ellenőrizzük
14 Ciklus: számok kiírása
PROGRAM KIÍR: "Meddig írjam ki?" BEOLVAS: n i=1 CIKLUS AMÍG i≤n KIÍR: i i=i+1 CIKLUS VÉGE KIÍR: "." PROGRAM VÉGE
i: n:
Itt mire jó a változó? Azzal tudjuk elérni azt, hogy a ciklus törzsében lévő kiírás utasítás mindig más számot írjon a képernyőre! Azzal számoljuk, hogy éppen hol tartunk.
15 Ciklus: Hérón módszere – feladat
Feladat: számoljuk ki a felhasználó által megadott szám négyzetgyökét Hérón módszerével (babilóniai módszer).
A módszer
- Adott: szám; keressük: gyök2=szám
- Tippelünk egy gyököt
- A megoldás valahol tipp és szám/tipp között van
- Ezért az új tipp legyen (tipp + szam/tipp)/2
- Ezt ismételgessük, amíg a különbség kellően kicsi nem lesz
Ezt a módszert alexandriai Hérón találta ki – ugyanaz a Hérón, aki a háromszög területének kiszámítására használható képletet is. Ugyanazt elmondhatjuk a programozásról, mint amit sok más tudományról is el lehet mondani: „már a régi görögök is”.
16 Ciklus: Hérón módszere – megoldás
PROGRAM szam=2 tipp=1 CIKLUS AMÍG |tipp-szam/tipp|>0.001 tipp=(tipp + szam/tipp)/2 CIKLUS VÉGE KIÍR: "A keresett gyök: ", tipp PROGRAM VÉGE
szam: tipp: szam/tipp: különbség: átlag:
17 Ciklusszervezés: áttekinthetőség!
Számok kiírása 1-től 10-ig:
i=0 CIKLUS AMÍG i≤9 i=i+1 KIÍR: i CIKLUS VÉGE
rossz, követhetetlen
i=1 első CIKLUS AMÍG i≤10 utolsó KIÍR: i teendők i=i+1 következő CIKLUS VÉGE
jól megírt
Ha áttekinthetően szeretnénk ciklust írni, akkor érdemes a fenti sémát megtartani. Az ismérvek:
- A ciklus előtt közvetlenül a ciklusváltozó inicializálása szerepel. Ez lesz az első iterációban az értéke. Egyben az első feldolgozott elem.
- A ciklustörzsben elöl a teendők szerepelnek. Mivel ez elöl van, ezért a ciklusváltozó értéke az első iterációban éppen a cikluson kívül beállított érték, vagyis az első elem! (Különben a ciklusváltozót olyan értékre kellene inicializálni, amit aztán nem dolgozunk fel, ahogyan az a bal oldalon is látszik.)
- A ciklustörzs végén az utasítás, amely lép a következő elemre. Ez változtatja a ciklusváltozót. Utána már nem írunk semmit, hiszen akkor egy iteráción belül némely utasítások még a régi, némelyek pedig már az új értékére vonatkoznának.
18 Ciklus: számlálásos változat
„Amíg” (while) ciklus
i=1 CIKLUS AMÍG i≤10 KIÍR: i i=i+1 CIKLUS VÉGE
Számlálásos ciklus
CIKLUS i=1-től, i≤10-ig, +1-esével KIÍR: i CIKLUS VÉGE
- Ez nagyon gyakori fordulat
- Az áttekinthetőség, olvashatóság miatt alkalmazzuk
- Rávezet, hogy átgondoljuk: honnan, hova, hogyan
- „i minden értékére… 1-től 10-ig 1-esével… csináljuk ezt…”
19 Ciklusok: tudnivalók
Ciklusfeltételek
- A ciklus bennmaradási feltétele logikai kifejezés
- Újra és újra kiértékelődik minden iterációban
- Ha teljesül, végrehajtódik a törzs
- Ha nem, a ciklus után folytatódik a program
Ciklusok
- Hányszor? Ahányszor a feltétel teljesül
- Ez lehet 0 is: a törzs egyszer sem hajtódik végre
- A feltétel előbb-utóbb hamissá kell váljon, különben végtelen ciklus (infinite loop) keletkezik
- A ciklusváltozónak változnia kell!
A feltétel hamissá kell váljon előbb-utóbb: praktikusan ez azt is jelenti, hogy a ciklusváltozónak, ha van, az egyes iterációk között változnia kell. Különben ugyanaz marad az értéke, és a ciklus feltételének igazságértéke sem fog változni! Ha nincs olyan utasítás a ciklusban, amely a ciklusváltozó értékét változtatja, az gyanús.
20 Vezérlési szerkezetek: összefoglalás
szerkezet | használat | pszeudokód |
---|---|---|
szekvencia | Egymás utáni utasítások. | utasítás1 utasítás2 utasítás3 |
elágazás | Feltételhez között végrehajtás. 0-szor vagy 1-szer. Lehet „hamis” ága is. | HA feltétel, AKKOR utasítás FELTÉTEL VÉGE |
ciklus | Ismétlés. 0-tól ∞-ig akárhányszor. | CIKLUS AMÍG feltétel utasítás CIKLUS VÉGE |
21 Vezérlési szerkezetek kombinációja
Feladat: írjunk programot, amelyik kér egy valós számot a felhasználótól, és Hérón módszerével kiszámolja a gyökét.
Tudjuk, hogy negatív számnak nincsen gyöke a valós számok körében. Ez nem csak definíciós kérdés, hanem a programunkat is érinti. Ugyanis ha Hérón algoritmusa negatív számot kap, akkor ide-oda ugrál pozitív és negatív tippek között. Így végtelen ciklus keletkezik: a program soha nem áll le. Ezért a felhasználótól kapott számot az algoritmus futtatása előtt ellenőrizni kell. Ha negatív, akkor nincs gyök, és ezt jelenzni kell. Ha nem, akkor indulhat a számítás.
A bemeneti adatok érvényességi köre része kell legyen a specifikációnak! Jelen esetben például meg kell mondani azt, hogy a program egy valós számot kell kérjen (ez a bemenet), amelynek a gyökét fogja meghatározni (ez a kimenet), de a beolvasott szám nem lehet negatív.
pozitív legyen
PROGRAM KIÍR: "Melyik szám gyöke?" BE: szam HA szam≤0, AKKOR KIÍR: "A szám pozitív kell legyen!" EGYÉBKÉNT tipp=1 CIKLUS AMÍG |tipp-szam/tipp|>0.001 tipp=(tipp + szam/tipp)/2 CIKLUS VÉGE KIÍR: "A keresett gyök: ", tipp FELTÉTEL VÉGE PROGRAM VÉGE
A vezérlési szerkezetek tetszőleges mélységben egymásba ágyazhatóak. A lenti program egy szekvenciát tartalmaz, amelynek része a szám beolvasása és egy feltétel. A feltétel hamis ágában egy újabb szekvencia van, amely egy ciklust is tartalmaz.
23 Szintaxis (syntax)
Nyelvtani szabályok
- Összefoglaló nevük: szintaxis
- Minden nyelvben van, pl. magyarban is:
- Én alszom, ő alszik ← helyes
- Mi alszanak ← hibás
- A forráskód meg kell feleljen az összes szabálynak
Szintaktikai hibák
int x, a, b, c; printf("Az eredmény:") // lemaradt pontosvessző printf("%d\n", y); // y: ismeretlen változó x=2*(a+b+c; // lemaradt bezáró zárójel
24 EBNF: Extended Backus-Naur Form
EBNF: formalizmus a szintaxis leírására.
Jelölés | Jelentés | Példa |
---|---|---|
= | definíció | névelő = 'egy'; |
; | definíció vége | |
' ' | szöveg | |
| | „vagy” | számjegy = '0' | '1' | … |
, | összefűzés | negatív = '-', szám; |
[ ] | elhagyható | pozitív = ['+'], szám |
{ } | ismétlés | szó = betű, { betű }; |
egész szám
szám = nemnulla, { számjegy }; nemnulla = '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'; számjegy = '0' | nemnulla;
- Akárhány számjegyből állhat, nem kezdődhet nullával.
- Helyes: 98, 54079, 43, 1, 112.
- Helytelen: 1ax, abcd, s98, 012.
A C nyelv összes nyelvtani szabálya kb. 5 oldalnyi EBNF-fel leírható. De ezt most nem fogjuk megtenni.
EBNF leírást használnak a programozók is, akik egy nyelvet használnak, és szintaxisát szeretnék megérteni. De ebből dolgoznak azok is, akik a fordítóprogramot írják: ha matematikai precizitással adottak a nyelvtani szabályok, akkor a nyelv minden mondatát könnyű értelmezni. Ezzel még fogunk foglalkozni.
25 A C nyelv elemei
Név | Példa | Használat |
---|---|---|
kulcsszó (keyword) | int, double, return | a nyelv része, valamilyen kifejezett jelentése van |
azonosító (identifier) | x, terulet | valami neve, pl. változóé |
operátor (operator) | * + / | számítási művelet |
blokk (block) | { } | több utasítás, csoportosítás |
sztring (string) | "helló, világ\n" | szöveg |
megjegyzés (comment) | /* */ | programozónak szóló, megértést könnyítő szöveg |
26 Utasítások fajtái a C nyelvben
int x; double pi=3.14159265;
változódefiníció
x = y+z; printf("x=%d\n", x);
kifejezés
{ printf("Helló!"); return 0; }
utasításblokk
if (x<0) printf("Negatív"); else printf("Nem negatív");
vezérlési szerkezet
27 Kifejezések
printf("Helló, világ!\n"); x=3; printf("x+1=%d\n", // több sorba is írható x+1); printf("A négyzet oldalhossza?\n"); scanf("%lf", &a); printf("Átló=%f\n", a*sqrt(2)); // négyzetgyök (square root)
- A kifejezések konstansokból, változókból és operátorokból állnak.
- A kifejezés utasításokat pontosvessző zárja.
28 Változódefiníciók
Egy vagy több változó definíciója „kvázi EBNF”-ben:
típus név [=kezdeti érték] {, név [=kezdeti érték]};
Példák C-ben:
int x=3; // x nevű egész, kezdeti értéke 3 double f_1=0, f_2=0; // két valós, f_1 és f_2 int szam, SZAM; // inicializálatlanok. ez két különböző!
alulvonás
underscore
- A változó neve tartalmazhat betűket, számokat és
_
(alulvonás) karaktert. - Számmal nem kezdődhet, ékezetes betű sem lehet benne.
Egy változónak adhatunk kezdeti értéket (rögtön a definíciójakor). Ezt inicializálásnak is hívjuk, és pontosan ugyanaz, mint az értékadás. (Értéket többször is kaphat.) A változókat nem kötelező inicializálni, azonban figyelni kell arra, hogy ne használjuk az értéküket addig, amíg nem adtunk nekik.
29 Utasításblokk és egy C program váza
#include <stdio.h> // bemenet/kimenet utasításokhoz int main() { int x; // változó definíciók x=2*3; printf("%d\n", x); // utasítások return 0; // program vége }
A programunk maga is egy utasításblokk.
- A blokk elején lehetnek a változódefiníciók. (Csak ott!)
- Után pedig utasítások.
A blokkoknak csak az elején lehetnek változódefiníciók. Ez azt jelenti, hogy az összes szükséges változót az elején meg kell adnunk, neveikkel és típusaikkal együtt. Az nem baj, ha csak később kapnak értéket.
30 Vezérlési szerkezet: if()
elágazás
if (feltétel)
utasítás;
[ else utasítás; ]
if (x>0) // a feltétel zárójelben printf("pozitív!\n"); else printf("nem pozitív.\n"); // hamis ág (elmaradhat)
if (x<0) { // több utasítás: { } között x=-x; printf("x negatív volt.\n"); } // itt nem kell pontosvessző
Ha a feltétel következményében vagy hamis ágában több utasítás is van, az egy szekvencia, ami C-ben utasításblokként jelenik meg. Ezért kellenek a kapcsos zárójelek. Ha csak egyetlen utasítás van, akkor nincsen rájuk szükség, de nem is hiba kiírni őket.
31 Vezérlési szerkezet: while()
ciklus
ciklus
while (feltétel)
utasítás;
while (x>0) // a feltétel zárójelben x=x-1;
while (x>0) { // több utasítás: { } között printf("x=%d\n", x); x=x-1; }
32 Elöltesztelő ciklus: Hérón módszere (példa)
#include <stdio.h> #include <math.h> int main() { double szam, tipp; printf("Szám: "); scanf("%lf", &szam); tipp=1; while (fabs(tipp-szam/tipp) > 0.001) // |tipp-szam/tipp| tipp=(tipp + szam/tipp)/2; printf("%f gyöke %f.\n", szam, tipp); return 0; }
33 Vezérlési szerkezet: for()
ciklus
ciklus
for (innentől; idáig; így)
utasítás;
1 2 3 4 5
for (x=1; x<=5; x=x+1) // pontosvesszők! printf("%d ", x);
„for every value of x from (x=1; to x<=5; step by x=x+1)”
34 while()
és for()
ciklus: összehasonlítás
/* számok egytől tízig */ for (x=1; x<=10; x=x+1) printf("%d ", x);
x=1; while (x<=10) { printf("%d ", x); x=x+1; }
– Harold Abelson, Gerald Jay Sussman
A két kódrészlet pontosan ugyanazt csinálja.
- Mindig azt érdemes írni, amelyik áttekinthetőbb
- A gépnek mindegy, nekünk számít!
Érdekesség: Harold Abelson az MIT egyetem professzora, a Creative Commons és a Free Software Foundation alapítványok egyik alapító tagja. (Az utóbbi alapítványhoz tartozik a GNU projekt, amely keretében a Linux rendszert is fejlesztik. Ez az androidos okostelefonok alapja.) Társszerzője a Structure and Interpretation of Computer Programs könyvnek, amelyből a fenti gondolat is származik.
35 Számlálásos ciklus: szorzótábla
#include <stdio.h> int main() { int y; for (y=1; y<=5; y=y+1) { int x; for (x=1; x<=5; x=x+1) printf("%2d ", x*y); printf("\n"); } return 0; }
A szorzótábla kirajzolása két ciklussal. Kívül a sorok ciklusa (y, öt
iteráció), és azon belül soronként öt szám (x, öt iteráció soronként) és egy újsor karakter.
Az x
változó csak a belső ciklushoz van, így azt érdemes belül definiálni,
mert csak ott használjuk. A változódefiníció szabályait viszont ott is betartjuk: a blokkok
elejére kerül a definíció, és utána az utasítások.
36 A kód tördelése – „indentálás”
#include <stdio.h> #include <math.h> int main() { │ double szam; │ │ printf("Szám: "); │ scanf("%lf", &szam); │ if (szam<=0) { │ └─ printf("Pozitív kell legyen!\n"); │ } else { │ │ double tipp=1; │ │ while (fabs(tipp-szam/tipp) > 0.001) { │ │ └─ tipp=(tipp + szam/tipp)/2; │ │ } │ └─ printf("%f gyöke %f.\n", szam, tipp); │ } │ └─ return 0; }
Ez a program a vezérlési szerkezetek rész végén bemutatott négyzetgyökszámoló C nyelvű változata. Három dolgot kell megfigyelni rajta:
- A kód szedése. Az egyes vezérlési szerkezetek belsejében
lévő utasítások beljebb kezdődnek (indent). A programon
belüli utasítások is, ahogyan az
if()
-en belüliek és a cikluson belüliek is. Ez nagyban megkönnyíti a program áttekintését. - A kapcsos zárójelek
{}
használata. Ha egy vezérlési szerkezeten belül csak egy utasítás van (mint pl. azif()
igaz ágában vagy a ciklusban), akkor nem szükséges köré kapcsos zárójelet tenni. Azonban nem is lenne hiba sem, sőt talán attól is áttekinthetőbb kicsit a program. (Sokan azt vallják, jobb úgy használni.) A szintaktikai szabályok bemutatása miatt a fenti program a minimális számú kapcsos zárójelet tartalmazza. - Változódefiníció utasításblokk elején. A C megengedi azt, hogy
bármely utasításblokk elején változót hozzunk létre. Az a változó
azonban csak az adott utasításblokkban fog élni.
Jelen esetben a
tipp
nevű változó ilyen. Csak akkor van rá szükség, ha nem negatív számot kapott a program, és el kell végezni a számítást.

Hogy ki pontosan hova helyezi el a nyitó és záró kapcsos zárójeleket, hova tesz szóközöket a műveleti jelek köré stb. – ez ízlés kérdése. Rengeteg stílus alakult ki, amelyek közül a tananyagban az ún. K&R stílust fogjuk használni. (Persze itt-ott ettől eltérünk, főleg ha ezt az előadásban a dia szűkös mérete kényszeríti.) Ezt a stílust tréfásan egyiptomi zárójelezésnek is szokták nevezni, a kapcsos zárójelek elhelyezése miatt.