A PL/1 programozási nyelv

Típusok, típuskonstrukciók

Típusok, típuskonstrukciük

A PL/I-ben háromféle literál írható: szám, sztring és bitsorozat. A karaktersorozatokat aposztrófok közé írjuk (ha a karaktersorozat maga is tartalmaz aposztrófot, azt meg kell kettõzni. Bitsorozatot aposztrófok közé zárt 0, 1 sorozattal adhatunk meg, amit egy B követ. Mindkét esetben használhatunk ismétlési tényezõt, ami egy a kezdõ aposztróf elé zárójelbe írt természetes szám, s azt jelenti, hogy az aposztrófok között lévõ sorozat ennyiszer egymás után leírva értendõ. pl: 'Hello', '?', (15)'*', '01'B.
A láthatóság és élettartam kérdésében a megszokott blokkstrukturált szerkezet érvényesül. A deklarációkban megadható az, hogy egy változó élettartama a deklaráció után a program végéig szól, de a láthatóságát már nem szabhatjuk meg. Ezekre kötött, a megszokott szabályok vonatkoznak.
A változók, alprogramok deklarációja a DECLARE kulcsszóval adható meg, ami futásidõ alatt kerül kiértékelésre, így lehetõség van más változókra is hivatkozni (pl. kezdeti értékadásban). A változó típusa statikus, a deklaráció után nem változtatható meg.
A PL/1 megengedi az implicit deklarációt is, így például, ha a változó I, J, K, L, M, N betûkkel kezdõdik, akkor a változó BIN FIXED típusú lesz, ellenkezõ esetben DEC FLOAT.
A változók deklarációjában különbféle attribútumok mondhatók. Az AUTOMATIC kulcsszó a tárterület deklaráció pontján való lefoglalását jelenti, aminek az ellentéte a CONTROLLED. Ekkor a programon belül az ALLOCATE és FREE utasításokkal foglalhatjuk le a tárterületet, illetve szabadíthatjuk fel. A STATIC attribútum esetén is azonnal lefoglalódik a tárterület, de a program teljes mûködése során élni fog. Ekkor csak a láthatósági szabályok határozzák meg, hogy mikor lesz használható. Az EXTERNAL kulcsszó mondja meg, hogy külsõ, másik fordítási egységben található a deklarált változó vagy eljárás.

Egy változó típusa az alábbi módon adható meg a nyelvben:

[s]<azonosító>[(i,[i...])][t][h][e] , ahol: s - szint i - index t - típus h - hossz e - egyéb

Szint

Lehet tömböket definiálni a szokásos módon, ahol megadható az indextartomány, ezzel együtt a dimenziószám, mely maximum három dimenziósig ajánlott. A tömbök ábrázolása a memóriában sorfolytonosan történik. Az indexelés hagyományosan történik, az indexeket kerek zárójelek közé tesszük. Megengedett, hogy az indexkifejezés valós értékû legyen, ekkor annak az egészre kerekített értéke számít indexnek. Többdimenziós tömbök esetén nemcsak az egyes elemekre vonatkozó szelekciós mûvelet használható, hanem kiválaszthatjuk pl. a mátrix egy sorát vagy oszlopát is a '*' joker karakterrel. A tömbökre is értelmezve vannak a szokásos mûveletek. Pl.:

DECLARE A(-2:3) 1x6-os tömb DECLARE B(3,2) 3x2-es tömb

A subset 3 dimenziós, a teljes változat 7 dimenziós tömböket enged meg.

Definiálhatók egyindexû tömbök, azaz vektorok, kétindexû tömbök, vagyis mátrixok, és minden PL/I -változatban definiálhatók még háromindexû tömbök is, a további dimenziók megléte már változatfüggõ. Az indextartomány minden esetben az egész számok egy intervalluma lehet, tehát megengedettek a negatív indexek is. Amennyiben az indexhatárok megadásakor az alsó határt elhagyjuk, az 1 lesz az érvényes alsó határ.

DCL A(10) FIXED BIN; DCL (B, C)(M+1,N+1) FLOAT;


Azonos dimenziójú, és dimenziónként azonos méretû numerikus tömbökre megengedettek az aritmetikai mûveletek, s azok elemenként hajtódnak végre, valamint megengedettek a tömb és skalár közötti mûveletek, amikor a mûvelet a tömb valamennyi elemére elvégzõdik. Ugyanígy használhatók a vektorokra a numerikus értékekre megengedett relációk is, ám ezeknek az eredménye nem egy bit, hanem egy bitsorozat lesz.

Típus

Numerikus típusai a PL/1 nyelvnek a

FIXED DECIMAL, FIXED BINARY, FLOAT DECIMAL, FLOAT BINARY.

A DECIMAL kulcsszó jelenti azt, hogy binárisan kódolt decimálisan, a BINARY esetén pedig binárisan tárolódik a változó értéke. A numerikus értékekre a szokásos mûveletek a megengedettek, valamint a nyelv tartalmaz még számos függvény a matematikai számítások elvégzésére. (pl. trigonometrikus függvények)

A számok megadhatók decimális vagy bináris formában, ezen belül lehetnek egész, fixpontos vagy lebegõpontos számok. Pl: +2.719, 11E-14, -1.85E6, 111B, +1B, -101101E3B, 11.001E2B. Megadható az is, hogy az ábrázolás hány (bináris, ill. decimális) számjegyen történjen. Decimális számjegy ábrázolása négy biten történik. Az elõjel feljegyzésére a szám végéhez a PL/I még egy számjegyet hozzátesz (és itt jelzi a pozitív, a negatív számokat - és hexadecimális értékek). (Bináris számábrázolás esetén a PL/I is a szokásos kettes komplemens ábrázolást alkalmazza.) A feltételezett és maximális hosszakat az alábbi táblázatba foglaljuk össze:

típus
feltételezett hossz
maximális hossz
FIXED DECIMAL
(5,0)
15
FIXED BINARY
(15,0)
31
FLOAT DECIMAL
(6)
16
FLOAT BINARY
(21)
53

A numerikus értékekre megengedettek a szokásos mûveletek, a +, -, *, /, ** (hatványozás), =, < , < =, > , > . A numerikus típusokra a PL/I bevezet predefinit matematikai függvényeket is. Az alábbi táblázatban ezeket soroljuk fel (a trigonometrikus függvények argumentuma és eredménye radiánban értendõ) :

atan(x) arcus tangens
atanh(x) arcus tangens hip.
cos(x) cosinus
cosh(x) cosinus hip.
sin(x) sinus
sinh(x) sinus hip.
tan(x) tangens
tanh(x) tangens hip.
abs(x) abszolútérték
sign(x) elõjel függvény
exp(x) exponenciális függvény
sqrt(x) négyzetgyök
log(x) természetes alapú logaritmus
log2(x) 2-es alapú log.
log10(x) 10-es alapú log.
floor(x) felsõ egészrész
ceil(x) alsó egészrész
trunc(x) abs(x)-nél nem nagyobb, legnagyobb egész szám
max(x,y,...) maximum függvény
min(x,y,...) minimum függvény
mod(x,y) modulo
round(x,n) kerekítés
prod(t) tömb elemeinek szorzata
sum(t) tömb elemeinek összege

A Round(x,n) függvény a tizedesponthoz képest n. számjegynél végzi el a kerekítést.

Az alábbi példában egy olyan programot mutatunk, ami 1 és 50 között kiírja a 7-tel osztható számok köbét!

E1 : PROC OPTIONS(MAIN);
DCL K FIXED BIN;
DO I = 1 TO 50;
IF FLOOR(I/7) = I/7 THEN
PUT EDIT (I, I**3) (SKIP, 2F(8));
END;
END E1;

Karakteres (string) típus a CHARACTER(n) jelenti, ahol 0<n<256. Megadható egy VARYING kulcsszó a változó hosszú string-ek kezeléséhez. Itt értelmezve vannak a relációk, a konkatenáció (||), illetve egyéb string mûveletek, például substr, length, index, <, <=, stb. Továbbá létezik a SUBSTR pszeudováltozó, melyet egy értékadás bal oldalán szerepeltetve helyettesíti a paraméterekben megadott stringben az adott pozíciótól kezdve adott hosszon az értékadás jobb oldalával.

A PICTURE típus tulajdonképpen formátumvezérelt numerikus típus. A COBOL nyelvhez hasonlatos, és használata azért célszerû, mert ennek a típusnak van közvetlenül HL Assembler nyelvben támogatása, így hatékonyan lehet dolgozni az ilyen numerikus típusú változókkal.

PIC'999999' (vagy PIC'(6)9' ),ekkor a változó csak numerikus értéket vehet fel, PIC'(5)X' esetben alfanumerikus lesz a mezõ, PIC'AAAA' alfabetikus lesz.

További finomságai a numerikus értékû PIC mezõnek:

DCL VALT PIC'ZZZBZZ9V,(5)9R'
deklaráció eredményeképpen a VALT nevû változó értékének kiírásakor a felesleges vezetõ nullák "elnyelõdnek" (Z=zéróelnyomás),
a B hatására ott üres karakter fog megjelenni (tagolás)
6 egész 5 tizedes ábrázolására képes (V=a tizedes vesszõ helye a mezõben)
és mivel a V után a vesszõt is beleírtuk a deklarációba, ezért megjelenítéskor ez látszani fog.
az R hatására negatív számot is képes ábrázolni, megjelenítéskor itt - jel lesz, ha az érték valóban negatív.

Tehát VALT=003412.0300; megjelenítéskor 3 412,03 lesz. Formázás nélkül ez 341203-nak látszana, ami elég sok bonyodalmat okozna.... A beleírt pont vagy vesszõ NINCS összhangban a tizedesek számával, ahová a programozó beírta, ott megjeleníti.
Pl. ha PIC'999.99' értékül kapja 314 egész számot, akkor a megjelenítés 3.14 lesz.

Ezeken kívül még számtalan formátum vezérlõ karaktert ismer, ezek taglalásától most eltekintek.

Bitsorozatok is definiálhatók, melyek kezelhetõk string-ként is, de speciális bitsorozat mûveletek is értelmezve vannak, pl a vagy, és, tagadás mûveletek, valamint a relációk is.

DECLARE BETA BIT; BETA='11000111010'B;
DCL B1 BIT(4); DCL B2 BIT(10) VARYING, BB(8) BIT(16);
A fenti deklarációk bitsorozatokat és egy bitsorozat-vektort definiálnak. A VARYING attribútummal ellátott változó tetszõleges (itt legfeljebb 10) hosszúságú bitsorozatot vehet fel értékül, a többi bitsorozat rögzített hosszúságú. Legfeljebb 64 bitbõl álló bitsorozatok definiálhatók. A bitsorozatokra értelmezve van a tagadás, a logikai és (&) és a logikai VAGY ( | ) mûvelete. Ezek mind bitenként kerülnek végrehajtásra. A kétoperandusú mûveletek nem követelik meg, hogy az operandusok azonos hosszúságúak legyenek, a rövidebb sorozatot nullákkal kiegészítik. A mûveletek eredménye mindig az operandusokkal megegyezõ hosszúságú bitsorozat lesz. Értelmezve vannak még a < , < =, ... relációk is. Ezek a bitsorozatokat bitrõl-bitre összehasonlítják, s az elsõ eltérõ bit alapján állapítják meg a reláció értékét. A bitsorozatokra is definiálva vannak a konkatenáció ( | | ) mûveletek.

Szintszám

További konstrukciós lehetõség a struktúrák használata. Ez a rekordtípus megvalósítása, mely szintszámmal jelzett deklarációban adható meg, és szokásos rekordtípusra vonatkozó '.' mûvelettel lehet minõsíteni.

DECLARE 1 KARTYA 2 SZ 2 DATUM 3 EV 3 HONAP 3 NAP 2 EA;

Azonos típusú struktúrák értékül adhatók egymásnak, de lehetséges név szerinti értékadás, ahol a struktúra változót a nevük alapján kapcsolja össze a fordító.

Egyéb

A PL/I tartalmaz egy, a FORTRAN utasításának megfelelõ elemet. Ez a DEFINED attribútum. Ennek segítségével ugyanazon a memóriaterületen több változó is elhelyezhetõ. Tehát a az unió típus egy egyszerû formája. A DEFINED attribútummal különbözõ típusú változók között csak abban az esetben szabad újradefiniálást végezni, ha az egyik karakteres, a másik PICTURE típusú. Nem lehet változót rádefiniálni DEFINED attribútumú változóra vagy struktúra egy mezejére. A DEFINED attribútummal összekapcsolt változók egyike sem tartalmazhatja a attribútumokat, s a attribútummal ellátott változóra nem alkalmazható sem a STATIC, sem az INITIAL attribútum.

A pointerváltozók értékei változók (memóriaterületek) címei lehetnek, s a pointerváltozók segítségével hivatkozhatunk az ezeken a területeken levõ értékekre. Pointer típusú változókra csak az = és = mûveletek, az értékadás és a hivatkozás (-> ) megengedettek. A NULL érték az a pointerérték, ami azt jelzi, hogy a pointer nem mutat objektumra. Pointerek vagy a már említett ALLOCATE utasítással, vagy pedig az ADDR függvénnyel (ami megadja az argumentumában megadott változó címét) kaphatnak értéket.

DCL 1 X, 2 X1 CHAR(2), 2 X2 FIXED BIN; P = ADDR(X);} { ...} P->X.X2 = 0;


Az AREA attribútummal ellátott változókat területkijelölõ változóknak hívjuk.

DCL A1 AREA(600), A2 AREA(*) CONTROLLED, A3 AREA(N), A4 AREA;

A méret a terület méretét jelenti byte-ban kifejezve (a méret a deklarációban elhagyható, ekkor a feltételezett érték 1000 byte).
Egy ilyen területen BASED változók allokálhatók, amelyekre a hivatkozás pointer segítségével történik.

A BASED attribútummal ellátott változók allokálására a deklarációs rész kiértékelésekor nem kerül sor, ezekhez a változókhoz - a CONTROLLED változókhoz hasonlóan - az ALLOCATE utasítással kell memóriaterületet igényelni, s a felszabadítás is külön utasítással, a FREE utasítással történik meg. A BASED változók abban különböznek a CONTROLLED változóktól, hogy a CONTROLLED változókra közvetlenül a nevükkel, a BASED változókra pointer segítségével, indirekt módon hivatkozhatunk; ezen felül a BASED változókat több példányban is allokálni lehet, s az egyes példányok azonosítója (címe) más-más pointer típusú változónak adható értékül. Emiatt a BASED attribútumú változók alkalmasak a dinamikus szerkezetek, pl. listák megvalósítására.