A PL/1 programozási nyelv

Utasítások, vezérlési szerkezetek

Utasítások, vezérlési szerkezetek

Kezdeti értékadás

A deklarációkban használható kezdeti értékadás, melyben egyszerűen megadhatók (vagy felsorolhatók) az elemek, akár hiányosan is, illetve minősítve is. De írható például ciklus is, amivel megkímélhetjük magunkat attól, hogy minden olyan inicializálandó elemet meg kéne adnunk, amely automatizálható.

Értékadás

Értékadás a szokásos, azzal a különbséggel, hogy a PL/1 támogatja a szimultán értékadást is. Ezt persze csak úgy, hogy a baloldalon több változó is állhat, de a jobboldalon csak egy kifejezés van megengedve.

Megengedettek a tömbökkel való műveletek, így például két tömb össze is adható, ha a méretük és típusuk azonos. Ha nem, kivétel keletkezik. Az egyes műveletek precedencia szintje azonos a megszokottakkal. Az operátorok nem definiálhatók át, nem terhelhetők túl, és nem is lehet bővíteni ezeknek a körét.

Megengedett az értékadás tömbökre is, amikor mind a baloldalon, mind a jobboldalon tömb (tömbkifejezés) áll.

A kifejezések belsejében, értékadáskor és paraméterátadáskor a PL/I nem követeli meg, hogy az értékek típusai megegyezzenek, megelégszik azzal, ha a típusok összeférhetők. Összeférhetők egymás közt a numerikus típusok, s bármely más esetben azok a típusok, amelyek között legfeljebb a hossz-specifikációban van eltérés. Az összeférhető típusok között a konverzió mindenütt automatikusan megtörténik.
A konverzió során a literálokhoz is típus- és hosszattribútumokat rendel a PL/I. A típusattribútum a literál írásmódjából következik, a hosszattribútumot az szabja meg, hogy mekkora az a legrövidebb tárolómező, amelyen az érték tárolható.

Azonos szerkezetű rekordok esetén a műveletek mindegyik elemi mezőre végrehajtódnak.
A PL/I azonban akkor is megengedi a rekordok közötti értékadást, ha azok mezői nem egyeznek meg, nem egyforma számúak, vagy nem ugyanabban a sorrendben vannak.

Struktúrák (szintezett változók) is értékül adhatók egymásnak. Ha a két struktúra nem egyezik meg, akkor használható a név szerinti értékátadás. Ekkor az azonos szinteken levő változókat név szerint illeszti a fordító.

Numerikus típusú változók esetén a konverzió implicit, esetleges csonkolással.

Az átvitel hosszát mindig a fogadó mező hossza határozza meg. Amennyiben a bal oldalon álló mező hosszabb, mint a jobb oldali, akkor karakteres fogadó mező esetén jobbról üres karakterekkel egészül ki, numerikus fogadó mező esetén pedig balról vezető nullákkal történik a feltöltés. Fordított esetben természetesen csonkolás történik.

Mivel lehetőséget ad a nyelv arra is, hogy egy memória területet többféleképpen is feloszthassunk (lsd. Adattípusok című fejezetben DEFINE kulcsszó ill. szintezett struktúrák) általánosan elterjedt módszer az értékadásra két különböző struktúra esetén az, hogy mindkét tárterületet először szint nélkül foglaljuk le, majd a kívánt, szintezett felosztást erre "húzzuk" rá. Ezek után az értékadás egyszerűen megtörténhet.

Érdekes lehetőség továbbá a nyelvben a konkatenálás, jelölése: ||. Ennek segítségével könnyen formázhatunk különböző, változó tartalma(ka)t is használó sztringeket, pl:

DCL SOR CHAR(100), 1 SORSTR DEF SOR, 2 URES CHAR(20) INIT (' '), 2 NEVIR CHAR(20), 2 FEJIR CHAR(40) INIT (' TÁBLÁZAT FEJRÉSZE'), 2 LAPIR PIC'ZZZZ9', 2 SZOVEG CHAR(15) INIT('.LAP '); DCL LAPSZ PIC'ZZZZ9' INIT(1), NEV CHAR(20) INIT ('EZ EGY NEV');

Ekkor :          NEVIR=NEV;   LAPIR=LAPSZ;

értékadások eredményeképpen a SORSTR (ami egyben a SOR nevű változó is!) tartalma:

"           EZ EGY NEV      TÁBLÁZAT FEJRÉSZE       1.LAP   "

A fenti eredmény elérhető:

SOR='       '||NEV|| '    TÁBLÁZAT FEJRÉSZE    ' ||LAPSZ||'.LAP';

értékadással is.(ekkor természetesen felesleges a SORSTR struktúra)

Feltételes elágazás

Az ALGOL 60 szerkezetét veszi át, de megengedi a THEN ágban a további IF-ek használatát blokkok nélkül. Ekkor persze ügyelni kell az ELSE ágak hovatartozásának egyértelműsítéséről. A feltételben tetszőleges kifejezés írható, de nagyon vigyázni kell az automatikus konverziókra. Feltételként megadható bitsorozat is, ekkor a feltétel akkor igaz, ha a bitsorozat legalább egy bitje 1. A feltételes elágazásra példák:

