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:

kep

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:

kep

A szekvenciális vezérlés C-beli megvalósítása a következő:

1
2
3
4
5
{
  P1;
  ...
  Pn;
}

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:

kep

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* Egy nap két időpontja között mennyi idő telt el.
 * 1997. Szeptember 26.  Dévényi Károly, devenyi@inf.u-szeged.hu
 */

#include <stdio.h>

int 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 */
    /* 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 = 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);
    return 0;
}

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.


Utolsó frissítés: 2020-10-13 06:15:04