Szekvenciális vezérlés
Szekvenciális vezérlés¶
Szekvenciális vezérlésről akkor beszélünk, amikor a P probléma megoldását úgy kapjuk, hogy a problémát P1, . . . , Pn részproblémákra bontjuk, majd az ezekre adott megoldásokat (részalgoritmusokat) sorban, egymás után végrehajtjuk. P1, ... , Pn lehetnek elemi műveletek, de lehetnek összetettek is, amiket utána tovább kell bontani.
A szekvenciális vezérlés folyamatábrája jól szemlélteti, hogy a részproblémákat, amelyekből a P probléma felépül, szépen egymás után kell végrehajtani:
A szerkezeti ábrán pedig az látszódik, hogy a P problémának a megoldását a P1, ..., Pn problémák megoldásával kapjuk. Itt a sorrendiséget csak a felsorolás sorrendje jelzi számunkra:
A szekvenciális vezérlés C-beli megvalósítása a következő:
1 2 3 4 5 |
|
A továbbiakban különböző példák fogják segíteni, hogy a bevezetett fogalmakat megismertessük. A példák megvalósítása során a korábban bemutatott vízesés modellt fogjuk használni, ennek lépéseit követve fogunk egy-egy problémafelvetéstől eljutni a probléma megoldásáig, miközben persze kiemeljük az újdonságnak számító ismereteket.
Példa: eltelt idő kiszámítása¶
-
Problémafelvetés: Egy munkahelyen a dolgozóknak minden be- és kilépési időpontot regisztrálni kell. A munkáltató tudni szeretné, ki mennyi időt töltött bent, illetve ebből mennyi volt az ebédszünet. Ehhez kellene neki egy program, amivel a nap két időpontja között eltelt időt tudja kiszámolni.
-
Specifikáció:
-
perc pontossággal számolunk
-
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:
1 2 3
0 <= O1 < 24 és 0 <= P1 < 60 0 <= O2 < 24 és 0 <= P2 < 60 O1 < O2 vagy (O1 = O2 és P1 <= P2)
-
A kimenő adat a két bemenő időpont között eltelt idő óra, perc formában, jelöljük ezeket O és P-vel.
-
A kimeneti feltétel:
1
0 <= O < 24 és 0 <= P < 60
-
-
Algoritmustervezés: kétféleképpen számolhatunk. Vagy külön kiszámítjuk az eltelt órákat és perceket, és a végén korrigáljuk az adatokat, hogy azok a specifikációnak megfeleljenek, vagy előbb átváltjuk az időpontokat percekre, ezek különbségét vesszük, majd visszaalakítjuk az eredményt óra/perc formátumra.
-
Az eltelt idő percben kifejezve:
(60 * O2 + P2) − (60 * O1 + P1)
-
Tehát O, P akkor és csak akkor megoldás, ha
1 2
60 * O + P = (60 * O2 + P2) − (60 * O1 + P1), és 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.
-
-
Algoritmustervezés szerkezeti ábrával:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Már volt arról szó, hogy ahhoz, hogy futtatható programot készítsünk, a programunknak kell tartalmaznia egymain
függvényt, aminek a visszatérési értéke egy egész szám.
Ez 0, ha minden jól megy, így a programunk utolsó utasításában, a return
után egy 0
szerepel. Ha ide eljutott a program, akkor tulajdonképpen sikeresen lefutott.
Amikor egy programban változókat használunk, akkor azokat a változókat deklarálnunk kell, azaz meg kell nevezzük őket, és meg kell mondjuk, hogy milyen típussal is rendelkeznek majd.
A specifikációnak megfelelően van 6 darab változónk, illetve lesz egy hetedik, amiben eltároljuk az eltelt időt percekben, hogy aztán azt majd a megfelelő formára hozzuk.
A változóink deklarálásáról szólnak a 8-11. sorok.
Mindegyik változóban egy-egy egész értéket tárolunk el, emiatt a típusuk int
lesz.
Látható, hogy a változókat hol egy soron belül, hol több sorban deklaráltuk.
Amikor egy soron (illetve egész pontosan egy utasításon belül, amíg ki nem tettük a ;
-t) deklaráljuk a változókat, addig minden egyes változó ugyanazzal a típussal rendelkezik, vesszővel választjuk el őket egymástól.
Általában jó az, ha a program, ami a felhasználótól várja a bemeneti adatokat, jelzi is az igényeit a felhasználó felé. Ezt teszi meg a 13. és 15. sor.
Az adatok beolvasására a scanf
utasítás szolgál.
Ebben először egy formátum sztring által meg kell adjuk, milyen adatokat várunk az adott ponton, majd jeleznünk kell, mely változók kapják meg ezt az értéket.
A %d
egy darab egész érték beolvasását teszi lehetővé.
A változó neve előtt pedig van egy &
jel, amivel egyelőre ne foglalkozzunk, mit is jelent, egyszerűen jegyezzük meg, hogy amikor egy primitív adatot olvasunk be egy adott változóba, ennek ott kell lennie a változó neve előtt.
A kiíratások és beolvasások miatt a programunk legelején ott van az #include <stdio.h>
utasítás, így tudja majd a fordító, hogy a printf
és scanf
függvény pontosan miként van deklarálva.
Miután minden adatot beolvastunk, elvégezzük a tervezésben meghatározott számításokat, majd a megfelelő kiíratás által kiírjuk az eredményeket.
Mivel a kiírás során a változóink adatait írjuk ki, így most a printf
első paraméterében csak jelezzük, hogy adott ponton egész értékeket fogunk kiírni, majd a formátumsztring után a megfelelő sorrendben felsoroljuk a megfelelő kifejezéseket (most épp a változókat), amik értékét be akarjuk a kiírásba helyettesíteni.
Fontos!! Kiíratás esetén a változók neve elé NEM kell & jelet tenni.