IF f1 THEN u1; ELSE u2; IF f1 THEN ; ELSE u2; IF f1 THEN u1; ELSE ; IF f1 THEN u1;
Azaz az üres utasítást nem kell kiírni, elég egy pontosvessző, és minden ELSE-t pontosvessző zár le.

A feltétel részben több feltétel összekapcsolása is lehetséges, a relációs jelek a matematikából megszokottak, ill. a negálás jele a régebbi klaviatúrákon még létező, a logikából jól ismert spec.jel, az "ÉS"-t a & jel, a "VAGY"-ot a | jelenti. Itt is az ÉS erősebben köt, mint a VAGY. Természetesen egy-egy THEN ill. ELSE után nem csak egy, hanem tetszőlegesen sok végrehajtandó utasítás is állhat, ilyenkor a blokk-képzés szintaktikája:
IF feltétel-rész THEN DO; ut11; ut12; .....ut1n; END;
ELSE DO; ut21; ut22; .....ut2m; END;
Az IF utasítások elméletileg bármilyen mélységig egymásba ágyazhatók, de a gyakorlatban ez a szám erősen fordító függő.(Általában 28-as mélység még megengedett, legfeljebb sok értelme nincs.....)

Többirányú elágazás

Többirányú elágazás nincs a nyelvben.

Ciklus

A DO utasítással írhatunk ciklusokat a PL/1-ben. Ez nagyon hasonlít a megszokott ciklusszervezési módokhoz. Írhatunk elöltesztelő ciklusokat, számlálós ciklusokat, vagy olyan ciklust, mely előre megadott értékekkel fut le. Ekkor felsorolással adható meg az értéklista. A számláló ciklusnál lépésköz is megadható. A felsorolt értéklista természetesen nem csak számérték lehet. Természetesen olyan ciklus is használható, ahol ezeket a szervezési módokat kombináljuk, így például írhatunk olyan ciklust is, mely először számlál, majd egy felsorolt értékkészleten működik, mindaddig, amíg egy WHILE feltétel igaz. Üres ciklus definiálható, ha a DO után pontosvesszőt írunk. Ekkor a ciklus egyszer fut le. GOTO-val is ki lehet lépni a ciklusból.

Elöltesztelő ciklus:
DO WHILE felt; ciklusmag; END;
Számláló ciklus lépésközzel:
DO v = k1 TO k2 BY k3; ciklusmag; END;

Elég sokféleképpen írható elő a ciklusmag végrehajtásainak száma (a ciklusváltozó által felvett értékek sorozata), pl:

DO I = 1 TO N BY 2; ...
DO N = 1 BY 1; ...
DO I = N TO 1 BY -1 WHILE(A(I) > 0); ...
DO WHILE(F(K) $<$ 1E10); ...
DO H=31,28,31,30,31,30,31,31,30,31,30,31; ...
DO J=1 TO 4, 4 BY 0 WHILE(A=0); ...
DO H=10,11,14 TO 22,24,26,30 TO 35,40,42;

Egyéb utasítások

A PL/1 még szerves része a GOTO, amit nagyon sok esetben célszerű is használni a fölösleges programrészek leírásának elkerülése végett. Ilyen alkalmazása a GOTO-nak az ON kivételkezelésben a leggyakoribb. A GOTO utasítás feltétlen vezérlésátadás kódolására szolgál. A PL/I nyelvben ennek az utasításnak sokkal kisebb a szerepe mint a korábbi nyelvekben. A utasítás argumentuma egy címke, vagy egy címkeváltozó lehet.

A RETURN utasítás a végrehajtás alatt levő alprogram befejezését, és a vezérlésnek a hívó alprogramba való visszatérését írja elő. Eljárásban a RETURN utasítás nem tartalmazhat argumentumot. Függvényben a visszatérési értéket is ebben az utasításban kell definiálni:

RETURN kifejezés;
formában.

Címkeváltozó

A PL/1 lehetőséget ad un. címkeváltozók használatára is, ami megfelel az assembly-ből ismert regiszter tartalma alapján végzett ugrásra. Ezt leginkább olyan esetben használjuk, amikor valamiért egy program-részt nem szubrutinként szeretnénk használni, ill. valamilyen feltételtől függően az adott program-szakasz végrehajtása után más-más helyen szeretnénk folytatni a programot. Ilyenkor egy LABEL típusú változót definiálunk a programunkban, és az adott programszakasz felhívása előtt beállítjuk a tartalmát a kívánt címkére. Talán legjobb, ha egy példával illusztrálom:

DCL CV LABEL; .... IF felt1 THEN CV=VISSZA; ELSE CV=TOVABB; GOTO RESZ; ..... VISSZA: ...... ...... RESZ: ut1_1; ut1_2; ... GOTO CV; TOVABB: ut2_1; ut2_2; ..... GOTO VISSZA;

Ez persze mai szemmel elég szörnyűnek tűnik...

További utasításokat vezettek be például a formázott és formázatlan input-output műveletekre. Az adatállomány-kezelés nagy erőssége a PL/1 nyelvnek. Ezekre mind külön kulcsszavakat vezettek be mind a deklarációban, mind az utasítások szintjén.