Strukturált programozás

A Wikipédiából, a szabad enciklopédiából

A strukturált programozás egy programépítési alapelv. A lényege az, hogy az elvégzendő feladatot kisebb, egymáshoz csak meghatározott módon kapcsolódó részfeladatokra kell felbontani, ezeken belül ugyanígy részfeladatok határozandók meg, amelyek teljes egészében megvalósítják az őket magába foglaló nagyobb részfeladatot, és így tovább. A cél az, hogy a teljes feladat olyan kis feladatelemekre legyen felosztva, amelyek egymással nincsenek átfedésben, egymáshoz meghatározott logika szerint kapcsolódnak, és mindegyik megoldható valamilyen elemi struktúra, elemi programséma követésével, esetleg egy programnyelv saját elemi eszközeivel. A részfeladatokat megoldva és azokat egymáshoz illesztve megszületik a teljes feladat megoldása.

A struktúra (latin: structura, angol: structure, holland: structuur) jelentése 'szerkezet', a név a feladat, illetve program jól meghatározott szerkezeti elemekből való szabályos felépítésre utal.

A feladat felosztásakor a részfeladatok csak három szerkezeti mintázat szerint kapcsolódhatnak egymáshoz, ezek a szekvencia, a feltételes elágazás (szelekció) és a feltételes ciklus (iteráció vagy véges ismétlés).

Az elvet a holland Edsger Wybe Dijkstra nevéhez kötik, aki korábbi, hasonló tárgyú cikkei után társszerzője volt az 1972-ben, Structured Programming címmel megjelent könyvnek[1].

Az alapelemek[szerkesztés | forrásszöveg szerkesztése]

Structured program patterns.png

A képen a három alapelem ábrázolási módja látható a ritkábban használt dobozdiagram (kék) és az általánosan használt folyamatábra (zöld) jelzésrendszerében. Az előbbi kifejezetten a három elemi séma jelölésére lett kidolgozva.

A szekvencia alapelem csak annyit jelent, hogy a részfeladatok, illetve azok megvalósítása valamely programnyelvben egymás után következnek, a jelzés szerint felülről lefelé hajtódnak végre. A program elve vagy nyelvi megvalósítása a strukturálás során eljut odáig, hogy a szekvenciában (lépéssorozatban) tovább már nem bontandó elemi műveletek vagy elemi utasítások (statement) követik egymást.

A feltételes elágazás (más néven szelekció)[2] egy megadott feltétel (condition) teljesülését vizsgálja meg (például egy programváltozóban tárolt számérték nagyobb-e száznál), és eszerint folytatódik a program végrehajtása az "igen" (y) és "nem" (n) esetekre előírt műveletekkel.

Egy nagyon rövid példarészlet egy dobozdiagramos programtervre

A feltételes ciklus (más néven hurok, ismétlés vagy iteráció) olyan alapstruktúra, amelyben amíg egy megadott feltétel (condition) teljesül, addig és csak addig végrehajtja a feltételhez rendelt ciklusmag műveleteket, egymást után újra megismételve. Például amikor a könyvespolcon valamilyen sorrendben addig vesszük le, nyitjuk ki, majd tesszük vissza egyenként a könyveket, amíg meg nem találunk benne egy bizonyos részletet.

Az elmélet fontos részét képezi az a szabály is, hogy ezeknek az alapelemeknek a dobozai egymásba helyezhetők tetszőleges mélységig. Ahol tehát a vázlatban egy utasítás (statement) helye látható, oda a három alapelem bármelyikének betehető egy példánya, azokba újabbak és így tovább, szükség szerint.

Mivel az egymásba helyezett dobozok a rajzokon és vázlatokban egy bizonyos mérték után már nehezen követhetők, megengedett, hogy egy adott feladatrészt megvalósító dobozok helyére csak egy címkét tegyünk, és egy külön rajzban részletezzük a címke helyén értendő műveletsorozatot, dobozokat. Bármelyik doboz helyettesíthető egy egyedi címkével, de a címkével helyettesített programegység dobozát külön helyen ugyancsak a három alapelem használatával kell kidolgozni. A címkézett, külön helyen részletezett szerkezeti egységek legkisebbjét a programokban eljárásoknak (procedure) hívják. Fontos: egy programegységet helyettesítő címke több helyen is elhelyezhető, ez esetben minden címke helyett ugyanazt az egységet kell odaképzelni.

GOTO[szerkesztés | forrásszöveg szerkesztése]

A GOTO (ejtsd: gótu) egy programnyelvi utasításszó, ebben vagy más azonos jelentésű formában számos programozási nyelvben létezik. A jelentése az, hogy a számítógép a program végrehajtása során a rendes esetben elejétől végéig követett utasítássorozatot egy másik, megadott helyen folytasson. Erre az ugrás néven emlegetett műveltre rendszerint elágazások vagy ciklusok megvalósítása céljából kerül sor, de használható más célból is.

