
Elôzô számunkban megtárgyaltuk a programtervezés alapvetô miben létét,
az adat és típús fogalmát. Az értékadást és a kétágú szelekciót. Most a
kétágú szelekciótól tárgyaljuk a fontosabb momentumokat.
A kétágú szelekciók - folytatás
A kétágú szelekciók egymásba ágyazhatóak az alábbi forma szerint:
Persze az egymásbaágyazás nem jelenti azt, a stuktogram szabályait ne
tartanánk be, tehát nem lóghatnak át a téglalapok egymásba ! Természetesen
bizonyos esetekben egyszerűsíthetô a kétágú szelekciók felépítése bizonyos
logikai műveletekkel. Az egymásbágyazott kétágú szelekciókat olyan esetben
lehet egyszerüsíteni ha a külsô szelekció és a második belsô szelekció
igaz vagy hamisra elvégzendô tevékenysége ugyanaz. Ilyenkor a két megadott
feltételt vagy-gyal kössük össze.
Vagy séma:
Létezhet olyan két egymásba ágyazott szelekció is melynek elsô hamis
ága ki írja, hogy valami nem stimmel, az igaz ágában pedig a második szelekció
van. A második szelekció igaz ága adja meg a jó eredményt míg a hamis az
elsôhöz hasonlóan a hibát írja ki. Ekkor a két szelekció feltételét és-sel
kössük össze.
Az elsô példa elrettentés célját szolgálja:
Végig vesszük a logikai műveleteket melyeket a szelekciók feltételeinek
egyszerűsítésére is használhatunk:
A VAGY művelet:
-
A VAGY (OR, szép magyar szóval diszjunkció) művelet eredménye akkor
igaz ha legalább egyik operandusának logikai értéke igaz. Lássuk az egyszerűbb
megértés végett a logikai táblázatot két operandusra, rendre A-ra és B-re:
A |
B |
A VAGY B |
hamis |
hamis |
hamis |
hamis |
igaz |
igaz |
igaz |
hamis |
igaz |
igaz |
igaz |
igaz |
Az ÉS művelet:
-
Az ÉS (AND, szép magyar szóval konjukció) művelet eredménye akkor
és csak akkor igaz ha a résztvevô összes operandus (itt: feltétel logikai
értéke) igaz.
A |
B |
A ÉS B |
hamis |
hamis |
hamis |
hamis |
igaz |
hamis |
igaz |
hamis |
hamis |
igaz |
igaz |
igaz |
A NEM művelet:
-
A NEM (NOT, szép magyar szóval negáció) művelet eredménye mindig
a megadott operandusának ellenkezôje. Ellentétben a VAGY ill. ÉS művelettel,
csak egy operandusa van.
A |
NEM A |
hamis |
igaz |
igaz |
hamis |
A KIZÁRÓ VAGY művelet:
-
Ez a művelet nem egészen ide tartozik de elmondom elôre, hogy máskor már
ne kelljen magyarázkodni:
A KIZÁRÓ VAGY (eXclusive OR) művelet eredménye akkor
és csak akkor igaz ha a résztvetô operanusok közül pontosan egy igaz. Lássuk
az igazság táblázatot a segítség kedvéért:
A |
B |
A XOR B |
hamis |
hamis |
hamis |
hamis |
igaz |
igaz |
igaz |
hamis |
igaz |
igaz |
igaz |
hamis |
Most már probláema nélkül tudjuk módosítani a két egymásba ágyazott - így
dupla feltételű - szelekciót. Nincs más dolgunk mint, hogy összefüzzük
a két feltételt: HA az elsô ÉS a második feltétel is teljesül AKKOR hajtsa
végre az utasítás ellenkezô esetben mást csináljon. Az elrettentô példa
emészthetôbb formája:
A többágú szelekciók
Elôfordul, hogy adott változó esetén kölönbözô értékekre különbôzô
módon kell reagálni. Ez még nem is lenne baj, mert több kétágú szelekció
megvalósításával lehetséges is. Csak ott van a baj, ha már rengeteg értéket
kell lekezelni akkor óriási - áttekinthetetlen mértékig lesznek a kétágú
szelekciók egymásbaágyazva.
Ennek elkerülése végett van a több ágúszelekció, mint minden nyelv (szinte
minden nyelv) egyik alap eleme.
Stuktogramm beli ábrája:
Az ábráról is egyszerűen leolvasható, hogy különbözô értékekre különbözô
môdon reagál programunk. Amennyiben egyik értéket sem vette fel a vizsgált
kifejezés akkor lehetôség van egy egyébként ág kialakítására.
FONTOS, hogy vizsgálat során az elemeket mind fel kell sorolni, s nem
lehet olyan feltételt adni, mint pl. Egy kétágú szelekciónál, ha X <
0. Itt meg kell adni, hogy ha X: =-1, -2, -3, -4 Vagy X: [-1, -1000] intervallumban
van. Az intervallum megadása is véges sok elem felsorolásával egyenértékű.
Bizonyos programozási nyelvek megengedik az intervallum használatát (Pascal),
míg mások nem (C, C++).
Lássunk egy példát a használatra:
kisbetű ...
Itáráció - azonos tevékenységek egymás utáni ismételése adott feltétel
szerint
Ahogy a fejezet címben megadtam, az itáráció nem más, mint azonos tevékenységek
egymás utáni ismételése adott feltétel szerint. Típus szerint két féle
ciklust (a ciklus az iteráció (az ismétlés) nyelvi megjelenítô eszköze)
különböztetünk meg:
-
Elöl- és
-
Hátultesztelô ciklust
Mindkettôt különbözô esetekben használjuk. Ésszerű - megfelelô - használatuk
része a program optimalizálásának.
Az Elöltesztelô ciklus
Stuktogram ábrája:
Az Elöltesztelô ciklus jellemzôi:
-
A ciklust irányító feltétel kiértékelése a ciklus mag lefuttatása elôtt
történik ami azt jelenti, hogy nem feltétlenül biztos, hogy legalább egyszer
is lefutna a ciklus magja.
-
A ciklusban addig ismétlôdik a ciklusmag végrehajtása amíg a feltétel igaz,
mert lefutási-feltételt adtunk - ill. kell megadnunk.
-
Amennyiben a lefutási feltétel hamissá válik akkor a ciklusmag már nem
hajtódik végre, hanem a futtatás kilép a ciklusból, s a ciklus utáni elsô
utasítással folytatja tevékenységét.
Minden elöltesztelôs ciklusnál gondoskodnunk kell arról, hogy a lefutási
feltétel belátható idôn belül hamissá váljon, az-az a végrehajtás egyszer
kilépjen a ciklusból. Amennyiben ezt nem tesszük meg (vagy rosszul alakítjuk
ki a lefutásifeltételt) akkor a végtelen-ciklusba kerülhetünk, melynek
eredménye, hogy programunkból nem lehet kilépni, s sok galiba támad ...
Nézzünk egy példát ennek alkalmazására. Olvassunk be egész, elôjeles
számokat és adjuk ôket össze amíg 0-t nem ütünk be.
-
Látjuk elôször beolvastuk a számot. De miért ? Mert lehet, hogy valaki
véletlenül indította el a programot, és rögtön indítás után ki akar lépni.
Így ha 0-val kezdünk rögtön kilépünk.
-
Ha nem 0-val kezdtünk akkor az osszeghez hozzádja a beolvasott számot,
és újat kér be:
-
ha ez nulla volt kilép a ciklusból, ha nem újból hozzáadja, és így tovább.
-
Azt ugye észrevettük, hogy az elején ossz=0-t írtunk. Nos ezt azért tettük,
mert kezdôértéket kell adni minden változónak elsô használat elôtt, ugyanis
deklarálás után nem biztos, hogy 0-t tartalmaz. (Úgy is mondják, hogy memória
szemetet tartalmaz a még nem inicializált változó.)
A Hátultesztelô ciklus
Stuktogram ábrája:
A Hátultesztelô ciklus jellemzôi:
-
A ciklust irányító feltétel kiértékelése a ciklus mag lefuttatása után
történik ami azt jelenti, hogy biztos, hogy legalább egyszer lefut a ciklus
magja.
-
A ciklusban addig ismétlôdik a ciklusmag végrehajtása amíg a kiugrási feltétel
nem lesz igaz, mert kiugrási- és nem lefutási feltételt adtunk - ill. kellet
megadnunk. Tehát addig teker (ismétlôdik) a ciklus amíg a feltétel hamis.
-
Amennyiben a kiugrási feltétel igazzá válik akkor a ciklusmag már nem hajtódik
végre, hanem a futtatás kilép a ciklusból, s a ciklus utáni elsô utasítással
folytatja tevékenységét.
Minden hátultesztelô ciklusnál gondoskodnunk kell arról, hogy a kiugrási
feltétel belátható idôn belül igazzá váljon, az-az a végrehajtás egyszer
kilépjen a ciklusból. Amennyiben ezt nem tesszük meg (vagy rosszul alakítjuk
ki a kiugrásifeltételt) akkor a
végtelen-ciklusba kerülhetünk, melynek eredménye, hogy programunkból nem
lehet kilépni, s sok galiba támad ...
Nézzünk meg az elôzô példát átalakítva: (Olvassunk be egész, elôjeles
számokat és adjuk ôket össze amíg 0-t nem ütünk be.)
-
Láthatjuk elôször inicializáljuk az osszeg változót.
-
Majd beolvassuk az elso szam-ot, ha ez 0 akkor hozzáadja az osszeghez,
az-az nem változik semmi, és kilép.
-
ha nem nulla az alsô szám akkor hozzáadja az osszeg-hez és elôrôl
kezdi a ciklust, stb.
Ez a példa persze úgy sikerült, hogy mind a két megoldás jó. Ez egy speciális
helyzet, a két különbözô ciklus-fajta működését tekintve más így nem alkalmazhatjuk
kényünk - kedvünk szerint hol az egyiket hol a másikat.
Léptetéses ciklus - az elöltesztelô speciális
változata
Gyakran elôfordulnak olyan problémák
melyekben elôre magadott (vagy a felhasználó által megadott) számszor
kell egy cselekmény(sorozatot) végrehajtani. Mivel tudjuk mennyiszer kell
végrehajtani kialakíthatunk egy olyan elöltesztelô ciklust melynek feltétele
a attól függ, hogy a ciklus változó elérte -e már a kívánt értéket (az-az
db-szor végrehajtotta e a tevékenységet - a ciklusmagot.)
Lássuk hogyan oldhatnánk meg általánosan egy elöltesztelô ciklussal
azt, hogy x-szer hajtson végre egy tevékenységet:
Ebbôl az általános elöltesztelô ciklusformából alakították ki az új
nyelvi - és stuktogrami- elemet a léptetéses ciklust:
Az elôzô példánkat melyben 0 végjelig olvastuk be a számokat modosítsuk
úgy, hogy megkérdezzük a felhasználótól, hány számot kíván beolvasni, majd
beolvassuk az x számot és összeadjuk. Íme a stuktogram:
A megismert stuktogram elemek nyelvi
használata
Minden cikkünkben lesz egy
ilyen rész melyben az elmélet során megismert formulákat a két legismertebb
nyelvben a C és Pascal nyelvben kipróbáljuk. Ezt azért tesszem, hogy könnyebbé
tegyem az érdeklôdô Olvasó feladatat. Nem megyünk az adott programozási
nyelv mélységeibe, mert ezt már megtették az abC ill. Pascal Iskola rovatok.
Csak a stuktogram formulához illô témákat tárgyaljuk.
Röpke áttekintés kedvéért nézzük meg hogyan épül fel egy Pascal ill
C program:
program {a programfej - programnevének megadása}
uses {az esetlegesen használt modulok neve}
{deklarációk kezdete}
label {NA ezt a parancsot NE használjuk.}
const {Konstansok deklarálása}
type {Típusok definiálása}
var {Változók deklarálása}
procedure ... {Rutinok részletes kifejtése}
var ... {lokális deklarációk}
begin
utasítások;
end;
function ... {Értékkel visszatérô rutinok (funkciók)
részletes kifejtése}
var ... {lokális deklarációk}
begin
utasítások;
end;
{deklarációk vége}
BEGIN {A program fô részének kezdete}
utasítások; {utasítások}
...
END. {A program fô részének vége}
-
Egy C program általános felépítése:
<preprocessziós parancsok>
<egyéb használt modulok megadása>
<típus definíciók>
<függvény prototípusok>
<globális változók>
<függvények>
<típus> FüggvényNév(<paraméterek>)
{
<lokális deklarációk>
utasítások;
<return <visszatérési érték>>
}
<típus> main(<paraméterek>)
{
utasítások;
<return <visszatérési érték>>
}
Láthatjuk, hogy a C nyelv
felépítése sokkal lazább, nincs mindennek kötött helye. Viszont sokkal
szigorúbb más tekintetben, a kis- és nagybetűk terén melyeket megkülönbözteti
- ez Unix maradvány, ill. minden nevet - deklarálni kell.
Nos lássuk az értékadást, mint elsô fontos m?veletünket:
-
Pascal:
A_Halmaz := B_Halmaz;
A halmazoknak vagy azonos típusúaknak kell lennie, vagy típus konverziót
kell alkalmazni.
-
C:
a_halmaz = b_halmaz;
Láthatjuk, hogy mindkét nyelv esetében az egyenlôség jellel adjunk
értéket az BAL oldalon álló változónak.
A különbség, hogy Pascal-ban := (tehát kettôspont és egyenlô)
Változó deklarálása:
-
Pascal:
A fenti program sémában megadott helyeken a:
var VáltozóNév1, VáltozóNév2: Típus;
forma alapján.
-
C:
1, Minden blokkon kívül: lehet globális
(mindenhol elérhetô) változót deklarálni (lásd a C prg. Sémát)
2, Elvileg bármely blokkban, lehet csak ott elérhetô, lokális változót
deklarálni (lásd a C prg. Sémát)
Formula:
Típus válotzónév1, változónév2, ...;
Adat bevitele:
Ezt csak parancs szintjén, mert az abC ill. Pascap rovatban volt már róla
szó:
-
Pascal:
var X: Word;
BEGIN
ReadLn(X);
END.
-
C:
#include <stdio.h>
void main()
{
int X;
scanf("%d", x);
}
Kétágú szelekció:
-
Pascal:
if logikai_feltétel
then utasítás1
else utasítás2;
A then ágba akkor kerül ha igaz a feltétel, ha hamis akkor az else
ágba jut.
-
C:
if (logikai_feltétel)
{ utasítás1; }
else {utasítás2;}
Az utasítás1-et igaz érték (1) esetén hajtja végre, az else utánit
ha hamis.
FIGYELEM: Az else utasítás mindig a hozzá legközelebb álló else-vel
nem párosított if-hez fog tartozni, így megfelelôen {}-jelezzünk !
Egymásbaágyazott kétágú szelekció:
-
Pascal:
if logikai_feltétel
then if logikai_feltétel2 then utasítás1
else utasítás2
else utasítás3;
A then ágba akkor kerül ha igaz a feltétel, ha hamis akkor az else
ágba jut.
-
C:
if (logikai_feltétel)
{ if (logikai_feltétel2) {utasítás1; } }
else {utasítás2;}
else {utasítás3;}
Persze ez a zárójelezés csak példa ha azt aharjuk, hogy az else másik
if-hez tartozzon nem így kell zárojelezni.
Többágú szelekció:
-
Pascal:
var betu: Char;
case betu of
'a'..'z': WriteLn('Kisbet?');
'A'..'Z': WriteLn('Nagybet?');
'0'..'9': WriteLn('Szám');
' ' : WriteLn('Space');
else WriteLn('Más karakter');
end;
-
C:
char betu;
switch (betu) {
case 'a': case 'b': és fel kell sorolni
egészen z-ig és: printf("Kisbet?"); break;
case 'A': case 'B': és fel kell sorolni egészen
Z-ig és: printf("Nagybet?"); break;
case '0': case '1': és fel kell sorolni egészen
9-ig és: printf("Szám"); break;
default: printf("Más karakter"); // itt elhagyható
a break;
}
Látjuk, hogy Pascal-ban megadhatunk intervallumot is, míg C-ben fel
kell sajna sorolni az összel elemet. Pascalban a hatásköre a kiválasztott
elem után 1 parancs vagy begin - end; közé rakva több. C-ben hasonlóan,
csak break-kal ki kell szálni a switch-bôl, hogy az elsô jó elem után NE
vizsgálja meg a többit.
Elöltesztelô ciklus
-
Pascal-ban:
while lefutási_feltétel do
begin
{ciklusmag}
end;
-
C-ben:
while (lefutási_feltétel) {
// ide jön a ciklusmag
}
Hátultesztelô cilkus
-
Pascal:
repeat
{ciklusmag}
until kilépési_feltétel;
-
C:
do {
//ciklusmag
} while (lefutási_feltétel);
FIGYELEM: A Pascal hátultesztelô ciklusa megegyezik a stuktogram szerinti
felépítéssel, az-az a kilépési feltétel kell amíg a C-ben NEM, mert ott
a lefutási feltétel kell !!!
Következô számunkban folytatjuk a léptetéses ciklus
Pascal ill. C formuláját, majd a stuktogram elemeit.
Amennyiben valakinek kérdése van a fent elmondottakkal kapcsolatban,
az írjon az alábbi eMail-cimre.
Bérczi László
Köszönetet mondanék fôiskolai
tanáromnak, Bálintné Farkas Judit tanárnônek a felhasznált irodalomért
([1]), és segítségért.