Dijkstra nyilvánosan kikelt a GOTO utasítás ellen,[3] és külön ellenezte a BASIC oktatását az iskolákban, mivel ez a programnyelv volt a legszélesebb körben ismert azok közül, amelyekben – a strukturált alapelemek maradéktalan követését megvalósító elemi utasítások híján – sűrűn használták ezt az utasítást.[4] A GOTO elleni indulatot azzal magyarázhatjuk, hogy a programozást még csak tanulók a programjaikban az ugrást sokszor olyan nehezen követhető következetlenséggel használják, a programban hirtelen felfedezett hibák áthidalására, ami végső soron egy rossz, a programok javítását nagyon megnehezíthető, a jövőben sok nehézséget okozó programfejlesztési megoldásra való rászokáshoz vezet. A GOTO utasítás ugyanis a programban bármekkora ugrást, sőt, a kisebb, önmagukban logikus szerkezeti egységekbe való beugrást is lehetővé teszi, ami miatt a program szerkezete valóban hasonlítani kezd a "spagetti-kód" csúfnévre.

A GOTO használata azért volt elkerülhetetlen, mert az akkori, elsősorban oktatásra, otthoni használatra szánt számítógépekbe épített BASIC nyelvekből még hiányzott a dobozszerű szerkezetet szemmel láthatóan, formailag megvalósító utasítások egy része. (Például a DO ... WHILE vagy IF ... END IF szerkezeti elemek.) Ezeket, ahogy a fenti ábra is mutatta, megfelelően ki lehet váltani az ugrás helyes alkalmazásával, de az ugrás alkalmazható helytelenül is. Valójában az oktatás során az ugrás helyes alkalmazását kell(ene) megtanítani, de ha a használni szándékozott programnyelvben léteznek a strukturált alapelemek, ott valóban ritkán van szükség ugrásra, és a program követhetősége (egyben javíthatósága) érdekében érdemes is kerülni azokat.

A másik, legalább ilyen komoly ok a GOTO használatára pedig az volt, hogy az egyszerű BASIC nyelveken írt programokhoz nem létezett olyan szövegszerkesztő, amellyel egyes programegységek sorrendjét egyszerűen meg lehetett változtatni, azok átrendezésével. Így ha a program írója változtatni akart a részek végrehajtási sorrendjén, ugrással kellett áthidalnia a távolságot, nem azért, mert így jó, hanem mert csak ez volt lehetséges.

A BASIC nyelvet a hivatásos programozók között gyakran fogadó ellenszenv mára valójában értelmetlenné vált, mivel a leginkább használatban levő, igen fejlett változatokban a GOTO használata ma már nem szükséges a feladat megoldásához, nem is szokás használni, és az oktatása során is a strukturált alapelemek használatát tanítják.

Helyes használata[szerkesztés | forrásszöveg szerkesztése]

Az ugrás mindezek ellenére sem nevezhető programtechnikai hibának, az assembly nyelvű, sokszor a legnagyobb végrehajtási sebességet megkövetelő feladatokat megoldó programokban ma is egy megszokott lépés. A program követhetőségének fenntartásához viszont teljesíteni kell ehhez a következő feltételeket:

  • az ugrás távolsága ne legyen túl hosszú. Ha egy programrészt át kell ugranunk, akkor azt egy vagy több kisebb egységre bontva, eljárásként elkülönítve, csak címkéjükkel helyettesítve kell elhelyezni, lásd fentebb. Így a látható programkódban az ugrás a programrészek helyett csak azok címkéit ugorja át, így már sokkal közelebb került egymáshoz az ugrás kiinduló- és végpontját adó két programpont.
  • az ugrásokat a program mellé rajzolt vonalakkal helyettesítve a vonalak lehetőleg minél kevesebbszer keresztezzék egymást.
  • a strukturált programegységeket célszerű mindig egyetlen ponton elhagyni.
  • a strukturált programegységek (például egy szubrutin vagy FOR ... NEXT ciklus) belsejébe azokon kívülről beugrani tilos.
  • a programban visszafelé irányuló ugrást csak ciklus létrehozására szabad használni.

A program egy adott pontja több különböző helyről végzett ugrás célpontja is lehet.

Strukturált utasítások Pascalban[szerkesztés | forrásszöveg szerkesztése]

Összetett utasítás – szekvencia[szerkesztés | forrásszöveg szerkesztése]

BEGIN
[ utasítás [;utasítás …]]
END

Elágazás – szelekció[szerkesztés | forrásszöveg szerkesztése]

IF feltétel THEN utasítás
[ELSE utasítás ]

Ha ELSE-t elhagyjuk, akkor a szelekció egyágú Utasítás lehet összetett utasítás, így egy ágon több utasítás is végrehajtható. Utasítás lehet újabb IF utasítás. ELSE mindig a legutolsó THEN párja.

Választás – szelekció[szerkesztés | forrásszöveg szerkesztése]

CASE szelektor OF
’állandó’ : utasítás;
’állandó’ : utasítás;
ELSE utasítás
END;

Források[szerkesztés | forrásszöveg szerkesztése]

  1. O.-J. Dahl, Edsger W. Dijkstra, C. A. R. Hoare: Structured Programming (Academic Press, London, 1972)
  2. A szelekció név valójában több lehetséges programág közül egy bizonyos feltétel megvizsgálásával történő választást jelenti; az elágazás, mint alapelem eredetileg két lehetséges programágra korlátozza a választást.
  3. A Case against the GO TO Statement
  4. Megjegyzést érdemel, hogy a minden programnyelv végső eredményét adó gépi kódban is a program fontos és nélkülözhetetlen eleme az ugró utasítás, ennek az assembly mnemonikja többnyire JUMP vagy JMP.