Sunteți pe pagina 1din 145

Zsongor F.

GOBESZ

Ciprian BACOIU

INIIERE N PROGRAMARE I N LIMBAJUL FORTRAN

INIIERE N
PROGRAMARE I
N LIMBAJUL FORTRAN

U.T.PRES

Zsongor F. GOBESZ

Ciprian BACOIU

INIIERE N
PROGRAMARE I
N LIMBAJUL FORTRAN

Editura U.T. PRES


Cluj-Napoca, 2003

PREFA
Aceast carte se adreseaz n primul rnd studenilor Colegiilor de Construcii i Instalaii
din cadrul Universitii Tehnice din Cluj-Napoca. Ea poate fi util ns n egal msur
tuturor celor care doresc s se iniieze n limbajul de programare Fortran.
Coninutul crii a fost selectat judicios, astfel nct pe lng caracterul didactic specific s
prezinte i un pronunat caracter practic aplicativ i s nu necesite cunotine iniiale
speciale din partea cititorului, n domeniul utilizrii calculatoarelor personale. La elaborarea
lucrrii s-a avut n vedere accesibilitatea unor instrumente informatice cu licen gratuit i
perspectiva utilizrii limbajului Fortran la rezolvarea problemelor tehnico-tiinifice din
domenii diverse. Exemplele sunt numeroase i sugestive, din cele mai diferite domenii, n
general simple, spre a fi accesibile studenilor din anii mici de studiu i vizeaz, pe lng
fixarea i adncirea treptat a cunotinelor necesare programrii, formarea unei gndiri
analitice, de alegere i formulare adecvat a algoritmilor de calcul. Spre deosebire de alte
lucrri similare, s-a urmrit ca n cadrul acestui volum s fie prezentate unitar majoritatea
aspectelor principale legate de realizarea programelor n limbajul Fortran. Prezentarea
teoretic succint mpreun cu exemplele tratate ajut dup prerea noastr la fixarea
temeinic a cunotinelor i fac ca aceast carte s fie util i acelora care prin autoinstruire
doresc s se iniieze n programarea calculatoarelor.
Cele 6 capitole ale crii trateaz urmtoarele aspecte:
n capitolul 1 cititorul este iniiat n evoluia sistemelor automate de calcul, a nivelelor de
comunicare om-calculator.
Capitolul 2 este consacrat prezentrii rolului i modului de alctuire a algoritmilor precum
i a ctorva dintre instrumentele utilizate pentru descrierea acestora.
n capitolul 3 se prezint sintaxa i semantica limbajului Fortran 77 ntr-o form sintetic,
considerat util pentru realizarea aplicaiilor de tip consol.
Capitolul 4 trateaz diferenele specifice ale limbajului Fortran 90 fa de Fortran 77,
punctnd facilitile i avantajele aprute prin evoluia limbajului, ns fr pretenia de a
constitui o referin complet. Multe dintre aceste noi caracteristici sunt ilustrate prin
exemple simple i sugestive, din considerente practice.
Capitolul 5 este destinat prezentrii sumare a compilatorului GNU Fortran 77 (g77), cel
mai cunoscut i mai accesibil compilator la ora actual.
Capitolul 6 conine exerciii (exemple complete i comentate) de dificulti gradate.
Soluiile propuse au fost testate cu ajutorul compilatorului g77, din acest motiv conin i
cteva faciliti noi ntlnite n Fortran 90 i acceptate de acest compilator.
n ncheiere, dorim s mulumim att membrilor de familie ct i prietenilor, colegilor de la
Facultatea de Construcii care ne-au susinut i sprijinit n elaborarea acestei lucrri.
Aprilie 2003,
Cluj-Napoca

Autorii

CUPRINS
CAPITOLUL 1: INTRODUCERE
1.1
NOIUNI DESPRE CALCULATOARE I PRELUCRAREA
DATELOR
1.2
EVOLUIA LIMBAJELOR DE PROGRAMARE
1.3
NOIUNI REFERITOARE LA REPREZENTAREA DATELOR
1.4
NOIUNI REFERITOARE LA PROGRAME

11
14
16

CAPITOLUL 2: ALGORITMI
2.1
NOIUNI DESPRE ALGORITMI
2.2
TEHNICI I INSTRUMENTE DE REPREZENTARE
2.2.1
Limbajul natural structurat
2.2.2
Pseudocodul
2.2.3
Tabele de decizie
2.2.4
Arbori de decizie
2.2.5
Scheme logice
2.2.6
Diagrame de structur (de tip Jackson)
2.2.7
Alte instrumente
2.2.8
Structurile de control primitive (de tip Dijkstra)

21
22
22
24
24
26
26
29
30
31

CAPITOLUL 3: FORTRAN 77
3.1
SCRIEREA PROGRAMELOR N LIMBAJUL FORTRAN
3.2
EXPRESII N FORTRAN
3.3
INSTRUCIUNILE LIMBAJULUI DE PROGRAMARE FORTRAN 77
3.4
DESCRIPTORII DE INTRARE/IEIRE
3.5
FUNCIILE INTRINSECI DIN FORTRAN 77

33
34
38
64
66

CAPITOLUL 4: FORTRAN 90
4.1
TRECEREA DE LA FORTRAN 77 LA FORTRAN 90
4.1.1
Compilatoare
4.1.2
Diferene formale
4.1.3
Specificri noi
4.2
STRUCTURI DE CONTROL NOI, INTRODUSE N FORTRAN 90
4.3
TABLOURI DE DATE
4.4
ALOCAREA DINAMIC A MEMORIEI
4.5
MODULE I INTERFEE
4.6
PROCEDURI N FORTRAN 90
4.7
STRUCTURI DE DATE, TIPURI DERIVATE
4.8
INTRRI I IEIRI
4.9
TRATAREA IRURILOR DE CARACTERE
4.10 POINTERI
4.11 ALTE ASPECTE
4.11.1 Funcii intrinseci i faciliti noi
4.11.2 Subprograme predefinite
4.11.3 Aspecte legate de evoluia limbajului

71
72
73
73
75
77
80
82
85
86
89
92
93
95
96
97
97

CAPITOLUL 5: G77
5.1
COMPILATORUL GNU FORTRAN 77
5.2
COMPILAREA CU G77
5.3
BIBLIOTECI PENTRU G77

99
100
102

CAPITOLUL 6: EXERCIII
6.1
EXERCIII ELEMENTARE INTRODUCTIVE
6.2
EXERCIII CU EXPRESII ARITMETICE
6.3
EXERCIII CU TABLOURI DE DATE
6.4
EXERCIII CU SUBPROGRAME
6.5
EXERCIII CU INTRRI/IEIRI FOLOSIND FIIERE
6.6
EXERCIII DIVERSE
6.7
ANEXE

103
107
110
124
130
135
137

BIBLIOGRAFIE

143

CAPITOLUL 1: INTRODUCERE
1.1

NOIUNI DESPRE CALCULATOARE I PRELUCRAREA DATELOR

Oamenii au fost fascinai probabil dintotdeauna de capacitatea de lucru a mainilor. Este


evident c din aceast cauz exist o dorin profund pentru crearea acestora. Dac privim
napoi n istoria tehnicii, de la mecanismele vechi (cum ar fi scripetele, cntarul etc.) pn
la sistemele cele mai noi (cum ar fi digitizoarele, echipamentele de comunicaii etc.)
ntotdeauna au existat ncercri pentru copierea i reproducerea unor soluii naturale prin
mijloace artificiale. Un farmec aparte caracterizeaz tentativele de imitare ale unor
capaciti umane sau realizarea unor instrumente pentru extinderea acestor capaciti (de
exemplu celebrul i misteriosul juctor automat de ah, realizat de Kempelen). Versiunile
moderne ale acestora se refer la roboi, androizi i alte caracteristici tiinifico-fantastice
(de la Frankenstein la Star Trek). n planul tiinelor teoretice, filozofii din Grecia antic au
propus deja crearea unor mecanisme formale bazate pe logic. Cteva variante, realizate n
cursul timpului, au la baz construcia unor modele de raionare mecanizat. Un exemplu n
acest sens ar putea fi maina construit de Ramon Lull din Spania, pentru demonstrarea
existenei lui Dumnezeu. Lull a folosit caractere ca simboluri pentru reprezentarea
cuvintelor (i a argumentelor), precum i combinaii ale acestora pe baza unui sistem de
reguli. Dup cum reiese din descrieri, la baza acestui sistem a stat o schem mecanic prin
care era posibil realizarea unei varieti de figuri geometrice care, dac erau micate unele
fa de altele, determinau noi argumente logice. Sistemul conceput de Lull a fost limitat de
stadiul de dezvoltare al geometriei tridimensionale prin numrul operaiilor geometrice
posibile. Asemenea invenii rmneau de multe ori secrete sau ajungeau s fie privite ca
nite jucrii interesante.
O main ce poate manipula simboluri este i calculatorul. Principala virtute a acestuia este
viteza de operare (numrul ridicat de operaii realizate ntr-un interval scurt de timp).
Utilizarea eficient a acestor echipamente este posibil prin programarea lor, transpunnd
astfel gndirea omului n aceste maini. Folosirea sistemelor de calcul s-a extins astfel de la
aplicaiile contabile, financiar-bancare, pn la aplicaiile inginereti, de la recunoaterea i
sinteza sunetelor pn la modelarea virtual. Electronica i informatica, tehnicile de calcul
i automatizrile, sistemele de comunicaii sunt domenii care fac parte din viaa noastr
cotidian. Mai mult chiar, dezvoltarea acestor domenii a devenit o necesitate pentru modul
n care se msoar azi progresul societii umane. La actualul grad de dezvoltare al tiinei
i tehnicii volumul informaiilor a crescut foarte mult i continu s creasc n ritm
accelerat. Cantitatea de informaii ce intervine n caracterizarea unui fenomen depinde pe
de o parte de complexitatea acestuia, iar pe de alt parte de profunzimea cu care el trebuie
cunoscut. n marea lor majoritate fenomenele sunt complexe i se urmrete descrierea lor
ct mai exact. Pentru a putea manevra informaiile, acestea trebuie modelate. Informaia
este constituit prin juxtapunerea de simboluri grupate convenional pentru a reprezenta
evenimente, obiecte, idei i relaii ntre aceste diverse elemente. Modelul manevrabil al
informaiilor considerate elementare poart denumirea generic de date. Conform celor
enunate mai sus, este necesar deci s se prelucreze un volum mare de date.

-7-

Pentru unele procese apar n plus condiii legate de precizia calculelor. Ca atare, de cele mai
multe ori trebuie s se lucreze cu multe cifre semnificative, volumul calculelor crescnd
astfel. De asemenea, timpul afectat rezolvrii problemelor, orict de complexe ar fi acestea,
este limitat. Toate acestea atest utilitatea folosirii calculatoarelor care concomitent cu
viteza mare de calcul pot asigura i precizii de calcul care satisfac exigenele, oferind o
productivitate mrit. Totodat ele preiau o nsemnat parte din eforturile intelectuale
necesitate de efectuarea calculelor, ceea ce permite concentrarea acestor eforturi asupra
muncii de creaie. Paradoxal ns, prin volumul mare de calcule crete i efortul necesar
stpnirii problemelor abordate i rezolvate, prin interpretarea corespunztoare a volumului
crescut de rezultate. Deci n prezent, direct sau indirect, mijloacele moderne de calcul
contribuie din plin la orice realizare a tiinei i tehnicii, n tot mai multe sectoare de
activitate devenind nerentabil izolarea de calculator.
Cele de mai sus constituie o explicaie a avntului extraordinar pe care informatica l-a
nregistrat n ultimele decenii. Prin informatic (neologism creat n 1962 prin alturarea i
juxtapunerea parial a cuvintelor informaie i automatic) se nelege n general tehnica
prelucrrii automate i raionale a informaiei, suportul cunotinelor i al modului de
comunicare uman. Avnd n vedere cantitatea i complexitatea informaiilor, putem afirma
c mnemonica informatica acoper o arie larg a tehnicilor i metodologiilor legate de
punerea n funciune a dispozitivelor complexe reprezentate de calculatoare i sisteme
informatice. Informatica se ocup att de natura informaiei (care-i servete drept materie
prim) ct i de metodele care permit tratarea i prelucrarea lor, precum i de mijloacele
care pot fi puse n funciune pentru efectuarea concret a acestei prelucrri. Domeniile de
aplicare ale informaticii se regsesc n toate sferele de activitate ale lumii contemporane.
La culegerea i prelucrarea automat a datelor, un rol deosebit este jucat de erorile ntlnite.
Chiar dac acestea nu pot fi eliminate n totalitate, recunoaterea, stpnirea i limitarea
acestora are un rol important din perspectiva rezultatelor urmrite. Exist trei categorii de
erori ce nu pot fi eliminate, din acest motiv necesit o atenie deosebit pe parcursul tratrii
datelor:
1.

Erorile inerente care in de instrumentele de msur utilizate la achiziionarea datelor.


Aceste instrumente dispun de anumite caracteristici legate de natura, alctuirea i
funcionarea lor. Indiferent dac este vorba de un liniar simplu sau de un instrument
optic de mare precizie, va exista o eroare la citirea datelor msurate, din cauza grosimii
fizice a gradaiilor i ale reperelor utilizate.

2.

Erorile de metod se datoreaz modului de selectare a algoritmilor i procedeelor de


prelucrare. Pentru aceeai problem se pot alege mai multe abordri, mai multe metode
de rezolvare. Unele dintre aceste metode pot fi mai exacte dect altele, ns aplicarea
unor metode indirecte va conduce inevitabil la considerarea unor tolerane n funcie de
raportul de rentabilitatate generat de costuri i rezultate.

3.

Erorile de calcul se nasc din modul de reprezentare valoric a datelor i rezultatelor.


Spaiul fizic utilizat ca memorie pentru reprezentarea valorilor numerice fiind limitat,
vor apare inevitabil trunchieri i rotunjiri.

-8-

Din punctul de vedere al clasificrii calculatoarelor putem vorbi de trei clase mari:
1.

Calculatoarele numerice (cifrice sau digitale) prelucreaz cantiti sau mrimi discrete
reprezentate prin valori cu un numr finit de cifre de reprezentare semnificative.
Avantajele principale ale acestor calculatoare constau n universalitatea utilizrii,
precizia ridicat a soluiilor i adaptabilitatea structurii graie modulrii (n funcie de
complexitatea problemei de rezolvat). Calculatoarele personale fac parte din aceast
categorie.

2.

Calculatoarele analogice opereaz cu mrimi ce pot varia continuu. Aceste


calculatoare au un domeniu mai limitat de aplicare (din motive tehnologice) i se
folosesc mai ales la rezolvarea unor probleme fizice, care din punct de vedere
matematic se pot modela prin sisteme de ecuaii difereniale. Precizia soluiilor
furnizate de aceste echipamente este limitat de precizia cu care funcioneaz diferitele
componente ale calculatorului. Avnd n vedere c multe probleme ale mecanicii
construciilor se pot modela matematic prin sisteme de ecuaii liniare (sau difereniale),
au fost realizate n diferite ri i calculatoare specializate pentru rezolvarea unor
asemenea probleme, dar avnd un domeniu restrns de aplicare nu au putut concura
calculatoarele numerice universale.

3.

Calculatoarele electronice mixte (hibride) rezult de fapt din asocierea celor dou clase
precedente cumulnd avantajele lor.

n cele ce urmeaz ne vom referi doar la calculatoarele numerice (nespecializate). Apariia


i dezvoltarea calculatoarelor electronice este de un dinamism de-a dreptul exploziv. Pentru
a marca din punct de vedere constructiv progresele nregistrate n aceast ramur a tiinei
i tehnicii, perioada scurs din anul 1946 (cnd a aprut ENIAC, primul calculator
electronic) i pn n prezent, a fost mprit n etape, fiecare reprezentnd o generaie de
calculatoare.
Calculatoarele din prima generaie (19461953) aveau urmtoarele caracteristici
principale:
utilizau tuburi electronice;
aveau numai memorie intern cu o capacitate redus;
pentru introducerea datelor i extragerea rezultatelor utilizau de regul band
perforat;
efectuau un numr de cteva sute pn la cteva mii de operaii elementare pe
secund;
scrierea programelor se fcea numai n cod main (sau prin conectic), totui
conceptele de asamblor i subprogram sunt deja folosite;
sigurana n funcionare era redus (a se vedea i originea termenului debugging:
depanare prin eliminarea insectelor atrase de lumina tuburilor electronice
noiunea a fost consacrat prin nsemnrile de ntreinere ale calculatorului Mark
I de la universitatea Harvard).

-9-

Dup 1953 apar calculatoarele din generaia a doua, cu urmtoarele caracteristici:


tuburile electronice sunt nlocuite cu tranzistori i se folosesc circuite imprimate;
n afara memoriei interne (mai extinse dect la generaia precedent) apare i
memoria extern (banda magnetic);
viteza de operare crete (sute de mii de operaii elementare pe secund);
elementele periferice se dezvolt foarte mult (pentru introducerea informaiei se
utilizeaz cartele perforate dar i benzi magnetice, la extragerea rezultatelor se
folosesc imprimante rapide),
apar limbajele de programare de nivel ridicat, asociate noiunii de macroasamblor;
apar noiunile de hardware (ansamblul fizic al circuitelor logice ale
calculatorului) i software (ansamblul programelor de deservire i operare livrate
odat cu calculatorul).
Calculatoarele din generaia a treia apar dup 1964 cnd firma IBM (International Business
Machines) lanseaz calculatoarele din seria 360. Ele utilizeaz circuite miniaturizate, au
memorii perfecionate, rapide, partea de software mbogindu-se foarte mult. Limbajele de
programare se profileaz pe tipuri de probleme, apare noiunea de programare structurat.
La calculatoarele din generaia a treia:
apar concepii noi n exploatare ca: multitasking (executarea simultan
ntreesut a mai multor programe), regimul time-sharing (utilizarea aceluiai
calculator de ctre mai muli beneficiari simultan, prin acordarea de trane de
timp succesive fiecruia, astfel nct un beneficiar s nu blocheze n exclusivitate
calculatorul);
ncep s fie folosite circuitele integrate (cu 310 circuite active/modul);
apar sisteme elaborate pentru gestiunea fiierelor.
ncepnd cu anul 1968 se vorbete deja de generaia a patra de calculatoare. Se
consemneaz perfecionri tehnologice nsemnate n construcia memoriilor interne i
externe, precum i n evoluia perifericelor. Aceste calculatoare utilizeaz circuite integrate
cu un grad ridicat de integrare, cunoscute sub denumirea generic de chip-uri sau
microchip-uri, numrul circuitelor active pe modul fiind foarte ridicat. Paii fcui ctre
circuitele VLSI (Very Large Scale Integration) au asigurat capacitatea de prelucrare
necesar construirii calculatoarelor personale, care reprezint o parte din calculatoarele din
a patra generaie. Aceste aparate sunt de dimensiuni reduse, fiind eficiente i ieftine.
Deoarece nu necesit condiii ambientale speciale, ele pot fi amplasate pe un birou, n
locuine sau la diverse puncte de lucru, de exemplu n instituii, n magazine, la ieirea din
supermarket (n ghieul de cas), n hale de producie, pe antiere etc. Paralel cu
dezvoltarea aparatelor de dimensiune redus a crescut numrul programelor i aplicaiilor
de utilizare ce se pot rula pe asemenea calculatoare. Printre acestea se gsesc jocuri,
editoare de texte, tabele de calcul, pachete pentru gestionarea bazelor de date, programe
grafice, programe de comunicare etc. Aceste calculatoare nu mai sunt cumprate,
programate i controlate doar de ctre specialiti i administratori de sisteme. Ele se afl
deja, n sensul adevrat, la ndemna utilizatorilor.
- 10 -

De la mijlocul anilor 1980 se poate vorbi i de calculatoare din generaia a cincea, un


concept revoluionar introdus de fapt de ctre japonezi, concept ce prevedea realizarea unor
echipamente de calcul prin regndirea ndrznea a tehnologiilor i arhitecturilor existente.
Elaborarea acestui concept a fost posibil datorit dezvoltrii tehnologice coroborate cu
rezultatele cercetrilor n domeniul inteligenei artificale. Pn n prezent ns, raiunile
economice, dirijate i de cerinele pieei, precum i valoarea investiiilor existente deja n
domeniul produciei de componente i de calculatoare au frnat i au deturnat oarecum
generalizarea pe aceast direcie de dezvoltare.
Calculatoarele timpurii nu erau prea performante, posibilitile lor de aplicabilitate erau
destul de restrnse, dar s-au ntmplat dou lucruri. n primul rnd calculatoarele personale
au devenit din ce n ce mai eficiente, au devenit adecvate pentru rularea unor limbaje de
programare cu apetit mare de memorie. Utilizarea discurilor cu suprafee magnetice pe post
de memorie a realizat accesul aparent instantaneu la cantiti foarte mari de date. Pe de alt
parte, calculatoarele personale pot fi conectate n reele, realiznd astfel posibilitatea
conversrii nemijlocite ntre oameni de afaceri, proiectani etc., respectiv posibilitatea
comunicrii cu un calculator central care poate oferi resurse extinse.
Evoluia tehnologic a determinat deci schimbri importante n poziia i rolul
calculatoarelor n cadrul organizaiilor. La nceput ele erau centralizate n mare msur i
erau folosite pentru rezolvarea unui numr restrns de probleme (de exemplu pentru
realizarea evidenelor de salarizare). Dezvoltarea tehnologiei s-a materializat n calculatoare
cu dimensiuni reduse, ieftine, performante, care puteau fi amplasate pe birouri. Conform
unei analize efectuate n anul 1992 s-a demonstrat c dac automobilele RollsRoyce s-ar fi
dezvoltat n aceeai msur ca i calculatoarele, atunci ele ar fi consumat doar 3 litri de
combustibil pentru a parcurge 1000 de km cu o vitez normal de 800 km/h, preul lor ar
fi cobort sub 5 lire sterline, iar dup gabaritul atins ar fi ncput ntr-o cutie de chibrituri.
Nu se tie ns, cine ar fi avut nevoie de asemenea automobile
1.2

EVOLUIA LIMBAJELOR DE PROGRAMARE

S-a artat c la nceput, la calculatoarele din prima generaie, s-a utilizat programarea
numeric n cod main (binar) ceea ce reprezenta o operaie greoaie, necesitnd cunotine
asupra particularitilor echipamentelor, antrennd i o probabilitate considerabil de a
introduce erori n program. Pentru a scpa de inconvenientele acestei metode au fost
elaborate limbaje simbolice simple. Acestea conineau de fapt o serie de mnemonice
derivate din limba englez, de genul ADD (adun), MUL (nmulete) etc., alctuind un
limbaj asamblor legat de main i necesitnd traducerea n cod main. Prin introducerea
macro-instruciunilor au aprut limbajele simbolice evoluate. O macro-instruciune
corespundea la mai mult dect o operaie cunoscut (executat) de calculator, fiind nlocuit
n momentul traducerii cu seria de instruciuni main corespunztoare. Timpul alocat
scrierii programelor i implicit i riscul de a grei s-a redus astfel considerabil. Programul
traductor al acestor limbaje se numea autocodificator. Limbajele asamblor cu autocodificator au coexistat n perioada 19581964, dar s-au folosit i ulterior la programarea
- 11 -

calculatoarelor din generaia a treia cu meninerea denumirii unificate de limbaj asamblor


(sau limbaj macroasamblor).
Un salt calitativ n domeniul limbajelor de programare l constituia apariia limbajelor
algoritmice (sau limbaje procedurale) nelegate de calculator. De fapt independena nu era
total, fiind necesare mici corecturi, adaptri, funcie de particularitile calculatoarelor
utilizate, aceste modificri nefiind ns eseniale ca volum. Ca orice limbaj, i cele
algoritmice (procedurale) se caracterizeaz printr-un vocabular i prin reguli de sintax.
Vocabularul este alctuit dintr-un ansamblu de cuvinte cheie (preluate i adaptate de regul
din limba englez), iar numele variabilelor sunt date de programator (respectnd anumite
reguli). Limbajele algoritmice permit scrierea algoritmilor dup care urmeaz s fie
soluionat problema abordat, sub form de instruciuni (fraze cu un coninut semantic
bine precizat). Prin semantica limbajului se nelege ansamblul regulilor de coresponden
sau de interpretare corespunztoare cuvintelor cheie, respectiv grupelor (blocurilor) de
cuvinte cheie. Frazele limbajului (rndurile de instruciune) vor fi alctuite deci din
combinaii de cuvinte cheie i nume de variabile, dup anumite reguli. Sintaxa limbajului
stabilete combinaiile posibile de cuvinte cheie, nume de variabile precum i folosirea
punctuaiei.
Primul limbaj algoritmic de nivel nalt este considerat FORTRAN (denumirea provine de la
FORmula TRANslation system) aprut n 1954, ns merit s amintim i alte limbaje
consacrate de acest gen, cum ar fi COBOL (Common Business Oriented Language aprut
n 1959 ca urmare a dezvoltrii limbajelor B-O din 1957 i Flow-Matic din 1958, prima
standardizare fiind cea din 1961, derivat din CODASYL Conference on Data Systems
Language, 1959); ALGOL (ALGorithmic Language 1958, aprut pe baza limbajului
Fortran prin combinarea limbajelor JOVIAL, NELIAC, BALGOL i MAD) fiind limbajul
din care au fost dezvoltate ulterior limbajele CPL (predecesorul din 1963 al limbajului C
care a aprut n 1971), PL/I (1964), Simula (1964) Pascal (1970) etc.; sau BASIC
(Beginners All-purpose Symbolic Instruction Code 1964).
Paralel cu dezvoltarea limbajelor procedurale au aprut i primele limbaje funcionale de
programare. Structura acestora este oarecum detaat de noiunea convenional de algoritm
(n sensul utilizat la limbajele algoritmice), ea fiind ns mai apropiat modului uman de
gndire. Ca i reprezentare consacrat pentru aceast categorie trebuie s amintim limbajele
LISP (LISt Processing aprut n 1958) i PROLOG (PROgramming in LOGic aprut n
1970), existnd foarte multe variante ale acestora, pe lng alte limbaje funcionale noi.
Dei aceste limbaje sunt asociate n general cu cercetrile din domeniul inteligenei
artificiale, ele au aplicabilitate i n domeniul ingineriei.
Avnd n vedere c n rezolvarea unor categorii de probleme specifice anumitor domenii de
activitate se ntmpinau dificulti chiar utiliznd limbaje algoritmice avansate, orientate pe
sisteme, dificultile aprnd fie la introducerea datelor fie din folosirea unor cuvinte cheie
diferite de limbajul tehnic consacrat n domeniul respectiv, au fost dezvoltate limbaje (i
compilatoare) orientate pe problem. Astfel, n domeniul mecanicii construciilor pentru
- 12 -

determinarea eforturilor n structurile alctuite din bare s-a elaborat n S.U.A. limbajul
STRESS (STRuctural Engineering System Solver 1963), care s-a bucurat de o rspndire
larg, iar n 1966 a fost elaborat ICES (Integrated Civil Enginnering Systems), un sistem
integrat de rezolvare a problemelor de construcii care coninea urmtoarele limbaje
orientate pe probleme:
COGO (Coordinate GeOmetry) pentru rezolvarea problemelor geometrice,
STRUDL (STRUctural Design Language) pentru analiza i proiectarea
structurilor,
PROJECT (PROJect Evaluation and Coordination Techniques) pentru
problemele schirii, reele, drum critic etc.,
SEPOL (SEttlement Problem Oriented Language) pentru calcule de tasri n
mecanica solului,
ROADS (Roadway Analysis and Design System) pentru amplasarea, alinierea
drumurilor, rurilor etc.,
BRIDGE pentru analiza i proiectarea podurilor,
TRANSET (TRANSportation Evaluation Techniques) pentru analiza reelelor,
fluxurilor de transport.
Limbaje similare orientate pe probleme au mai fost elaborate i n alte ri. Preocupri n
aceast direcie i realizri remarcabile s-au obinut i la noi n ar. Amintind doar cteva
exemple specifice din domeniul analizei structurale: n cadrul C.O.C.C. Bucureti a fost
elaborat limbajul SISBAR (autor L. Dogaru) pentru analiza general a structurilor alctuite
din bare, iar n cadrul Universitii Tehnice din Cluj-Napoca a fost dezvoltat limbajul
SICAM (Sistem Interpretativ de Calcul Automat Matriceal, autor F. Gobesz) pentru analiza
structurilor n formularea matriceal.
Un salt calitativ considerabil n domeniul dezvoltrii limbajelor procedurale a reprezentat
apariia noiunii de orientare pe obiecte. Astfel, pe lng apariia unor limbaje noi, au fost
dezvoltate variante corespunztoare i n cadrul limbajelor existente i consacrate (Fortran
90, OO Cobol, C++, Borland Pascal etc.). Prin tendinele de detaare fa de varietatea
sistemelor de operare au aprut limbajele interpretate i script-urile (acestea nenecesitnd
compilatoare n sensul cunoscut, fiind convertite n cod main doar n momentul executrii
programului cu ajutorul unui sistem de interpretare specific sistemului de operare). Dintre
aceste limbaje merit s amintim Java (aprut n 1995 din limbajul Oak care s-a nscut n
1991 din limbajele Cedar, Objective-C, C++ i SmallTalk-80) respectiv JavaScript (aprut
n 1995 din LiveScript care la rndul lui a derivat din Cmm, acesta din urm dezvoltndu-se
din limbajul ISO C cunoscut i ca C90 respectiv din C++).
n cele ce urmeaz vom sintetiza istoria limbajului Fortran, avnd n vedere orientarea
acestei lucrri. Limbajul a aprut n noiembrie 1954, dezvoltarea lui fiind iniiat de ctre o
echip remarcabil de programatori de la IBM (sub conducerea lui John Backus). Din anul
1957 se poate vorbi de limbajul i compilatorul Fortran I, destinate iniial calculatorului
IBM 704. Fiind primul limbaj algoritmic aprut, oferind o serie de avantaje fa de limbajul
de asamblare, a fost adoptat foarte repede de comunitile tiinifice din toate domeniile.

- 13 -

Acest succes a concurat la dezvoltarea fireasc a limbajului, aprnd variante ca Fortran II


n 1957, Fortran III n 1958, Fortran IV n 1962 precum i convertoare pentru a menine
compatibilitatea cu programele scrise n versiunile anterioare. n luna mai a anului 1962 a
devenit primul limbaj de nivel nalt standardizat oficial, iar n 1966 a fost adoptat primul
standard ANSI (American National Standards Institute) referitor la Fortran IV (acesta
primind denumirea oficial de Fortran 66 ANS). Aceast versiune a fost urmat de Fortran
V, respectiv de alte tentative de dezvoltare.
Pn la mijlocul anilor 1970 aproape toate calculatoarele mici i mari dispuneau de
compilatoare pentru Fortran 66, acesta fiind limbajul de programare cel mai rspndit. Cu
trecerea timpului i cu dezvoltarea limbajului, definiia standardizat a fost actualizat n
1978 (ANSI X3.9), ea fiind adoptat i de ISO (International Standardization Organization) n 1980 ca norm internaional, aprnd astfel versiunea cea mai cunoscut a
limbajului, sub denumirea Fortran 77. Caracterul relativ conservator al acestui standard a
lsat limbajului un numr de faciliti ce preau din ce n ce mai depite de ctre noile
limbaje de programare aprute (unele derivate n parte chiar din Fortran), aa c n mod
firesc din anii 1980 s-a trecut la dezvoltarea acestuia (sub numele Fortran 8x). Dei limbaje
ca Algol, Basic, Pascal i Ada erau mai uor de nvat i de utilizat, ele nu se puteau
compara cu eficiena dovedit de Fortran n ceea ce privea viteza de calcul i compactitatea
codului generat.
A treia standardizare a limbajului Fortran s-a produs abia n 1991, versiunea limbajului
primind numele Fortran 90. Aceast ntrziere a dus la accentuarea competiiei n privina
popularitii limbajelor de programare, avnd efecte negative asupra limbajului Fortran.
Chiar adepi convini ai acestui limbaj au migrat ctre limbaje ca C sau C++, n ciuda lipsei
de performane n calcule ale acestora. Prin includerea complet a versiunii anterioare
(Fortran 77) alturi de noutile introduse, oferind flexibilitate i performane remarcabile,
noua versiune a limbajului Fortran a reuit s se impun n rndul programatorilor,
permind realizarea programelor n moduri adecvate mediilor moderne. Prin extinderea
limbajului n direcia procesrii paralele s-a standardizat HPF (High Performance Fortran)
n 1993. n anul 1996 s-a dat publicitii a patra standardizare a limbajului Fortran, acesta
primind numele Fortran 95, la care s-au adugat nc dou rapoarte tehnice elaborate sub
egida ISO. Ultima versiune a limbajului este cea din anul 2000, purtnd numele sugestiv
Fortran 2000.
1.3

NOIUNI REFERITOARE LA REPREZENTAREA DATELOR

Aa cum s-a menionat n primul capitol, datele reprezint modele manevrabile ale
informaiilor. Calculatoarele personale stocheaz aceste date pe medii magnetice i optice,
utiliznd structuri logice arborescente. Pentru a ne face o idee despre aceste structuri,
trebuie s lmurim cteva noiuni fundamentale.
Din motive tehnologice calculatoarele folosesc un set limitat de valori pentru reprezentarea
datelor. Unitatea elementar de memorie utilizat pentru date se numete bit. Aa cum un
- 14 -

magnet poate dispune de doi poli, un circuit electric poate avea curent sau nu, starea unui
bit poate fi notat cu dou valori distincte: 0 sau 1. Deoarece cele dou valori ofer o plaj
foarte limitat, aceste entiti elementare sunt grupate n octei (bytes), doi octei formnd o
entitate adresabil ce poart denumirea de cuvnt. Manevrarea teoretic a valorilor binare
fiind greoaie i consumatoare, se utilizeaz reprezentarea n cifre hexadecimale a acestora,
derivat din expresiile greceti hexa (6) i deca (10) care compuse, marcheaz numrul
aisprezece (16).
Tabel comparativ cu reprezentarea unor valori n sisteme de numrare diferite:
Decimal
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F
Binar (pe 4 bii) 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
Privind tabelul de mai sus se poate observa uor faptul c pe un octet (pe opt bii) pot fi
reprezentate n sistemul binar dou cifre din sistemul hexadecimal, deci gruparea biilor n
octei nu este ntmpltoare. Astfel putem nelege de ce se consider mai comod utilizarea
cifrelor hexadecimale n locul celor decimale pe calculatoare. Cifrele decimale fiind de la 0
la 9, s-ar consuma cte 4 bii pentru reprezentarea uneia, combinaiile binare din plaja
10101111 fiind inaccesibile. Deci, dac am ncerca s reprezentm ntr-un octet (byte)
valorile prin cifre decimale, nu am putea scrie o valoare mai mare de 99, pierznd astfel
plaja valorilor dintre 100 i 255 (ceva mai mult de jumtatea numerelor reprezentabile).
Prin utilizarea sistemului hexadecimal putem reprezenta dou cifre pe un octet, deci patru
cifre pe un cuvnt (FFFF scris n hexa nsemnnd valoarea 65536 n sistemul decimal).
Dac se consider i noiunea de semn, atunci, n maniera anterior discutat, pe doi octei
pot fi reprezentate valorile corespunztoare unei notaii n sistemul decimal de la 65535
pn la +65535 (n acest caz FFFF scris n hexa va nsemna valoarea 1 n sistemul decimal
obinuit).
Pentru a putea manevra eficient datele, ele trebuie s fie grupate i adresabile. n acest sens
vom defini dou noiuni des ntlnite n utilizarea calculatoarelor:
1.

Fiierul este o colecie organizat de date ce se trateaz uniform. (Dup prerea


autorilor, aceasta este cea mai scurt i cea mai pertinent definiie pentru asemenea
colecii, cuprinznd patru caracteristici eseniale: datele sunt coninute n fiiere, sunt
organizate, se pot efectua operaii asupra lor, toate datele dintr-un fiier pot suporta
aceleai operaii.)

2.

Directorul (se utilizeaz i denumirile: folder, dosar) este o colecie de referine


organizate ce se trateaz uniform. Definiia este asemntoare cu cea a fiierelor, totui
exist diferene semnificative pe care le vom exemplifica n cele ce urmeaz.

Dac ne imaginm, pentru exemplificarea definiiilor anterioare, o cmar (pe post de


memorie de stocare) n care depozitm alimente (privite ca i date) i ambalaje, atunci
putem face urmtoarele analogii:
innd, de exemplu, mere ntr-o cutie, putem privi acea cutie ca pe un fiier de mere, iar o
alt cutie n care inem sticle goale, ca un fiier de sticle goale. Evident, att merele ct i
- 15 -

sticlele vor alctui colecii organizate (dupa forma cutiilor, dup legea gravitaiei etc.) care
pot suporta aceeai prelucrri. Chiar daca momentan nu avem mere n cutia respectiv,
cutia va fi tot un fiier de mere atta timp ct nu i se schimb caracteristicile, n acest caz
putnd vorbi despre un fiier gol de mere. Ceea ce este important de observat: cutiile pot
conine la nivel fizic entitile pentru care sunt destinate.
Dac dorim s avem o eviden referitoare la aceste cutii, vom nota ntr-un carneel numele
i poziia lor. Un asemenea carneel va conine astfel doar referine la cutii (la fiiere)
reprezentnd un director (folder sau dosar), fr a conine fizic cutiile (fiierele) respective.
Bineneles, un asemenea carneel poate conine i alte nsemnri, de exemplu referitoare la
alte carneele (n care sunt notate denumirile i poziiile altor cutii). Asemenea referine pot
fi percepute ca i subdirectoare. Prin acest mod de eviden se poate crea o structur
arborescent similar cu cea existent n mediile de stocare ale datelor.
Interfeele utilizator ale sistemelor de operare pot induce neclariti referitoare la aceste
concepte, sugernd prezena fizic a fiierelor n directoare pentru a simplifica operaiile.
De cele mai multe ori, tergnd o nregistrare se va obine de fapt marcarea special a
acesteia (referina devine ascuns iar zona alocat se poate suprascrie) i nu tergerea fizic.
Fiierele pot fi de tipuri diferite, n funcie de coninutul lor. Ele sunt mprite de regul n
dou categorii mari: fiiere cu caractere afiabile i fiiere cu coduri neimprimabile (dac
merele se pot mnca, ncercarea de a consuma sticle goale poate avea urmri imprevizibile).
Fiierele cu coduri neimprimabile pot fi executabile sau nu. n cazul n care ele sunt
executabile, poart numele generic de program sau de comand extern (comenzile interne
sunt cele coninute de programele ncrcate n memoria intern a calculatorului). Un caz
particular este reprezentat de fiierele cu caractere afiabile care sunt executabile (de
regul acestea sunt interpretate). Acestea conin de fapt linii de comenzi ntr-o succesiune
secvenial i poart denumirea generic de fiiere de comand.
1.4

NOIUNI REFERITOARE LA PROGRAME

n capitolul anterior am dat o definie pentru noiunea de program, din punctul de vedere al
fiierelor. Programul poate fi definit i ca mulimea comenzilor (instruciunilor)
selecionate de ctre programator din mulimea de instruciuni puse la dispoziie prin
platforma de calcul. n cele ce urmeaz vom discuta i alte aspecte legate de aceast
noiune.
Se tie foarte bine c dac pentru soluionarea unor probleme dintr-un domeniu limitat
dispunem de o descriere clar i bine definit a procedurii de rezolvare, atunci aceast
munc (n unele cazuri cu pronunat caracter repetitiv) poate fi ncredinat unui sistem
automat de calcul. Cele mai multe programe sunt scrise sub forma unor algoritmi, acestea
coninnd practic lista instruciunilor n ordinea corespunztoare executrii lor de ctre
calculator. De cele mai multe ori un asemenea algoritm utilizeaz i date care sunt
organizate ntr-o anumit form, n fiiere separate, externe. Programul de calculator poate
fi privit astfel i ca un pachet alctuit din date + algoritm.
- 16 -

De exemplu, un program pentru calculul salariilor poate fi descris n felul urmtor: caut
prima persoan din nregistrri, citete salariul brut al persoanei gsite, determin treapta de
impozitare n care se ncadreaz, calculeaz impozitul, caut toate celelalte sczminte
(contribuii la fonduri de asigurri, cotizaii etc.) i determin salariul net. Toate aceste
elemente ajung sub o form prestabilit pe fluturaul de salarizare i pe statul de plat.
Dup prelucrarea datelor primului angajat, sistemul pentru calcularea salariilor continu
determinarea salariilor pentru ceilali angajai, indiferent dac numrul lor este de ordinul
zecilor sau al sutelor. Algoritmul nu se schimb la nici un angajat. Sistemele de acest gen se
bazeaz pe tehnica de calcul timpurie proiectat pentru rezolvarea problemelor numerice
repetitive, complet plictisitoare. Aplicaiile mai recente oglindesc deja i schimbrile
tehnologiei. Rspndirea utilizrii calculatoarelor personale a condus la apariia unor
aplicaii mai mici de salarizare, bazate pe tabele de calcul, care sunt compuse din iruri i
coloane de numere manipulate cu ajutorul sistemului de calcul. Pachetele de programe care
au fost vndute n numrul cel mai mare sunt tabelele de calcul i procesoarele de texte.
Oamenii ns nu folosesc numai cuvinte i cifre, ci manevreaz i o cantitate din ce n ce
mai mare de informaii referitoare la acestea. Acest fapt a condus la apariia i dezvoltarea
bazelor de date. Bazele de date nmagazineaz o cantitate enorm de informaii sub form
structurat, utilizatorul avnd acces la informaia dorit oricnd, n orice form dorit. Un
exemplu foarte bun pentru ilustrarea celor amintite poate fi o baz cu date despre angajaii
din cadrul unei firme. n structura bazei de date fiecrui angajat i corespunde un articol,
acesta coninnd informaiile utile referitoare la angajat, de exemplu: numele, adresa, data
naterii, salariul de ncadrare, locul de munc etc. Utilizatorul poate ntocmi, din
informaiile coninute de ctre baza de date (de regul prin folosirea unui limbaj de
interogare), o situaie pentru analiz despre angajai, ori de cte ori este nevoie. Poate
obine rapoarte de genul: lista angajailor cu salariul peste X lei, cu vechime peste Y ani, sau
domiciliai ntr-o anumit zon. Ceea ce putem obine din baza de date este limitat doar de
ctre informaia nmagazinat i de ctre limbajul de interogare.
Din cele prezentate mai sus se desprinde ideea c un pachet de programe poate avea o
alctuire complex. n aceast carte vom aborda doar realizarea unor aplicaii de tip consol
cu ajutorul limbajului Fortran i al compilatorului g77, fr a discuta despre conceperea i
generarea interfeelor grafice sau despre detaliile i specificitile caacteristice diverselor
sisteme de operare. Etapele de programare sunt n general sintetizate prin 3 faze: concepia
(nivelul logic de rezolvare a problemei cu elaborarea sau alegerea algoritmului
corespunztor), codificarea (transcrierea algoritmului ntr-un limbaj de programare,
accesibil calculatorului), testarea i implementarea (verificarea corectitudinii cu date de test
i punerea la punct a programului). Aceste faze pot fi realizate att ntr-o form empiric
ct i n manier structurat, mai eficient dect prima variant (permind dezvoltarea i
testarea modulat). Prefernd abordarea structurat, n locul celor 3 faze generice amintite
prezentm urmtoarea succesiune de etape, considerate necesare realizrii unui program:

recunoaterea i definirea problemei de abordat;


alegerea i descrierea metodei (algoritmului) de rezolvare;
scrierea sursei programului ntr-un limbaj de programare;
compilarea (traducerea n cod main a) sursei;
- 17 -

realizarea legturilor cu modulele de bibliotec ale mediului de programare;


rularea i testarea programului creat.
De ce sunt necesare asemenea etape de parcurs?
n primul rnd, fr recunoaterea problemei nu avem ce rezolva. Prin definirea problemei
se pot determina datele de intrare necesare i suficiente, precum i rezultatele urmrite a fi
obinute.
Aproape orice problem poate fi abordat i rezolvat pe mai multe ci. Exist o varietate
foarte mare de metode studiate i validate n diferite domenii, din aceast cauz doar rareori
se impune crearea sau inventarea unor metode complet noi. Alegerea unei metode trebuie
s in seama att de caracteristicile problemei, ct i de echipamentele i instrumentele
informatice accesibile programatorului, precum i de generalitatea i aplicabilitatea
soluiilor urmrite. Descrierea pertinent i clar a metodei permite i eliminarea unor erori
pe lng modularizarea procedeelor n vederea eficientizrii programrii. n general
metodele pot fi clasificate n dou categorii: metode directe i metode indirecte. Metodele
directe sunt cele care ne conduc la rezultat ntr-un numr finit de pai. Metode indirecte
sunt considerate cele care ar necesita parcurgerea unui numr infinit (mai corect nedefinit)
de pai pentru a obine un rezultat exact. Dei un numr infinit de pai nu pare o soluie
practic, sunt cazuri n care nu avem la ndemn dect asemenea metode. Ele se aplic prin
alegerea unor tolerane fa de rezultatul urmrit (prin aprecierea convergenei, limitarea
unor abateri etc.) ceea ce conduce la un numr necunoscut de pai, dar finit. Condiionarea
metodelor este un alt concept de care se ine seama la alegere. Sunt considerate bine
condiionate acele metode la care perturbrile mici n datele iniiale nu conduc la alterarea
deranjant a rezultatelor. Metodele n care perturbrile iniiale au ca efect deranjarea
rezultatelor, se consider slab condiionate i au de regul o aplicabilitate mai redus,
necesitnd un control mai strict al validrilor. Experiena i rutina sunt factori importani n
aceast etap.
Limbajul de programare i mediul n care se scrie sursa programului se recomand a fi
alese dup specificul problemei abordate i a metodei de soluionare pentru care s-a optat.
Sursa poate fi compus din mai multe uniti surs de program (uneori denumite module)
care pot fi redactate chiar utiliznd fiiere separate. Ea trebuie s fie conform rigorilor
impuse de limbajul de programare ales i de mediul de dezvoltare folosit (sistemul de
operare, mediul de programare etc.). n limbajul Fortran se poate creea doar un singur
program surs principal care poate fi combinat ns cu diverse subuniti de program
(blocuri de date, subprograme, funcii externe etc.) scrise chiar n fiiere separate.
Deoarece textul rezultat n urma scrierii sursei se materializeaz prin crearea unor fiiere cu
caractere afiabile (imprimabile) ce nu sunt interpretabile de ctre calculator, instruciunile
coninute vor trebui traduse n coduri nelese de main. Acest lucru este realizat prin
compilarea sursei, etap n care se poate face i verificarea sintaxei (verificarea semanticii
ns nu poate fi efectuat de compilator). O asemenea traducere ns nu realizeaz i
transformarea sursei n program (fiier executabil), crend doar imagini obiect ale surselor
- 18 -

(fiiere neexecutabile dar care conin coduri main). Fiierele cu date de intrare nu trebuie
compilate pentru c ele nu conin instruciuni ci doar valori ce vor fi utilizate ca atare,
independente de limbajul de programare utilizat.
Pentru a obine fiiere executabile (programe propriu-zise), trebuie prelucrate legturile
generate n cadrul imaginilor obiect, innd cont i de bibliotecile necesare. Acest lucru se
realizeaz de regul prin procedee automate ale mediului de dezvoltare ales, n urma
opiunilor exprimate de programator. Unele medii de dezvoltare ofer aceast facilitate n
mod transparent, aparent mpreun cu opiunea de compilare. n aceast etap este posibil
i definirea unei structuri prefereniale explicite a programului prin segmentare (stabilirea
succesiunii de ncrcare n memorie i a dependinelor modulelor create).
Rularea i testarea programului realizat, menionate ca etap final, sunt foarte importante
pentru verificarea performanelor obinute i a corectitudinii rezultatelor n diverse ipostaze.
Toate etapele descrise pot i se recomand a fi supuse unor rafinri sau unor abordri
repetitive n scopul depistrii i eliminrii erorilor posibile.
Ca orice proces de proiectare, conceperea i dezvoltarea aplicailor informatice se supune
unor reguli i se poate privi ca un ciclu. Din acest punct de vedere, orice asemenea
activitate presupune parcurgerea nu numai a unor etape fizice, ci i a unora logice, pe
niveluri i n planuri diferite:
Cerine

NIVEL:
LOGIC
FIZIC

PLAN:

MODEL LOGIC
EXISTENT

MODEL LOGIC
NOU

MODEL FIZIC
EXISTENT

MODEL FIZIC
NOU

EXISTENT

NOU

Pentru a putea altera situaia existent, avem nevoie de un model corespunztor. Prin
formularea acestuia putem determina schimbrile necesare. Prima etap va nsemna
delimitarea i msurarea caracteristicilor ntr-un plan fizic, din care prin abstractizare se va
nate un model logic. Intervenind asupra acestuia prin concepia schimbrilor propuse,
considernd i cerinele externe, se va obine un nou model logic, care la rndul su se va
- 19 -

transforma ntr-un model fizic nou. Deci, pornind de la o situaie existent, am ajuns la o
situaie nou. Caracterul ciclic al acestui proces este evident n acest moment, deoarece
situaia nou creat va deveni una existent (din momentul implementrii), care la rndul ei
va fi la un moment dat alterat printr-un proces similar.
Era o vreme cnd programatorii erau considerai artiti, i asta n principal datorit
manierelor personale de lucru. Trecerea i n acest domeniu de la artizanat la industrializare
a constituit o constrngere, derivnd arta scrierii aplicaiilor n tiina programrii. Aceast
transformare urmrea i trecerea de la microeficien la macroeficien n domeniu, ceea ce
a necesitat un compromis ntre resursele necesare (spaiu de memorie, timp de rulare,
costuri de realizare i de ntreinere) i fiabilitate. Toate acestea au condus n mod firesc
ctre modularitatea programelor i ctre principiile structurrii, din 1968 fiind recunoscut
i disciplina ingineriei de soft.
Bazele programrii structurate au fost enunate n 1969 de ctre Dijkstra (prin teorema de
structur), fiind aplicate pentru prima dat n cadrul corporaiei IBM la un proiect pentru
determinarea orbitelor definitive ale sateliilor teretri, cu un rezultat deosebit (n decursul a
6 luni s-a reuit de ctre Mills un superprogramator scrierea i validarea n limbajul
PL/1 a 50 de mii de instruciuni, ceea ce pna atunci reprezenta norma obinuit pentru 30
de oameni de-a lungul unui an).

- 20 -

CAPITOLUL 2: ALGORITMI
2.1

NOIUNI DESPRE ALGORITMI

Un algoritm poate fi definit ca mulimea finit de reguli care indic o succesiune de operaii
pentru rezolvarea n mod mecanic (sau automat) a unui anumit tip de probleme. Principiile
de baz, valabile att la analiza/definirea unei probleme, ct i la celelalte etape de realizare
(prezentate n capitolul precedent) pot fi sintetizate n urmtorul mod:
Concepia la orice nivel prin descompunere toate metodele utilizate n mod
curent respect acest principiu, de exemplu: principiul KISS (Keep It Stupid
Simple) din metoda Yourdon, principiul proiectrii ierarhice din metoda
Constantine, principiul detaliilor din metoda Warnier, principiul primitivelor din
metoda Dijkstra etc.;
Realizarea analizei/concepiei prin descompunere (de sus n jos) combinat cu
recompunerea (de jos n sus) n faza de realizare;
Structura datelor determin structura prelucrrilor (aplicarea metodelor bazate pe
structuri de date);
Aplicarea unui proces iterativ de verificare (revenire, chiar cu rafinare dac se
impune) n toate fazele de elaborare a unui produs informatic.
n general se recomand utilizarea metodelor de programare modular i structurat.
Aceaste metode reprezint o manier de a concepe i codifica programe astfel nct s fie
uor de neles i de modificat. Este nevoie de o anumit experien, dar aceasta se
acumuleaz relativ uor, metoda rezultnd din procesul de organizare al gndirii care duce
la o expresie inteligibil a procesului de calcul ntr-un timp rezonabil, fiind considerat i
arta simplitii sau rentoarcerea la bun-sim. Cele mai importante proprieti ale unui
algoritm sunt considerate urmtoarele:
Definibilitatea

fiecare pas trebuie s fie foarte bine precizat, att ca i


coninut ct i ca poziie.
Realizabilitatea obinerea rezultatului n timp util, cu resurse corespunztoare.
Finitatea
aplicarea algoritmului s ne conduc la rezultat dup un
numr finit de pai.
Generalitatea
algoritmul s se aplice unei ntregi familii (clase) de
probleme i nu doar unui caz izolat (utilizarea variabilelor).
Automatismul s necesite ct mai puine intervenii umane dup lansarea n
execuie.
Elementele caracteristice ale unui algoritm sunt:
datele (informaia vehiculat) date de intrare, de ieire, intermediare;
operaiile operaii de atribuire, de calcul, de decidere, de salt, de citire sau de
scriere, de deschidere sau de nchidere fiiere etc.;
paii descriu regulile algoritmului.
- 21 -

2.2

TEHNICI I INSTRUMENTE DE REPREZENTARE

Specificarea unui proces nseamn elaborarea unei descrieri concise i complete a


transformrii efectuate de acesta. Primul principiu enunat n subcapitolul anterior:
concepia la orice nivel prin descompunere, a condus la elaborarea descrierilor pentru
procesele elementare (numite i primitive funcionale). Aceste descrieri poart denumirea
de minispecificaii, reprezentnd regulile de transformare a elementelor datelor de intrare n
elemente ale datelor de ieire la nivelul procesului elementar. Descrierea algoritmilor
trebuie s respecte aceeai principii pe care le ntlnim la minispecificaii. Ea trebuie s
conin aspectele logice (ceea ce se realizeaz n cadrul procesului) i nu aspectele fizice
(cum se realizeaz ceea ce se proceseaz) ntr-o manier clar, concis i complet, fr a
eluda caracteristici eseniale ale procesului. Metodele de descriere a proceselor pot fi prin:
text obinuit:

descriere imprecis, redundant, abund n elemente


nesemnificative, greu de scris, foarte greu de neles i
aproape imposibil de actualizat;
limbaj natural structurat: descriere precis, neredundant, greu de scris dar uor
de neles i se poate actualiza;
pseudocod:
descriere foarte precis, vocabular redus i uor de
controlat (dar greu de neles pentru nespecialiti);
tabele de decizie:
descriere foarte precis, uor de transformat n
programe, greu de scris (i relativ greu de neles de
ctre nespecialiti);
instrumente grafice:
(arbori, grafuri, scheme etc.) cu caracteristici i faciliti
diferite, considerate ns ca fiind cele mai eficiente din
punct de vedere al comunicrii concise.

n cele ce urmeaz vom trece n revist cteva metode i instrumente de reprezentare.


Textul obinuit (limbajul natural scris sau nregistrat) nu prezint un interes deosebit n
cazul de fa (dei redactarea acestei cri s-a fcut n mare parte prin aceast metod), aa
c vom sri peste el i vom ncepe direct cu varianta structurat a acestuia.
2.2.1

Limbajul natural structurat

Deficienele limbajului natural n ceea ce privete descrierea proceselor (algoritmilor) au


condus la construirea unui limbaj cu o sintax riguroas dar cu un vocabular mai srac, prin
renunarea la calificatori considerai nesemnificativi (adjective i adverbe), la alte moduri
ale verbelor dect cele imperative, la punctuaia excesiv, la adnotri i prin impunerea
folosirii unor propoziii enuniative, simple. Ca i definiie, putem spune c limbajul natural
structurat (prescurtat: LNS) este un limbaj simplificat care mbin vocabularul limitat din
limbajul gazd cu sintaxa limbajelor de programare structurat.
Vocabularul limbajului natural structurat este constituit din verbe cu neles neambiguu (la
modul imperativ), termeni ce descriu obiecte i atribute precise, cuvinte rezervate pentru
formulare logic (dac, atunci, altfel, repet etc.). Sintaxa enunurilor este limitat la

- 22 -

propoziii enuniative simple, construcii decizionale (cu dou posibiliti: da sau nu),
construcii de repetiii, precum i combinaii ale acestor trei. Pentru claritatea exprimrii i
folosirea unui set redus de simboluri, terminarea unei construcii decizionale sau de
repetiie se marcheaz cu o linie vertical care ncepe la nceputul construciei i se ncheie
dup ultimul enun al acesteia. Pentru exemplificare, iat descrierea rezolvrii ecuaiei de
gradul doi (AX2+BX+C=0) n LNS, calculnd partea real (PR) i imaginar (PI) a
rdcinilor:
REPET pentru fiecare set de COEFICIENI
Citete COEFICIENI
DAC A=0
ATUNCI
Respinge COEFICIENIi
ALTFEL
Calculeaz =B24AC
DAC 0
ATUNCI
PR(X1) = (B+ ) / (2A)
PR(X2) = (B ) / (2A)
PI(X1) = 0
PI(X2) = 0
ALTFEL
PR(X1) = (B) / (2A)
PR(X2) = (B) / (2A)
PI(X1) = / (2A)
PI(X2) = / (2A)
Scrie PR(X1) PI(X1) PR(X2) PI(X2)
SFRIT
Printre avantajele limbajului natural structurat putem meniona faptul c poate fi folosit n
orice etap din ciclul de via al proiectului (analiz, proiectare logic, proiectare tehnic)
fiind concis i uor de neles, cu o sintax simpl, constituind un bun limbaj intermediar
fiind apropiat att de limbajul natural ct i de limbajele evoluate de programare, i poate fi
redactat i ntreinut cu editoare de text sau chiar editoare de programare.
Ca i dezavantaje trebuie s menionm c realizarea unui set de reguli sintactice i a unui
vocabular adecvat pentru un LNS este o activitate de durat cu implicarea unei
responsabiliti majore din partea autorilor; prnd mai formalizat dect este n realitate
este acceptat mai greu de ctre analiti i programatori; refacerea iterativ a descrierilor (n
etapa de analiz mai ales) este consumatoare de timp i cere efort; i nu n ultimul rnd, o
bun descriere n LNS a procesului nu garanteaz corectitudinea (un fenomen prost neles
poate fi exprimat la fel de uor n i de coerent n LNS ca i n limbaj natural).
- 23 -

2.2.2

Pseudocodul

Este foarte asemntor cu LNS, fiind tot o reprezentare a pailor algoritmului sub form de
propoziii simple i construcii decizionale i repetitive. Diferena major fa de LNS
const n vocabularul creat din limba englez i din apropierea mai accentuat prin sintax
de limbajele de programare structurate de nivel nalt. n urmtorul tabel se poate observa
diferena dintre limbajul natural structurat, pseudocod i schema logic (prin prisma a trei
primitive funcionale: decizia logic, repetiia postcondiionat i repetiia precondiionat).
Tabel cu 3 exemple de structuri logice elementare
Descriere n LNS
Descriere n pseudocod
Reprezentare n schem logic
DAC C
ATUNCI
Procedura A
ALTFEL
Procedura B

IF C
THEN
DO A
ELSE
DO B
ENDIF

REPET pn cnd C
Procedura A

REPEAT UNTIL C
DO A
ENDREPEAT

Da

Nu

A
Nu

C
Da

REPET ct timp C
Procedura A

2.2.3

WHILE C
DO A
ENDWHILE

C
Nu

Da
A

Tabele de decizie

Este bazat pe identificarea i codificarea condiiilor logice i a aciunilor ce intervin n


urma unor combinaii ale acestor condiii. Acest instrument se poate folosi n orice etap
din dezvoltarea unui program, cu toate c iniial era folosit doar pentru descrierea
procedurilor. Exist i generatoare de programe ce accept ca i surse de intrare tabele de
decizie. Tabelele pot fi mprite n patru zone cu semnificaii distincte: definirea
condiiilor, definirea aciunilor, combinaia condiiilor, respectiv efectul acestor combinaii
n aciuni. n funcie de tipul coninutului zonelor a treia i a patra, putem vorbi de tabele cu
- 24 -

intrri/ieiri simple sau multiple. n cazul n care sunt marcate n cadrul aciunilor salturi
ctre alte tabele de decizie, putem vorbi de tabele imbricate (nlnuite).
n general, la alctuirea unei tabele de decizie trebuie respectate urmtoarele principii:
condiiile sunt prioritare fa de aciuni, acestea din urm find selectate n funcie
de combinaiile condiiilor;
condiiile trebuie s fie independente (unele fa de altele);
orice combinaie de condiii va conduce la un set de aciuni definit.
Pornind de la aceste principii, alctuirea unei tabele de decizii se realizeaz n urmtoarea
secven:

se identific i se definesc toate condiiile (n prima zon);


se definesc toate aciunile (ce vor alctui a doua zon);
se completeaz toate combinaiile valide ale condiiilor (n a treia zon);
se alctuiesc regulile prin marcarea aciunilor (n a patra zon) rezultate n urma
combinrii condiiilor;
se reduce tabela prin fuzionarea regulilor corespunztoare (i eliminarea celor
redundante dac este cazul);
se verific tabela prin testri succesive, validnd versiunea final.
Pentru o ilustrare sumar a structurii unei tabele de decizie vom prezenta exemplul cu
descrierea rezolvrii unei ecuaii de gradul doi (tratat i la LNS):
Zona 1:
condiii

Zona 2:
aciuni

TD1
C1
C2
A1
A2
A3

Zona 3:
cu valorile
condiiilor

marcarea regulilor pe
vertical: R1 R4

Identificatorul
tabelei: TD1
(AX2+BX+C=0)
Coeficientul A nul
Discriminant negativ
Respinge coeficienii
Determin soluiile reale
Determin soluiile complexe

R1
DA
DA
DA

R2
DA
NU
DA

R3
NU
DA

R4
NU
NU
DA

DA
Zona 4: cu valorile aciunilor

n acest exemplu se poate observa c regulile R1 i R2 rezult n aciuni identice, deci


tabela de decizie prezentat (notat TD1) se poate reduce, prin suprapunerea acestor dou
reguli, obinnd o singur regul din ele (n care valoarea condiiei C1 ar fi DA, valoarea
condiiei C2 ar fi * adic ORICE, iar a aciunii A1 ar rmne DA).
Dac o tabel de decizii conine n condiii independente (n zona 1), numrul de combinaii
(din zona 3) va fi de 2n. Dac fiecare condiie i are un numr de pi alternative, vor rezulta
p1p2pn combinaii ale acestor n condiii n total.
- 25 -

2.2.4

Arbori de decizie

Pot fi considerate reprezentri grafice ale unor tabele de decizie, reprezentare n care
nodurile arborelor marcheaz condiii, iar ramurile desemneaz aciuni. Construirea unui
arbore de decizie pentru o procedur se poate face n mod asemntor celui de alctuire a
unei tabele de decizii. De multe ori se creaz arbori de decizii din tabele de decizii,
deoarece arborele (fiind un instrument grafic) constituie un mod mai eficient de comunicare
cu utilizatorii.
Iat exemplul rezolvrii ecuaiei de gradul doi, din nou, de data aceasta ns sub forma unui
arbore de decizie:
Respinge coeficienii
Coeficientul A

Nul
Determin soluiile reale
Nenul
Nenegativ

Discriminant

Negativ
Determin soluiile complexe
2.2.5

Scheme logice

Sunt cele mai cunoscute instrumente folosite pentru descrierea proceselor, din familia celor
grafice. Schema logic este de fapt o reprezentare grafic a pailor dintr-un algoritm, sub
form de blocuri (simboluri) legate prin linii. Pentru a folosi acest instrument ntr-o manier
structurat, trebuie s cunoatem pe lng primitivele funcionale de baz i cteva dintre
principiile fundamentale, cum ar fi:
schemele se alctuiesc i se citesc de sus n jos (excepiile se marcheaz),
ntr-un bloc iniial nu intr nici o legtur i din el pleac o singur linie de
legtur,
ntr-un bloc terminal intr oricte linii de legtur i nici o linie de legtur nu
pleac din el,
n toate celelalte blocuri intr cel puin o linie de legtur, pasul reprezentat de
simbol se aplic n cel puin o succesiune n descrierea algoritmului,
din blocurile de intrare/ieire, atribuire i procedur pleac o singur linie de
legtur,
dintr-un bloc de decizie pleac cel puin dou linii de legtur.
Printre avantajele oferite de acest instrument se pot meniona claritatea i simplitatea
reprezentrii, restrngerea spaiului necesar prin utilizarea simbolurilor grafice n locul

- 26 -

propoziiilor (fa de LNS i pseudocod). Fiind prea analitic, poate ocupa un spaiu destul
de mare n cazul prelucrrii unui volum mare de date (de exemplu prelucrarea fiierelor),
ceea ce este considerat un dezavantaj. Blocurile (simbolurile) folosite la construcia
schemelor logice sunt prezentate n tabelul urmtor.
Simbol

Tabel cu simbolurile utilizate n scheme logice


Denumire
Utilizare
Bloc iniial/terminal
Marcarea nceputului/sfritului schemei
Bloc de intrare/ieire

Marcarea operaiilor de citire/scriere

Bloc de intrare

Marcarea operaiilor de citire

Bloc de ieire

Marcarea operaiilor de scriere

Bloc de atribuire

Punerea n eviden a operaiilor de


calcul i a atribuirii de valori

Bloc de decizie

Marcarea operaiilor de evaluare prin


decidere (apariia ramificaiilor)

Bloc de procedur sau


modul

Marcarea pailor ce vor fi detaliai


ulterior

Bloc de procedur sau


modul (pentru fiiere)

Punerea n eviden a operaiilor de la


nceputul/sfritul prelucrrii fiierelor

Linie de legtur

Precizarea modului de nlnuire a


blocurilor (i marcarea salturilor)

Conector intern

Marcarea ntreruperii i continurii unei


scheme logice n cadrul aceleiai pagini

Conector extern

Marcarea ntreruperii i continurii unei


scheme logice de pe o pagin pe alta

sau

Primitivele funcionale sunt nite structuri simple, standardizate n anii 19691970 la


propunerea lui Dijkstra n scopul structurrii programelor. Ele nu sunt specifice doar
schemelor logice, dar folosind aceste primitive, construirea i citirea schemelor logice

- 27 -

devine mai simpl. Dintre principiile utilizrii acestor structuri la alctuirea schemelor
logice, menionm cele mai importante:
ntr-o primitiv funcional intr o singur legtur i din ea iese o singur
legtur,
un modul dintr-o primitiv funcional poate conine orice primitiv funcional.
Pentru exemplificare vom prezenta rezolvarea ecuaiei de gradul doi (tratat i la LNS,
tabele de decizie i arbori decizionali):

START
INTRODUCEREA
COEFICIENILOR
DA

NU

A=0

:= B2 4AC
COEFICIENI
RESPINI

DA

NU

PR(X1) := (B+ )/(2A)

PR(X1) := B/(2A)

PR(X2) := (B )/(2A)

PR(X2) := B/(2A)

PI(X1) := 0

PI(X1) :=

/(2A)

PI(X2) := 0

PI(X2) :=

/(2A)

PR(X1), PI(X1)
PR(X2), PI(X2)
START
n mod evident nu aceasta este singura modalitate de a rezolva problem propus. Am ales o
singur variant doar pentru a permite compararea diverselor instrumente descriptive ntre
ele.

- 28 -

2.2.6

Diagrame de structur (de tip Jackson)

Utiliznd acest instrument grafic, paii algoritmului ales sunt reprezentai prin module
nlnuite conform unor legi de structur bine precizate. Un modul reprezint un ansamblu
de operaii cu funcii bine definite, delimitate fizic prin elemente de nceput i de sfrit, i
care pot fi referite prin nume. Exist dou tipuri principale de module: module de control
(cu rolul de a apela module componente subordonate) i module funcionale (care avnd
funcii concrete, nu se mai descompun). Simbolurile utilizate sunt ilustrate n tabelul
urmtor:
Simbol

Semnificaie
Bloc pentru identificarea algoritmului (modul de
identificare).
Bloc pentru un modul executat necondiionat, secvenial, o
singur dat.
o

Bloc pentru un modul executat cel mult o dat, n funcie de


o condiie precizat (condiia se noteaz deasupra
modulului).
Bloc pentru un modul executat de mai multe ori, repetitiv,
ct timp este ndeplinit condiia precizat (notat deasupra
modulului).

Printre avantajele acestui instrument menionm posibilitatea descrierii la niveluri logice


diferite n cadrul aceleiai scheme, oferind tehnica optim pentru reprezentarea algoritmilor
compleci. Ca i dezavantaje se menioneaz spaiul extins ocupat pe orizontal (n funcie
de nivelul de detaliere abordat) i necesitatea unei descrieri ulterioare destul de laborioase
pentru modulele funcionale (se poate combina cu alte instrumente descriptive). Iat, din
nou, rezolvarea ecuaiei de gradul doi, descris prin diagram de structur (fr detalierea
modulelor elementare):
REZ.EC.GRD.2
STRUCTURA
INTRRI
CALCUL

A=0
RESPINGE COEF. o

0
DET.SOL.REALE o

EC.GRD.2o

DET.SOL.COMPLEXE o

SCRIE SOLUII

Dei exist nc foarte multe alte instrumente, neprezentate n acest capitol, vom trece n
cele ce urmeaz la prezentarea unei tehnici de baz n modelarea/programarea structurat.
- 29 -

2.2.7

Alte instrumente

n afara celor prezentate exist o varietate foarte mare de instrumente, n special cu caracter
grafic. Dintre acestea menionm doar cteva, ele fiind utile mai mult n fazele de analiz i
de proiectare a sistemelor informatice.
Diagramele cu flux de date (DFD) se pot utiliza pentru reprezentarea proceselor att la
nivel fizic ct i la nivel logic, fiind bazate pe fluxurile de date dintre procese. Ele sunt
completate de regul i cu alte instrumente, cel puin cu unele necesare descrierii datelor
cum ar fi dicionarul datelor (DD), sau diagrama de structur a datelor (DSD). Avantajul lor
const n principal n schematizarea sugestiv i modulat oferit pe parcursul etapelor de
descompunere (analiz) i recompunere (proiectare) a sistemelor informatice. Procesele
elementare, la rndul lor pot fi descrise prin LNS, tabele de decizie, arbori de decizie etc.
Iat cum ar arta reprezentarea generic a unui program, prin DFD:
FLUX-INT.

FLUX-IE.
PROCES

DEPOZIT-DATE
Date de intrare

Prelucrare

Date de ieire

Observnd maniera de reprezentare oferit de DFD se poate deduce necesitatea atarii


unor descrieri suplimentare. T (terminal) i DEPOZIT-DATE sunt periferice standard,
marcate ca atare. Dac prelucrarea marcat prin PROCES poate fi detaliat tot printr-un
DFD (de nivel mai jos, adic mai descompus), fr un dicionar de date nu putem ti ce
nseamn exact FLUX-INT., FLUX-IE., sau ce se transmite din DEPOZIT-DATE.
Specificarea corespunztoare dintr-un dicionar de date ar putea arta n felul urmtor:
FLUX-INT. = (COD) +
DESTINAIE +
10
0

{CANTITATE } +

JUDE + LOCALITATE

COD_POSTAL

n acest exemplu COD este o component opional, CANTITATE se poate repeta de


la 0 la 10 ori, iar dintre JUDE + LOCALITATE i COD_POSTAL exist fie una, fie
alta.

- 30 -

2.2.8

Structurile de control primitive (de tip Dijkstra)

Acestea nu reprezint un instrument n sine, ci aa cum am menionat deja la schemele


logice, reprezint o tehnic de structurare a construirii/descrierii algoritmilor, ce poate fi
aplicat cu orice instrument de reprezentare. La introducerea lor s-a inut cont i de
microspecificaiile existente n cadrul diferitelor limbaje de programare de nivel nalt,
aceste primitive urmrind cerinele programrii structurate prin existena n aproape fiecare
limbaj de programare a unor instruciuni corespunztoare fiecrei structuri de control
primitive.
Exist trei tipuri de structuri de control primitive: secvenial, alternativ (selectiv sau
decizional) i repetitiv. Aceste structuri de control precizeaz de fapt nlnuirea posibil
a pailor unui algoritm, conform principiilor programrii modulare i structurate, paii
putnd fi: propoziii, blocuri sau module. n cele ce urmeaz, vom prezenta cele trei tipuri
de structuri de control (prezentnd i cteva subvariante), descriindu-le att n pseudocod
ct i cu scheme logice i diagrame de structur Jackson.
1.

Structura secvenial (liniar) apare atunci cnd orice operaie se parcurge o dat:
Pseudocod:

Schem logic:
A

DO A
DO B
2.

Diagram de structur
(tip Jackson):
A

Structurile alternative (decizionale sau selective) apar atunci cnd operaiile se


execut opional, n funcie de condiii precizate:

a. varianta clasic (IF-THEN-ELSE):


Pseudocod:
IF C
THEN

Schem logic:
Da

DO A
ELSE

Nu
B

Diagram de structur
(tip Jackson):
C
Ao

B o

DO B
ENDIF
b. varianta cu ramur vid (IF-THEN):
Pseudocod:

Schem logic:
Da

IF C DO A

Diagram de structur
(tip Jackson):

Nu
C
Ao

- 31 -

c. varianta generalizat (CASE):


Pseudocod:
SELECT C
CASE C = 1 : DO A
CASE C = 2 : DO B
...
CASE C = n : DO P
ENDSELECT
3.

Schem logic:

Diagram de structur
(tip Jackson):

C
n

1
A

C=1 C=2
Bo
Ao

C=n
Po

Structurile repetitive apar cnd anumite operaii se execut de mai multe ori, n
funcie de o condiie precizat:

a. varianta condiionat anterior (WHILE-DO):


Pseudocod:
WHILE C
DO A
ENDWHILE

Schem logic:

Da

C
A*

Nu

Diagram de structur
(tip Jackson):

b. varianta condiionat posterior (DO-UNTIL):


Pseudocod:
REPEAT UNTIL C
DO A
ENDREPEAT

Schem logic:
A
C

Diagram de structur
(tip Jackson):

Da

Nu
c. varianta combinat (LOOP-EXIT IF-ENDLOOP):
Pseudocod:
LOOP
DO A
IF NOT C EXIT
DO B
ENDLOOP

Schem logic:

A
C

Diagram de structur
(tip Jackson):

Da
B

Nu

- 32 -

CAPITOLUL 3: FORTRAN 77
3.1

SCRIEREA PROGRAMELOR N LIMBAJUL FORTRAN

n acest capitol vom discuta aspectele legate de redactarea surselor, utiliznd limbajul de
programare Fortran. Un program scris n acest limbaj poate s conin una sau mai multe
seciuni (numite uneori module). Seciunile de program sunt segmente de instruciuni i/sau
de date ce pot fi nglobate n unul sau mai multe fiiere. Acestea pot fi compilate i separat,
ns la construirea programului executabil ele vor fi reunite, mpreun cu bibliotecile
necesare. Pentru redactarea fiierelor ce conin segmentele de program se poate apela la
orice editor de text ce genereaz fiiere cu coninut afiabil curat, ns trebuie avute n
vedere i cteva reguli, prezentate n cele ce urmeaz.
Setul de caractere const din caractere alfanumerice (cele 26 litere mici sau mari ale
alfabetului englez: az, AZ; i cifrele: 09), 4 simboluri pentru operaii aritmetice
(adunare: +, scdere: -, nmulire: *, mprire: /, ridicare la putere: **) precum i dintr-un
set determinat de caractere speciale (blank sau spaiu, tabulator orizontal, virgul, punct,
apostrof, paranteze rotunde deschise i nchise, precum i urmtoarele caractere: =, $, &).
Limbajul Fortran 90 a mai extins aceast list cu urmtoarele caractere speciale admise: _,
!, :, ;, ", %, <, >, ?, ^ i #. n general, conform conveniilor anglo-saxone, virgula are rol
de separator n cadrul unei liste, iar separatorul zecimal este punctul.
Pentru denumirea diferitelor seciuni de program precum i pentru identificarea funciilor,
variabilelor, tablourilor i blocurilor se folosesc nume simbolice. Dac conveniile
versiunilor mai vechi ale limbajului au permis utilizarea a doar 8 caractere (alctuite din
caractere alfanumerice i caracterul special $), Fortran 90 permite utilizarea a 31 de
caractere (alctuite din caractere alfanumerice, caracterul special $ i caracterul special _).
Primul caracter trebuie s fie ntotdeauna o liter. Numele seciunilor de program sunt
considerate globale i trebuie s fie unice n ntreaga surs.
Modul de redactare al sursei poate fi n format fix (Fortran 77), format tabular sau format
liber (admise de Fortran 90 i versiunile ulterioare ale limbajului). Formatul fix respect
structura de redactare bazat pe cartele perforate, considernd lungimea unui rnd (articol)
de maximum 80 de caractere, avnd urmtoarea structur:
Coloane:
Coninut:

15
Etichete.
(n prima
coloan se
poate scrie i
caracterul ce
marcheaz
ntregul rnd
explicit ca fiind
comentariu).

6
772
Caracter ce
Instruciuni.
marcheaz
continuarea
rndului
anterior (dac
este cazul).

- 33 -

7380
Comentariu
implicit.

Etichetele reprezint serii de cel mult 5 caractere numerice (cifre) cu rol de referin n
cadrul seciunii de program, ele marcnd instruciunile n faa crora apar (n rndul
respectiv). Folosirea lor este opional i supus unor restricii (nu toate instruciunile pot
purta etichet). Pentru ca o etichet s fie valid, valoarea ei trebuie s fie cuprins n
intervalul 199999. Dac se dorete marcarea rndului curent ca i comentariu, n prima
coloan se va scrie litera C sau caracterul * (respectiv ! n cazul versiunilor Fortran 90 i
ulterioare), n acest caz structura i coninutul rndului fiind ignorate la compilare. Unele
compilatoare permit i folosirea caracterului D pentru marcarea n prima coloan a rndului
curent ca i comentariu, aceast facilitate permind compilarea (interpretarea) opional a
acestor rnduri n caz de depanare a sursei (debugging).
n Fortran 77 se scrie doar o singur instruciune ntr-un rnd. Dac spaiul dintre coloanele
7 i 72 din rndul curent nu este suficient pentru a scrie instruciunea dorit, ea poate fi
extins marcnd n coloana 6 pe urmtoarele rnduri continuarea celor precedente, prin
cifre (doar din intervalul 19), litere sau prin unul din caracterele +, -, * (sub Fortran 90 se
poate folosi orice caracter n afar de cifra 0). ncepnd cu versiunea 90 a limbajului se
admite scrierea mai multor instruciuni pe un rnd, n cazul acesta caracterul ; fiind
separatorul dintre instruciuni. Numrul liniilor de continuare admise depinde i de
compilatorul ales (Fortran 90 permite pn la 90 de linii de continuare n formatul fix i
doar 31 de rnduri de continuare n formatul liber). Unele compilatoare permit extinderea
zonei de interpretare a rndurilor pn la coloana 80 (chiar coloana 132 n cazul utilizrii
Fortran 90), dar n mod implicit orice coninut din intervalul coloanelor 7280 este
considerat comentariu i ca atare ignorat la compilare.
n format liber structura rndurilor din surs nu conine constrngerile descrise mai sus,
instruciunile nu se limiteaz la o anumit ncadrare pe coloanele liniilor orice linie putnd
conine de la 0 la 132 de caractere. n schimb spaiile sunt semnificative, primind rol
separator n anumite cazuri, pentru a distinge nume, constante sau etichete de numele,
constantele sau etichetele cuvintelor cheie alturate. Acest format a fost introdus doar
ncepnd cu Fortran 90 (acesta accept ns i formatul fix i tabular). n formatul liber
comentariul este indicat de caracterul !, iar continuarea unui rnd curent prin caracterul &
la sfritul rndului curent (lungimea maxim a unui rnd fiind de 132 de caractere). Dac
se scriu mai multe instruciuni pe un rnd, ele trebuie separate prin caracterul ; (la sfritul
unui rnd acest caracter se ignor n mod firesc).
3.2

EXPRESII N FORTRAN

Expresiile sunt alctuite din operatori, operanzi i paranteze. Un operand este o valoare
reprezentat printr-o constant, variabil, element de tablou sau tablou, sau rezultat din
evaluarea unei funcii. Operatorii sunt intrinseci (recunoscui implicit de compilator i cu
caracter global, deci disponibili ntotdeauna tuturor secvenelor de program) sau definii de
utilizator (n cazul n care un operator e descris explicit de programator ca funcie). Dup
modul de operare, putem vorbi de operatori unari (ce opereaz asupra unui singur operand)
i operatorii binari (ce opereaz asupra unei perechi de operanzi).
- 34 -

Orice valoare sau referin la funcie folosit ca operand ntr-o expresie trebuie s fie
definit la momentul evalurii expresiei.
ntr-o expresie cu operatori intrinseci avnd ca operanzi tablouri, acetia din urm trebuie
s fie compatibili (trebuie s aib aceeai form), deoarece operatorii specificai se vor
aplica elementelor corespondente ale tablourilor, rezultnd un tablou corespunztor ca rang
i dimensiune cu operanzii. n cazul n care n expresie pe lng tablouri exist i un
operand scalar, acesta din urm se va aplica tuturor elementelor de tablou (ca i cum
valoarea scalarului ar fi fost multiplicat pentru a forma un tablou corespunztor).
Evaluarea unei expresii are ntotdeauna un singur rezultat, ce poate fi folosit pentru
atribuire sau ca referin.
Expresiile pot fi clasificate n funcie de natura lor n:
expresii aritmetice sau numerice,
expresii de ir (caractere),
expresii logice.
n variantele mai moderne ale limbajului Fortran (ncepnd cu Fortran 90) exist i expresii
considerate ca fiind de iniializare i specificare.
Expresiile numerice, aa cum sugereaz denumirea lor, exprim calcule numerice, fiind
formai din operatori i operanzi numerici, avnd rezultat numeric ce trebuie s fie definit
matematic (mprirea la zero, ridicarea unei baze de valoare zero la putere nul sau
negativ, sau ridicarea unei baze de valoare negativ la putere real constituie operaii
invalide). Termenul de operand numeric poate include i valori logice, deoarece acestea pot
fi tratate ca ntregi ntr-un context numeric (valoarea logic .FALSE. corespunde cu
valoarea 0 de tip ntreg). Operatorii numerici specific calculele ce trebuie executate, dup
cum urmeaz:
**
*
/
+

ridicare la putere;
nmulire;
mprire (diviziune);
adunare sau plus unar (identitate);
scdere sau minus unar (negaie).

ntr-o expresie numeric compus cu mai muli operatori, prima dat se vor evalua
ntotdeauna prile incluse n paranteze (dinspre interior spre exterior) i funciile,
prioritatea de evaluare a operatorilor intrinseci fiind dup cum urmeaz: ridicarea la putere,
nmulirea i mprirea, plusul i minusul unar, adunarea i scderea. n cazul operatorilor
cu aceeai prioritate operaiile vor fi efectuate de la stnga spre dreapta. Prin efect local,
operatorii unari pot influena aceast regul, genernd excepii n cazul unor compilatoare
care accept asemenea expresii. De exemplu, n cazul expresiei numerice X**Y*Z, dei
ridicarea la putere are prioritate mai mare dect nmulirea sau negaia, evaluarea se va face
sub forma x y z (pentru forma x y z ar fi trebuit s scriem X**(Y)*Z ), sau, n cazul

- 35 -

expresiei numerice X/Y*Z, evaluarea se va face sub forma

x
x
(pentru
z ar fi
y
yz

trebuit s scriem X/(Y)*Z sau X/Y*Z ).


Expresiile sunt omogene dac toi operanzii sunt de acelai tip i sunt neomogene n caz
contrar. Tipul valorii rezultate n urma evalurii unei expresii numerice depinde de tipul
operanzilor i de rangul acestora. Dac operanzii din cadrul expresiei au ranguri diferite,
valoarea rezultat va fi de tipul operandului cu cel mai mare rang (cu excepia cazului n
care o operaie implic o valoare complex i una n dubl precizie, rezultatul n asemenea
situaii fiind de tip complex dublu). La verificarea corectitudinii unei expresii numerice
compuse se recomand s se in cont i de tipul valorilor pariale rezultate n cursul
evalurii. Rangul tipurilor de date n ordine descresctoare este urmtoarea:
(COMPLEX*8)
COMPLEX*4
(REAL*16)
REAL*8 i DOUBLE PRECISION
REAL*4
(INTEGER*8)
INTEGER*4
INTEGER*2
INTEGER*1
(LOGICAL*8)
LOGICAL*4
LOGICAL*2
LOGICAL*1 i BYTE
Expresiile de ir (caractere) se pot alctui cu operatorul de concatenare intrinsec + (// n
Fortran 90) sau cu funcii create de programator, aplicate asupra unor constante sau
variabile de tip caracter. Evaluarea unei asemenea expresii produce o singur valoare de tip
caracter. Concatenarea se realizeaz unind coninuturile de tip caracter de la stnga spre
dreapta fr ca eventualele paranteze s influeneze rezultatul. Spaiile coninute de
operanzi se vor regsi i n rezultat.
Expresiile logice constau din operanzi logici sau numerici combinai cu operatori logici
i/sau relaionali. Rezultatul unei expresii logice este n mod normal o valoare logic
(echivalent cu una din constantele literale logice .TRUE. sau .FALSE.), ns operaiile
logice aplicate valorilor ntregi vor avea ca rezultat tot valori de tip ntreg, ele fiind
efectuate bit cu bit n ordinea corespondenei cu reprezentarea intern a acestor valori. Nu
se pot efectua operaii logice asupra valorilor de tip real (simpl sau dubl precizie),
complex sau caracter n mod direct, ns asemenea tipuri de valori pot fi tratate cu ajutorul
unor operanzi relaionali n cadrul expresiilor logice. n tabelele urmtoare vom prezenta
operatorii relaionali i operatorii logici. Cei relaionali au nivel egal de prioritate (se
execut de la stnga la dreapta, dar naintea celor logici i dup cei numerici), iar operatorii

- 36 -

logici sunt dai n ordinea prioritii lor la evaluare. Operatorii relaionali sunt binari (se
aplic pe doi operanzi), la fel i operatorii logici, cu excepia operatorului de negaie logic
(.NOT.) care este unar.
Operator
Fortran 77 Fortran 90
.LT.
<
.LE.
<=
.EQ.
==
.NE.
/=
.GT.
>
.GE.
>=
Operator
.NOT.
.AND.
.OR.
.EQV.
.NEQV.
.XOR.

Tabel cu operatorii relaionali:


Semnificaie
Mai mic dect ... (Less Than)
Mai mic sau egal cu ... (Less or Equal than)
Egal cu ... (EQual with)
Diferit de ... (Not Equal with)
Mai mare dect ... (Greater Than)
Mai mare sau egal cu ... (Greater or Equal than)

Tabel cu operatorii logici:


Semnificaie
Prioritate
Negaie logic (NU), rezult adevrat dac operandul are
mare
valoarea fals i fals dac operandul are valoarea adevrat.
Conjuncie logic (I), rezult adevrat doar dac ambii mai mic
operanzi au valoarea adevrat, n caz contrar rezult fals.
Disjuncie logic (SAU), rezult adevrat dac unul din i mai mic
operanzi are valoarea adevrat, n caz contrar rezult fals.
Echivalen logic, rezult adevrat dac ambii operanzi au
aceai valoare, dac au valori diferite atunci rezult fals.
cea mai
Inechivalen logic, rezult adevrat dac operanzii sunt
mic
diferii, i fals dac sunt la fel.
Disjuncie logic exclusiv (SAU exclusiv), efect similar cu
inechivalena logic.

Expresiile de iniializare i specificare pot fi considerate cele care conin operaii intrinseci
i pri constante, respectiv o expresie scalar ntreag. Aa cum sugereaz i denumirea
lor, ele servesc la iniializarea unor valori (de exemplu indicele pentru controlul unui ciclu
implicit) sau la specificarea unor caracteristici (de exemplu declararea limitelor de tablouri
sau a lungimilor din iruri de caractere).
Prioritatea de evaluare a operatorilor din cadrul expresiilor neomogene este dup cum
urmeaz:

Operatori unari definii (funcii);


Operatori numerici (n urmtoarea ordine: **; *, /; + unar, unar; +, );
Operatorul de concatenare pentru iruri (caractere);
Operatori relaionali (cu prioritate egal: .EQ., .NE., .LT., .LE., .GT., .GE.);
Operatori logici (n ordinea: .NOT.; .AND.; .OR.; .XOR., .EQV., .NEQV.).

- 37 -

3.3

INSTRUCIUNILE LIMBAJULUI DE PROGRAMARE FORTRAN 77

Prezentarea instruciunilor o vom face n ordine alfabetic. Pentru fiecare instruciune se va


specifica forma general, semnificaia elementelor ce apar n sintax, precum i efectul
instruciunii. Instruciunile executabile pot purta etichete, cele declarative nu.
n ceea ce privete notaiile utilizate, v rugm s luai n considerare urmtoarele:
Instruciunile i cuvintele cheie specifice limbajului de programare sunt scrise cu
majuscule ngroate;
[ ] parantezele drepte ncadreaz elemente opionale, aceste paranteze nu fac parte din
sintaxa limbajului de programare prezentat;
... cele trei puncte semnific repetitivitatea unor elemente n cadrul sintaxei;
spaiul (blank-ul) face parte din sintax, apare scris ca atare (fr marcaj special);
( ) parantezele rotunde fac parte din sintax;
, virgula face parte din sintax, are rol separator n cadrul unei liste;
* asteriscul face parte din sintax, de cele mai multe ori se ntlnete la instruciunile de
intrare/ieire semnificnd o valoare implicit (unitatea implicit: consola, sau format
implicit: n funcie de natura elementelor din lista de intrare/ieire).
ACCEPT, citire secvenial cu format:
ACCEPT f [,list]
unde:

ACCEPT instruciunea executabil;


f referina la format (specificator de format);
list lista de intrare.

Efect:

Citete una sau mai multe nregistrri de la consol, convertete valorile


citite n conformitate cu specificaia de format asociat f, dup care le
atribuie elementelor din lista de intrare. Similar cu instruciunea READ.

Variant cu format implicit:

ACCEPT *[,list]

Atribuire aritmetic/logic/caracter:
v=exp
unde:

v variabil, element de tablou sau subir de caractere;


= simbolul pentru operaia de atribuire;
exp expresie.

Efect:

Atribuie valoarea unei expresii aritmetice, logice sau caracter variabilei v.


Se recomand ca tipul variabilei v i tipul expresiei exp s corespund.
- 38 -

ASSIGN, asignare:
ASSIGN e TO v
unde:

ASSIGN instruciunea executabil;


e eticheta unei instruciuni executabile sau a unei instruciuni FORMAT
din aceeai unitate de program cu instruciunea ASSIGN;
TO cuvnt cheie;
v variabil ntreag.

Efect:

Atribuie eticheta s unei variabile ntregi v pentru a fi utilizat ulterior ntro instruciune GOTO asignat sau ca un specificator de format n cadrul
unei instruciuni de citire/scriere.

BACKSPACE, repoziionare n cadrul unui fiier secvenial:


BACKSPACE u
sau
BACKSPACE([UNIT=]u[,ERR=e])
unde:

BACKSPACE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile.

Efect:

Repoziioneaz un fiier secvenial, n curs de prelucrare, aflat pe unitatea


logic u, la nceputul nregistrrii precedente nregistrrii la care s-a fcut
accesul prin ultima instruciune de intrare/ieire efectuat nainte de
BACKSPACE. n cazul unei erori la executarea instruciunii se va preda
controlul instruciunii executabile care poart eticheta e din cadrul
aceluiai modul de program. Atunci cnd n sintax s-a folosit ERR=e i
apare o eroare la execuie, controlul va fi transferat instruciunii
executabile cu eticheta e din cadrul aceleiai uniti de program.

Bloc de date sub form de subunitate:


BLOCK DATA [nume]
unde:

BLOCK DATA instruciunea declarativ;


nume un nume simbolic.

- 39 -

Efect:

Specific un subprogram (modul) executabil ce urmeaz a fi descris, ca


bloc de date.

CALL, apel la subprogram:


CALL nume[([p][,p]...)]
unde:

CALL instruciunea executabil;


nume numele unui subprogram sau al unui punct de intrare (a se vedea
instruciunile SUBROUTINE i ENTRY);
p parametru efectiv (poate fi o expresie sau numele unei variabile,
numele unui tablou sau numele unui subprogram).

Efect:

Apeleaz un subprogram sau orice procedur extern avnd numele


nume, transfernd controlul execuiei la acesta i asociind parametrii
efectivi p parametrilor formali din procedura apelat.

CLOSE, nchiderea unui fiier deschis:


CLOSE([UNIT=]u[,c=val][,ERR=e])
unde:

CLOSE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
c opiune, unul din cuvintele cheie: STATUS, DISPOSE sau DISP;
val subir caracter corespunztor valorii cuvntului cheie c, putnd fi:
'SAVE', 'KEEP', 'DELETE' sau 'PRINT'.
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile.

Efect:

Realizeaz nchiderea unui fiier deschis, deconectnd fiierul de unitatea


logic u la care a fost asociat anterior. A se vedea i instruciunea OPEN.
Atunci cnd n sintax s-a folosit ERR=e i apare o eroare la execuie,
controlul va fi transferat instruciunii executabile cu eticheta e din cadrul
aceleiai uniti de program.

COMMON, declararea unei zone comune de memorie:


COMMON [/[bc]/] nlist[[,][/[bc]/] nlist]...
unde:

COMMON instruciunea declarativ;


bc numele unui bloc comun;
- 40 -

nlist o list de nume de variabile, nume de tablouri sau declaratori de


tablou, separate prin virgule.
Efect:

Permite definirea uneia sau mai multor zone contigue de memorie, numite
blocuri comune, avnd numele specificat i coninnd variabile asociate
cu numele blocului.

CONTINUE, continuarea execuiei:


CONTINUE
unde:

CONTINUE instruciunea executabil.

Efect:

Transfer controlul execuiei la urmtoarea instruciune executabil. Fiind


o instruciune executabil, poate purta etichet, din acest motiv se
recomand utilizarea ei dup instruciunile declarative ce nu pot fi
etichetate, atunci cnd este cazul.

DATA, definirea datelor sub forma unui modul:


DATA nlist/clist/[[,]nlist/clist/]...
unde:

DATA instruciunea declarativ;


nlist este o list de una sau mai multe variabile, nume de tablouri,
elemente de tablouri sau nume de subiruri caracter, separate prin virgule;
clist este o list alctuit din una sau mai multe constante separate
prin virgule, de forma:
[n*]val[,[n*]val]...
unde

Efect:

n este o constant ntreag fr semn, diferit de zero;


val o valoare constant.

Valorile constante din fiecare clist sunt atribuite succesiv (n ordine de la


stnga la dreapta) cte unei entiti specificate n lista nlist asociat.

DECODE, citire intern cu transformare prin format:


DECODE(n,f,var[,ERR=e]) [list]
unde:

DECODE instruciunea executabil;


n o expresie ntreag;
f referina la format (specificator de format);
- 41 -

var numele unei variabile, unui tablou, unui element de tablou sau
subir caracter;
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list lista de intrare.
Efect:

Citete n caractere din tamponul var i atribuie valori elementelor din


list, valori care au rezultat din conversia conform specificaiei de format
f. Atunci cnd n sintax s-a folosit ERR=e i apare o eroare la execuie,
controlul va fi transferat instruciunii executabile cu eticheta e din cadrul
aceleiai uniti de program.

DEFINE FILE, definirea structurii unui fiier:


DEFINE FILE u(m,n,U,v)[,u(m,n,U,v)]...
unde:

DEFINE FILE instruciunea declarativ;


u variabil sau constant ntreag;
m variabil sau constant ntreag;
n variabil sau constant ntreag;
U variabil sau constant ntreag;
v variabil ntreag.

Efect:

Definete structura nregistrrii unui fiier n acces direct unde u este


numrul unitii logice, m este numrul nregistrrilor (de lungime fix
din cauza accesului direct) din fiier, n este lungimea n cuvinte a unei
nregistrri, U este un argument fixat, iar v este variabila asociat
fiierului (n aceast variabil se va memora numrul nregistrrii imediat
urmtoare celei curente).

DELETE, tergerea unei nregistrri:


DELETE([UNIT=]u[,REC=r][,ERR=e])
sau
DELETE(u'r[,ERR=e])
unde:

DELETE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
REC cuvnt cheie pentru desemnarea nregistrrii;
r expresie ntreag (semnificnd numrul nregistrrii vizate);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;

- 42 -

e eticheta unei instruciuni executabile.


Efect:

terge nregistrarea specificat prin r, din fiierul asociat unitii logice u,


sau cea mai recent nregistrare accesat. Atunci cnd n sintax s-a
folosit ERR=e i apare o eroare la execuie, controlul va fi transferat
instruciunii executabile cu eticheta e din cadrul aceleiai uniti de
program.

Declaraia de tip:
tip var[,var]...
unde:

tip este unul din urmtoarele tipuri de date: BYTE, LOGICAL (sau
LOGICAL*1,
LOGICAL*2,
LOGICAL*4),
INTEGER
(sau
INTEGER*2, INTEGER*4), REAL (sau REAL*4, REAL*8), DOUBLE
PRECISION, COMPLEX (sau COMPLEX*8), CHARACTER (sau
CHARACTER*lungime);
var numele unei variabile, unui tablou, unei funcii externe, unei
funcii aritmetic definite, unei funcii parametru formal sau al unui
declarator de tablou. Numele poate fi urmat opional de un specificator de
lungime de forma: *n
unde:

Efect:

n este o expresie ntreag semnificnd lungimea lui var n


octei (n cazul entitilor caracter semnific numrul de
caractere).

Numele simbolic var va avea asignat tipul specificat prin tip. Fiind
declaraie, nu poate purta etichet. Declaraia de tip poate fi combinat cu
declararea dimensiunilor pentru tablouri, n acest caz nemaifiind necesar
utilizarea instruciunii DIMENSION ntr-un mod explicit (n asemenea
cazuri var va avea forma: a(d) cu semnificaia termenilor de la
declaraia DIMENSION.

DIMENSION, declararea dimensiunilor:


DIMENSION a(d)[,a(d)]...
unde:

DIMENSION instruciune declarativ;


a numele tabloului;
d declaratorul de dimensiune, sub forma: n[,n]...
unde:

n este o expresie ntreag (semnificnd numrul maxim de


elemente n dimensiunea respectiv).

- 43 -

Efect:

Specific spaiul de memorie necesar tablourilor.

DO, instruciune pentru cicluri repetitive:


DO e[,] c=i,f[,p]
unde:

DO instruciune executabil;
e eticheta unei instruciuni executabile;
c variabil (variabila de control al ciclului);
i expresie numeric (desemnnd o valoare iniial);
f expresie numeric (desemnnd o valoare final);
p expresie numeric (desemnnd pasul variabilei de control).

Efect:

Execut ciclul DO (instruciunile ce urmeaz, pn la cea care poart


eticheta e inclusiv, acestea alctuind corpul ciclului), realiznd
urmtoarele faze:
1. Evalueaz: cnt=INT((f-i+p)/p) (cnt fiind contorul ciclului).
2. Execut atribuirea: c=i
3. Dac c este mai mic sau egal cu zero, nu se va executa ciclul.
4. Dac c este mai mare ca zero, atunci:
a. Execut instruciunile din corpul ciclului.
b. Evalueaz:
c=c+p
c. Decrementeaz contorul ciclului: cnt=cnt-1 i dac cnt este
mai mare dect zero, repet ciclul.

Varianta de ciclu implicit: ([list,] c=i,f[,p])

Not:

unde:

list list de intrare/ieire;


celelalte valori avnd semnificaiile de la instruciunea DO.

Efect:

Determin executarea ciclului asupra elementelor din list n cadrul unei


operaii de intrare/ieire. Condiiile de realizare ale ciclului sunt similare
cu cele de la instruciunea DO.

Varianta de ciclu implicit poate fi folosit doar n cadrul listelor de intrare/ieire de


la instruciunile de citire/scriere. Aceast variant nu reprezint o instruciune de
sine stttoare, este considerat doar expresie de iniializare.

ENCODE, scriere intern cu transformare prin format:


ENCODE(n,f,var[,ERR=e]) [list]
unde:

ENCODE instruciunea executabil;


- 44 -

n expresie ntreag;
f referina la format (specificator de format);
var numele unei variabile, unui tablou, unui element de tablou sau
subir caracter;
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list lista de ieire.
Efect:

Scrie n caractere din list n tamponul var, care va primi caracterele


convertite conform specificaiei de format f. Atunci cnd n sintax s-a
folosit ERR=e i apare o eroare la execuie, controlul va fi transferat
instruciunii executabile cu eticheta e din cadrul aceleiai uniti de
program.

END, marcaj de sfrit:


END
unde:

END instruciunea declarativ;

Efect:

Marcheaz sfritul unei uniti de program (fiind obligatoriu pentru


compilare).

ENDFILE, scrierea unei nregistrri EOF:


ENDFILE u
sau
ENDFILE([UNIT=]u[,ERR=e])
unde:

ENDFILE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile.

Efect:

Scrierea unei nregistrri de sfrit de fiier (EOF End Of File) n


fiierul secvenial asociat unitii logice u. Atunci cnd n sintax s-a
folosit ERR=e i apare o eroare la execuie, controlul va fi transferat
instruciunii executabile cu eticheta e din cadrul aceleiai uniti de
program.

- 45 -

ENTRY, declararea unui punct de intrare:


ENTRY nume[(p[,p]...)]
unde:

ENTRY instruciunea declarativ;


nume numele punctului de intrare;
p un nume simbolic reprezentnd un parametru formal.

Efect:

Permite crearea unor puncte de intrare multiple n unitile de program


declarate ca FUNCTION i SUBROUTINE.

EQUIVALENCE, echivalare prin declarare:


EQUIVALENCE (nlist)[,(nlist)]...
unde:

EQUIVALENCE instruciunea declarativ;


nlist este o list de cel puin dou variabile, nume de tablouri,
elemente de tablouri sau subiruri caracter, separate prin virgule.
Expresiile de indici trebuie s fie constante ntregi.

Efect:

Aloc fiecrei entiti din nlist aceeai locaie de memorie.

EXTERNAL, declararea unor module externe:


EXTERNAL nume[,nume]...
sau
EXTERNAL *nume[,*nume]...
unde:

EXTERNAL instruciunea declarativ;


nume numele unei uniti de program.

Efect:

Definete numele specificat ca fiind numele unei uniti de program.


Cnd nume este precedat de *, definete o unitate (subprogram) extern
furnizat de utilizator.

FIND, poziionare n fiier:


FIND(u'r[,ERR=e])
sau
FIND([UNIT=]u[,REC=r][,ERR=e])

- 46 -

unde:

FIND instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
REC cuvnt cheie pentru desemnarea nregistrrii;
r expresie ntreag (semnificnd numrul nregistrrii vizate);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile.

Efect:

Poziioneaz fiierul n acces direct de pe unitatea logic u pe articolul


specificat prin r. Atunci cnd n sintax s-a folosit ERR=e i apare o
eroare la execuie, controlul va fi transferat instruciunii executabile cu
eticheta e din cadrul aceleiai uniti de program.

FORMAT, declararea formei la operaii de intrare/ieire:


FORMAT(list)
unde:

FORMAT instruciunea de specificare;


list list de una sau mai muli descriptori (specificatori de cmp).

Efect:

Descrie formatul n care urmeaz s se transmit, prin intermediul


instruciunilor de citire/scriere, una sau mai multe nregistrri.
Instruciunea trebuie ntotdeauna etichetat, altfel nu-i are rostul.

Funcie aritmetic definit:


nume([p[,p]...])=exp
unde:

nume nume simbolic (denumirea funciei);


p nume simbolic (al parametrului formal);
exp expresie.

Efect:

Permite realizarea unei proceduri definite printr-o singur instruciune i


avnd p drept parametru formal. Cnd funcia nume astfel definit este
referit, se evalueaz expresia exp utiliznd parametri efectivi de apel.
Este o instruciune declarativ ce poate fi precedat de o declaraie de tip.

- 47 -

FUNCTION, declararea unei funcii ca modul:


FUNCTION nume[([p[,p]...])]
unde:

FUNCTION instruciunea declarativ;


nume nume simbolic (asociat modulului);
p nume simbolic (parametru formal).

Efect:

Definete o unitate de program ca funcie extern (modul separat de


program) avnd numele indicat prin nume i utiliznd parametri formali p.
Transferarea valorilor parametrilor se efectueaz prin corespondena celor
formali p (ca ordine i tip) cu cei efectivi, la invocarea funciei prin nume.

GO TO, salt necondiionat:


GO TO e
sau
GOTO e
unde:

GO TO cuvinte cheie ale instruciunii executabile;


e eticheta unei instruciuni executabile.

Efect:

Determin transferul controlului la executarea instruciunii cu eticheta e


din cadrul aceleiai uniti de program.

GO TO, salt calculat:


GO TO (list)[,]exp
sau
GOTO (list)[,]exp
unde:

GO TO cuvinte cheie ale instruciunii executabile;


list list de una sau mai multe etichete de instruciuni executabile,
separate prin virgul;
exp expresie aritmetic (ntreag).

Efect:

Transfer controlul la instruciunea a crei etichet ocup poziia exp n


list. Dac exp este mai mic dect 1 sau mai mare dect numrul
etichetelor din list, nu se va efectua transferul.

- 48 -

GO TO, salt asignat:


GO TO v[[,](list)]
sau
GOTO v[[,](list)]
unde:

GO TO cuvinte cheie ale instruciunii executabile;


v variabil de tip ntreg;
list list de una sau mai multe etichete de instruciuni executabile,
separate prin virgul.

Efect:

Transfer controlul la instruciunea a crei etichet a fost atribuit


variabilei v printr-o instruciune prealabil ASSIGN. Dac se utilizeaz
list, valoarea atribuit lui v trebuie s aparin listei (n caz contrar, nu
are loc transferul).

IF aritmetic:
IF(exp)e1,e2,e3
unde:

IF instruciunea executabil;
exp expresie aritmetic;
e1, e2, e3 etichetele unor instruciuni executabile.

Efect:

Transfer controlul la instruciunea cu eticheta e1, e2 sau e3 din aceeai


unitate de program, n funcie de valoarea expresiei exp: dac exp rezult
mai mic ca zero, controlul este transferat la instruciunea cu eticheta e1;
dac exp rezult zero, controlul este transferat instruciunii cu eticheta e2;
dac exp rezult mai mare ca zero controlul este transferat instruciunii cu
eticheta e3.

IF logic simplu:
IF(exp) inst
unde:

IF instruciunea executabil;
exp expresie logic;
inst orice instruciune executabil cu excepia urmtoarelor: DO, END,
IF logic simplu, IF logic structurat (IF-THEN sau bloc IF).

Efect:

Execut instruciunea inst dac expresia logic exp are valoare .TRUE.
(adevrat). n caz contrar, se execut instruciunea care urmeaz
instruciunii IF logic fr a se mai executa instruciunea inst.
- 49 -

IF logic structurat (blocul IF):


IF(exp1) THEN
[bloc]
[ELSE [IF(exp2) THEN
[bloc]
[ELSE
bloc]]
ENDIF
unde:

IF instruciunea executabil;
exp1 expresie logic;
exp2 expresie logic;
THEN cuvnt cheie (obligatoriu);
ELSE cuvnt cheie (opional); definete un bloc de instruciuni ce
urmeaz a fi executate dac expresiile logice din instruciunile IF-THEN
precedente au valoarea .FALSE. (fals);
bloc o secven de una sau mai multe instruciuni;
ENDIF cuvnt cheie (obligatoriu); marcheaz terminarea unui bloc IF.

Efect:

Definete blocuri de instruciuni i le execut condiionat. Dac expresia


logic exp1 din instruciunea IF-THEN are valoarea .TRUE., se va
executa primul bloc i controlul se va transfera la prima instruciune
executabil dup cuvntul cheie ENDIF. Dac expresia logic exp1 are
valoarea logic .FALSE., procedura se va repeta pentru urmtoarea
instruciune ELSE IF-THEN. Dac toate expresiile logice au valoarea
.FALSE., se va executa bloc-ul ce urmeaz cuvntului cheie ELSE.
Dac acest bloc nu exist, controlul se va transfera la urmtoarea
instruciune executabil care urmeaz cuvntului cheie ENDIF.

IMPLICIT, declararea naturii implicite de tip:


IMPLICIT tip (a[,a]...)[,tip (a[,a]...)]...
unde:

IMPLICIT instruciunea declarativ;


tip specificator de tip (a se vedea Declaraia de tip);
a fie o singur liter, fie dou litere, n ordine alfabetic, separate printro liniu (de exemplu: A,DF).

Efect:

Atribuie tipul specificat tuturor entitilor al cror nume simbolic ncepe


cu una din literele aparinnd domeniului descris ntre paranteze.

- 50 -

INCLUDE, inserare de cod:


INCLUDE 'specfis'[ /opt]
unde:

INCLUDE instruciunea declarativ;


specfis un specificator de fiier (citat);
opt opiune (comutator opional) cu una din urmtoarele dou forme:
LISTF se listeaz instruciunile incluse (implicit);
NOLIST nu se listeaz instruciunile din fiierul inclus.

Efect:

Include instruciunile surs din fiierul specificat prin specfis n


compilarea fiierului surs curent.

INTRINSIC, redeclararea funciilor interne:


INTRINSIC nume[,nume]...
unde:

INTRINSIC instruciunea declarativ;


nume numele simbolic al unei funcii intrinseci (interne).

Efect:

Desemneaz numele simbolic ca funcii intrinseci i permite utilizarea


acestor nume n cadrul unitii curente de program, cu parametri efectivi.
Se subnelege c aceste funcii trebuie s fie funcii existente, predefinite
intern.

OPEN, deschiderea fiierelor:


OPEN(p[,p]...)
unde:

OPEN instruciunea executabil;


p parametru, fiind specificaia unui cuvnt cheie, de forma:
cuv
unde

Efect:

sau

cuv=val

cuv este cuvnt cheie (a se vedea tabelul urmtor);


val valoare n funcie de cuvntul cheie cuv (a se vedea
tabelul urmtor).

Deschide un fiier asociindu-l cu unitatea logic u specificat, n


conformitate cu parametrii specificai prin cuvintele cheie.

- 51 -

Tabel cu parametrii din instruciunea OPEN (n ordine alfabetic):


Cuvntul cheie (cuv)
Valoarea (val)
Funciune
Implicit
'SEQUENTIAL'
ACCESS
'SEQUENTIAL' Metoda de acces
'DIRECT'
'APPEND'
'KEYED'
ASSOCIATEVARIABLE val
Numrul
Nu exist variabil
nregistrrii
asociat
urmtoare n
accesul direct
'NULL'
BLANK
'NULL'
Interpretarea
'ZERO'
spaiilor
(blank-urilor)
BLOCKSIZE
val
Dimensiunea
Alocat de sistem
tamponului de
intrare/ieire
BUFFERCOUNT
val
Numrul de
Alocat de sistem
tampoane de
intrare/ieire
CARRIAGECONTROL
'FORTRAN'
Controlul
'FORTRAN' n
'LIST'
(interpretarea)
cazul formatat, i
'NONE'
returului de car
'NONE' n cazul
neformatat
DISPOSE
'SAVE'
Starea fiierului la 'SAVE'
'KEEP'
sau
nchidere
'PRINT'
DISP
'DELETE'
ERR
e
Eticheta de transfer Nu se face transfer
la eroare
la eroare
EXTENDSIZE
val
Extensie de alocare Dat de sistemul
a spaiului de
de operare sau de
memorie pentru
volum (partiie)
fiier
FILE
specfis
Specificator de
Depinde de unitate
sau
fiier
i de sistem
NAME
'FORMATTED'
FORM
Formatul fiierului Depinde de
'UNFORMATTED'
cuvntul cheie
ACCESS
INITIALSIZE
val
Spaiu de memorie Nu se aloc
alocat pentru fiier
KEY
(k[,k]...)
Cmpurile de cheie Nu este implicit
pentru fiier
indexat

- 52 -

Cuvntul cheie (cuv)


MAXREC

Valoarea (val)
val

NOSPANBLOCKS
ORGANIZATION

'SEQUENTIAL'
'RELATIVE'
'INDEXED'

READONLY

Funciune
Numrul maxim de
nregistrri n
accesul direct
nregistrrile nu
traverseaz
blocurile
Structura fiierului

Implicit
Nu exist
maximum

Protecie la scriere

Neprotejat la
scriere
Depinde de
cuvintele cheie:
TYPE,
ORGANIZATION,
RECORDTYPE
Depinde de
cuvintele cheie:
ACCESS, FORM
Nu este permis
accesul partajat la
fiier
'UNKNOWN'

RECL
sau
RECORDSIZE

val

Lungimea
nregistrrii

RECORDTYPE

'FIXED'
'VARIABLE'
'SEGMENTED'

Structura
nregistrrii

SHARED
STATUS
sau
TYPE

Acces partajat la
fiier

UNIT

'OLD'
'NEW'
'SCRATCH'
'UNKNOWN'
u

USEROPEN

nume

Starea fiierului la
deschidere
Numrul unitii
logice asociate
fiierului
Opiune pentru un
program utilizator

nregistrrile pot
traversa blocurile
'SEQUENTIAL'

Nu este implicit
Nu exist opiune

Semnificaia notaiilor din coloana valorilor val (exceptnd cuvintele cheie):


val valoare numeric;
e eticheta unei instruciuni executabile;
specfis specificator de fiier;
k numele simbolic asociat cmpului de cheie;
u numrul unitii logice;
nume numele simbolic al unei uniti de program.

- 53 -

PARAMETER, declaraie pentru parametri:


PARAMETER (p=c[,p=c]...)
unde:

PARAMETER instruciunea declarativ;


p nume simbolic;
c constant.

Efect:

Definete un nume simbolic pentru o constant.

PAUSE, suspendarea temporar a execuiei:


PAUSE [ir]
unde:

PAUSE instruciunea executabil;


ir un ir constituit din maximum cinci caractere numerice (cifre), o
constant octal sau un literal alfanumeric.

Efect:

Suspend execuia programului i afieaz ir la terminal. Execuia


programului se continu doar dup comanda dat de la tastatur de ctre
utilizator.

PRINT, scriere secvenial:


PRINT f[,list]
unde:

PRINT instruciunea executabil;


f referin la format (specificator de format);
list list de ieire.

Efect:

Scrie o nregistrare pe dispozitivul de ieire implicit (consol/monitor sau


imprimant), coninnd valorile elementelor din list. Valorile sunt
convertite n conformitate cu specificaia de format f.

Varianta cu format implicit:

PRINT *[,list]

PROGRAM, definirea programului principal:


PROGRAM nume
unde:

PROGRAM instruciunea declarativ;


- 54 -

nume nume simbolic (asociat corpului programului principal).


Efect:

Specific un nume pentru programul principal. Declaraia fiind opional,


n cazul n care este omis, programul principal va purta numele simbolic
MAIN.

READ, citire secvenial:


READ([UNIT=]u[,[FMT=]f][,END=e1][,ERR=e2]) [list]
sau
READ f[,list]
unde:

READ instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
END cuvnt cheie pentru tratarea ntlnirii sfritului fiierului (EOF);
e1 eticheta unei instruciuni executabile;
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e2 eticheta unei instruciuni executabile;
list list de intrare (cu elemente separate prin virgul).

Efect:

Citete una sau mai multe nregistrri logice de la unitatea u i atribuie


valori elementelor din list. Valorile sunt convertite n conformitate cu
specificatorul de format f. Atunci cnd n sintax s-a folosit END=e1 i la
executarea instruciunii se ntlnete sfritul fiierului (EOF), controlul
va fi transferat instruciunii executabile cu eticheta e1 din cadrul aceleiai
uniti de program. Atunci cnd n sintax s-a folosit ERR=e2 i apare o
eroare la execuie, controlul va fi transferat instruciunii executabile cu
eticheta e2 din cadrul aceleiai uniti de program.

Varianta cu format implicit:


READ([UNIT=]u,[FMT=]*[,END=e1][,ERR=e2]) [list]
sau
READ *[,list]
Efect:

Citete una sau mai multe nregistrri logice de la unitatea u i atribuie


valori elementelor din list. Valorile sunt convertite n conformitate cu
tipul elementelor din list.

- 55 -

Varianta fr format:
READ([UNIT=]u[,END=e1][,ERR=e2]) [list]
Efect:

Citete o nregistrare (un articol) fr format de la unitatea logic u i


atribuie valori elementelor din list.

READ, citire n acces direct:


READ([UNIT=]u,REC=r[,[FMT=]f][,ERR=e]) [list]
sau
READ(u'r[,[FMT=]f][,ERR=e]) [list]
unde:

READ instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
REC cuvnt cheie pentru desemnarea nregistrrii;
r expresie ntreag (semnificnd numrul nregistrrii vizate);
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list list de intrare (cu elemente separate prin virgul).

Efect:

Citete nregistrri pornind cu nregistrarea r de la unitatea logic u i


atribuie valori elementelor din list. Valorile sunt convertite n
conformitate cu specificatorul de format f. Atunci cnd n sintax s-a
folosit ERR=e i apare o eroare la execuie, controlul va fi transferat
instruciunii executabile cu eticheta e din cadrul aceleiai uniti de
program.

Varianta fr format:
READ([UNIT=]u,REC=r[,ERR=e]) [list]
sau
READ(u'r[,ERR=e]) [list]
Efect:
Not:

Citete nregistrarea r de la unitatea logic u i atribuie valori elementelor


din list.

Citirea direct se aplic fiierelor cu organizare relativ. Un fiier secvenial poate


fi citit n acces direct numai dac nregistrrile au lungimi egale (fixe) i fiierul a
fost asociat cu o unitate logic prin instruciunea OPEN utiliznd i parametrul
ACCESS='DIRECT'. A se vedea instruciunea OPEN.
- 56 -

READ, citire indexat:


READ([UNIT=]u[,[FMT=]f],cc=vc[,KEYID=nc][,ERR=e]) [list]
unde:

READ instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
cc cuvnt cheie, una din urmtoarele:
KEY, KEYEQ, KEYGE sau KEYGT;
vc expresie (valoare) de cheie;
KEYID cuvnt cheie pentru referina cheii;
nc expresie ntreag (numrul de referin sau rangul cheii);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list list de intrare (cu elemente separate prin virgul).

Efect:

Citete nregistrarea, de la unitatea logic u, descris de expresia de cheie


vc i numrul de referin al cheii nc. Valorile din nregistrare sunt
convertite n conformitate cu specificatorul de format f i vor fi atribuite
elementelor din list. Dac cuvntul cheie KEYID este omis (i implicit
referina de cheie nc), atunci se subnelege un singur cmp definit ca i
cheie n structura nregistrrii. Atunci cnd n sintax s-a folosit ERR=e i
apare o eroare la execuie, controlul va fi transferat instruciunii
executabile cu eticheta e din cadrul aceleiai uniti de program.

Varianta fr format:
READ([UNIT=]u,cc=vc[,KEYID=nc][,ERR=e]) [list]
Efect:

Not:

Citete nregistrarea, de la unitatea logic u, descris de expresia de cheie


vc i numrul de referin al cheii nc. Valorile din nregistrare vor fi
atribuite elementelor din list.

Citirea indexat se poate aplica doar fiierelor indexate care conin una sau mai
multe cmpuri de nregistrare declarate sub form de cheie. A se vedea instruciunea OPEN.

READ, citire intern:


READ([UNIT=]c,[FMT=]f[,END=e1][,ERR=e2]) [list]

- 57 -

Not:

unde:

READ instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
c specificator de fiier intern;
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
END cuvnt cheie pentru tratarea ntlnirii sfritului fiierului (EOF);
e1 eticheta unei instruciuni executabile;
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e2 eticheta unei instruciuni executabile;
list list de intrare (elementele separate prin virgul).

Efect:

Citete date caracter de la un fiier intern c, transform datele din caracter


n form binar utiliznd specificatorul de format f, atribuie datele
transformate elementelor din list n ordine, de la stnga la dreapta.
Atunci cnd n sintax s-a folosit END=e1 i la executarea instruciunii se
ntlnete sfritul fiierului (EOF), controlul va fi transferat instruciunii
executabile cu eticheta e1 din cadrul aceleiai uniti de program. Atunci
cnd n sintax s-a folosit ERR=e2 i apare o eroare la execuie, controlul
va fi transferat instruciunii executabile cu eticheta e2 din cadrul aceleiai
uniti de program.

Citirea intern se utilizeaz pentru convertirea caracterelor. A se vedea i


instruciunea DECODE.

RETURN, revenire din subunitatea curent de program n cel apelant:


RETURN
unde:

RETURN intruciune executabil.

Efect:

ntoarce controlul programului apelant din cadrul subprogramului curent.

REWIND, repoziionare:
REWIND([UNIT=]u[,ERR=e])
sau
REWIND u
unde:

REWIND instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);

- 58 -

ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;


e eticheta unei instruciuni executabile.
Efect:

Repoziioneaz unitatea logic u la nceputul fiierului curent, deschis.


Atunci cnd n sintax s-a folosit ERR=e i apare o eroare la execuie,
controlul va fi transferat instruciunii executabile cu eticheta e din cadrul
aceleiai uniti de program.

REWRITE, rescriere:
REWRITE([UNIT=]u[,[FMT=]f][,ERR=e]) [list]
unde:

REWRITE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list lista de ieire.

Efect:

Rescrie nregistrarea curent de pe unitatea logic u, utiliznd valorile


elementelor din list. Valorile sunt convertite conform referinei de
format f (dac aceasta a fost specificat). Atunci cnd n sintax s-a folosit
ERR=e i apare o eroare la execuie, controlul va fi transferat instruciunii
executabile cu eticheta e din cadrul aceleiai uniti de program.

SAVE, salvarea entitilor:


SAVE [a[,a]...]
unde:

SAVE instruciunea declarativ;


a numele unui bloc comun (incadrat de /-uri), nume de variabil sau de
tablou.

Efect:

Pstreaz definirea curent a entitilor a dup ntlnirea unei instruciuni


END sau RETURN a unui subprogram.

- 59 -

STOP, oprirea execuiei:


STOP [ir]
unde:

STOP instruciunea executabil;


ir un ir de maximum cinci cifre zecimale, un literal alfanumeric sau
o constant octal.

Efect:

Termin execuia programului, afind la terminalul utilizatorului ir-ul


specificat.

SUBROUTINE, declararea unui subprogram:


SUBROUTINE nume[([p[,p]...])]
unde:

SUBROUTINE instruciunea declarativ;


nume nume simbolic (asociat subprogramului);
p nume simbolic (parametru formal).

Efect:

Definete o unitate de program ca subprogram extern avnd numele


indicat prin nume i utiliznd parametri formali p. Transferarea valorilor
se efectueaz prin corespondena parametrilor formali p (ca ordine i tip)
cu parametrii efectivi din linia de apel. A se vedea instruciunea CALL.

TYPE, scriere secvenial:


TYPE f[,list]
unde:

TYPE instruciunea executabil;


f referin la format (specificator de format);
list list de ieire.

Efect:

Scrie o nregistrare pe dispozitivul de ieire implicit (consol/monitor),


coninnd valorile elementelor din list. Valorile sunt convertite n
conformitate cu specificaia de format f.

Varianta cu format implicit:

TYPE *[,list]

- 60 -

UNLOCK, deblocarea unitii logice:


UNLOCK([UNIT=]u[,ERR=e])
sau
UNLOCK u
unde:

UNLOCK instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile.

Efect:

Deblocheaz toate nregistrrile curente blocate, de pe unitatea logic u.


Atunci cnd n sintax s-a folosit ERR=e i apare o eroare la execuie,
controlul va fi transferat instruciunii executabile cu eticheta e din cadrul
aceleiai uniti de program.

VIRTUAL, declararea memoriei virtuale:


VIRTUAL a(d)[,a(d)]...
unde:

VIRTUAL instruciunea declarativ;


a numele tabloului;
d declaratorul de dimensiune, sub forma:
n[,n]...
unde:

Efect:

n este o expresie ntreag (semnificnd numrul de elemente n


dimensiunea respectiv).

Specific rezervarea spaiului necesar memorrii tablourilor indicate prin


a(d), n afara spaiului direct adresabil al programului.

WRITE, scriere secvenial:


WRITE([UNIT=]u[,[FMT=]f][,ERR=e]) [list]
unde:

WRITE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
- 61 -

list list de ieire.


Efect:

Scrie una sau mai multe nregistrri pe unitatea logic u, coninnd


valorile elementelor din list. Valorile sunt convertite conform referinei
de format f (dac aceasta a fost specificat). Atunci cnd n sintax s-a
folosit ERR=e i apare o eroare la execuie, controlul va fi transferat
instruciunii executabile cu eticheta e din cadrul aceleiai uniti de
program.

Varianta cu format implicit:


WRITE([UNIT=]u,[FMT=]*[,ERR=e]) [list]
Efect:

Scrie una sau mai multe nregistrri pe unitatea logic u, coninnd


valorile elementelor din list. Valorile sunt convertite n conformitate cu
tipul elementelor din list.

Varianta fr format:
WRITE([UNIT=]u[,ERR=e]) [list]
Efect:

Scrie una sau mai multe nregistrri pe unitatea logic u, coninnd


valorile elementelor din list.

WRITE, scriere n acces direct:


WRITE([UNIT=]u,REC=r[,[FMT=]f][,ERR=e]) [list]
sau
WRITE(u'r[,[FMT=]f][,ERR=e]) [list]
unde:

WRITE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
REC cuvnt cheie pentru desemnarea nregistrrii;
r expresie ntreag (semnificnd numrul nregistrrii vizate);
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list list de ieire (cu elemente separate prin virgul).

Efect:

Scrie una sau mai multe nregistrri pe unitatea logic u, coninnd


valorile elementelor din list, ncepnd de la nregistrarea r. Valorile sunt
convertite n conformitate cu referina de format f (dac aceasta s-a
- 62 -

specificat n cadrul instruciunii). Atunci cnd n sintax s-a folosit


ERR=e i apare o eroare la execuie, controlul va fi transferat instruciunii
executabile cu eticheta e din cadrul aceleiai uniti de program.
Varianta fr format:
WRITE([UNIT=]u,REC=r[,ERR=e]) [list]
sau
WRITE(u'r[,ERR=e]) [list]
Efect:
Not:

Scrie nregistrarea r pe unitatea logic u coninnd valorile elementelor


din list.

Scrierea direct se aplic fiierelor cu organizare relativ deschise n acces direct.


A se vedea instruciunea OPEN.

WRITE, scriere indexat:


WRITE([UNIT=]u[,[FMT=]f][,ERR=e]) [list]
unde:

WRITE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
u expresie ntreag (semnificnd numrul unei uniti logice);
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list list de ieire.

Efect:

Scrie una sau mai multe nregistrri pe unitatea logic u (conectat la un


fiier indexat), coninnd valorile elementelor din list. Valorile sunt
convertite conform referinei de format f (dac aceasta a fost specificat).
Atunci cnd n sintax s-a folosit ERR=e i apare o eroare la execuie,
controlul va fi transferat instruciunii executabile cu eticheta e din cadrul
aceleiai uniti de program.

Varianta fr format:
WRITE([UNIT=]u[,ERR=e]) [list]
Efect:
Not:

Scrie una sau mai multe nregistrri pe unitatea logic u (conectat la un


fiier indexat), coninnd valorile elementelor din list.

Scrierea indexat corespunde sintactic cu scrierea secvenial.

- 63 -

WRITE, scriere intern:


WRITE([UNIT=]c,[FMT=]f[,ERR=e]) [list]
unde:

WRITE instruciunea executabil;


UNIT cuvnt cheie pentru desemnarea unitii logice;
c specificator de fiier intern;
FMT cuvnt cheie pentru referina de format;
f referin la format (specificator de format);
ERR cuvnt cheie pentru tratarea unei erori la executarea instruciunii;
e eticheta unei instruciuni executabile;
list list de ieire (elementele separate prin virgul).

Efect:

Scrie elementele din list pe fiierul intern specificat prin c, convertindule n iruri de caractere n conformitate cu specificaia de format f. Atunci
cnd n sintax s-a folosit ERR=e i apare o eroare la execuie, controlul
va fi transferat instruciunii executabile cu eticheta e din cadrul aceleiai
uniti de program.

Not:

Scrierea intern se poate utiliza pentru convertirea valorilor de tip ntreg n


caractere (chiar n caractere extinse, neimprimabile), cu condiia ca valorile s
corespund cu codul ASCII. A se vedea i instruciunea ENCODE.

3.4

DESCRIPTORII DE INTRARE/IEIRE

Descriptorii sunt specificatori de cmpuri utilizai la operaiile de citire/scriere n cadrul


instruciunii FORMAT pentru stabilirea formei valorilor din lista de intrare/ieire. Ei pot fi
folosii i fr instruciunea FORMAT, fiind citai n asemenea cazuri n lista de parametri a
instruciunilor de intrare ieire, n locul referinei de format f, sub forma: '(list)'
(unde list are semnificaia prezentat la instruciunea FORMAT). Lista descriptorilor
trebuie s corespund ca ordine i tip cu elementele din lista de intrare/ieire, n caz contrar
putnd avea loc conversii, efecte nedorite sau erori.
Descriptorii pot alctui liste complexe, repetiiile putnd fi marcate prin includerea n
paranteze rotunde precedate de un factor de repetiie opional (scalar). Dac numrul
descriptorilor specificai n list este mai mic dect numrul valorilor din lista de
intrare/ieire, se vor relua de la stnga la dreapta descriptorii din ultima parantez deschis.
n cele ce urmeaz, vom prezenta sub form tabelar descriptorii din Fortran 77 n ordine
alfabetic. Acetia se regsesc i n variantele ulterioare ale limbajului pe lng ali
descriptori mai noi bineneles, ei putnd fi grupai n dou categorii: de editare i de
control.

- 64 -

Tip
Sintax
A [n]Aw
D

[n]Dw.d

[n]Ew.d[Ee]

[n]Fw.d

[n]Gw.d[Ee]

cHa[a...]

[n]Iw

L
Z

[n]Lw
[n]Zw

Tip
Sintax
/[/...]
/

\[\...]

BN BN
BZ BZ
S

SP

SP

SS

SS

Tabel cu descriptorii de editare:


Efect
Descrie n cmpuri de tip alfanumeric (CHARACTER),
fiecare cu w poziii.
Descrie n cmpuri de numere reale extinse (DOUBLE
PRECISION sau REAL*8), fiecare cu cte w poziii din
care d sunt dup punctul zecimal.
Descrie n cmpuri de numere reale sub form exponenial,
fiecare cu cte w poziii din care d sunt dup punctul
zecimal. Opional se poate specifica prin e numrul de
caractere utilizate pentru exponent.
Descrie n cmpuri de numere reale, fiecare cu cte w poziii
din care d sunt dup punctul zecimal.
Descrie n cmpuri de numere reale extinse (DOUBLE
PRECISION sau REAL*8) sub form exponenial, fiecare
cu cte w poziii din care d sunt dup punctul zecimal.
Opional se poate specifica prin e numrul de caractere
utilizate pentru exponent.
Descrie o constant de tip Hollerith avnd lungimea c i
coninutul specificat prin a (un numr de c caractere ce
urmeaz dup litera cheie H).
Descrie n cmpuri de numere ntregi, fiecare cu cte w
poziii.
Descrie n cmpuri de tip logic, fiecare cu cte w poziii.
Descrie n cmpuri de numere hexadecimale, fiecare cu cte
w poziii.
Tabel cu descriptorii de control:
Efect
Similar cu returul de car (Enter). Determin ncheierea
rndului curent i saltul la nceputul unui rnd nou pentru
tratarea urmtoarelor valori prin descriptorii din lista
curent.
Inhib saltul la rnd nou. Urmtoarele valori formatate vor
fi tot pe rndul curent, n continuare.
Ignor spaiile dintr-un cmp numeric (Blank None).
Determin interpretarea spaiilor dintr-un cmp numeric ca
zerouri (Blank Zero).
Determin tratarea semnului valorilor numerice (Sign),
anulnd efectul descriptorilor SP i SS.
Determin afiarea semnului plus (+) la valori numerice
pozitive (Sign Plus).
Inhib semnul opional plus (+) la valori numerice pozitive
(Sign Suppressed).
- 65 -

Tip
T
TL
TR
X

Sintax
Tn
TLn
TRn
nX

Efect
Introduce n tabulatori orizontali (Tab).
Introduce n tabulatori orizontali spre stnga (Tab Left).
Introduce n tabulatori orizontali spre dreapta (Tab Right).
Sare peste n poziii (introduce n spaii)

Not:

Descriptorii de formatare / i \ nu trebuie separai neaprat prin virgul de


restul descriptorilor din list, ei nii avnd i rol de separare.

3.5

FUNCIILE INTRINSECI DIN FORTRAN 77

Funciile intrinseci sunt specifice bibliotecilor utilizate, avnd nume simbolice prestabilite
(rezervate). Printre ele exist unele ce fac parte din echiparea standard a mediului de
programare, regsindu-se n toate variantele limbajului Fortran. Numele acestor funcii sunt
rezervate, nu pot exista variabile sau tablouri de variabile care s aibe nume ce coincid cu
cele ale funciilor intrinseci. De asemenea, numele acestor funcii nu se recomand s apar
ntr-o list a unei instruciuni EXTERNAL, acest fapt ducnd la anularea definiiei lor
intrinseci. n cazul includerii numelor lor n liste ale instruciunii declarative INTRINSIC,
ele vor putea fi utilizate ca parametri la proceduri (uniti de subprograme sau de funcii
definite de utilizator).
Sintaxa general a acestora este urmtoarea:
nume(p[,p]...)
unde:

Definiie
|x|

cos(x)
sin(x)

nume nume simbolic (denumirea funciei);


p nume simbolic (al parametrului efectiv).
Tabel cu funciile intrinseci din limbajul Fortran 77:
Parametrii
Funcia
Nume
Efect
generic
Nr. Tip
Nume
Tip
R ABS
R Returneaz valoarea
ABS
1
D DABS
D absolut (modulul)
R CABS
R argumentului specificat.
I IIABS
I
I4 JIABS
I4
IABS
I IIABS
I
I4 JIABS
I4
R COS
R Returneaz valoarea
COS
1
D DCOS
D cosinusului argumentului
C CCOS
C exprimat n radiani.
R SIN
R Returneaz valoarea
SIN
1
D DSIN
D sinusului argumentului
C CSIN
C exprimat n radiani.

- 66 -

Definiie

Nume
generic

ex

EXP

ln(x)

LOG

log(x)

LOG10

SQRT

tg(x)

TAN

arccos(x)

ACOS

arcsin(x)

ASIN

arctg(x)

ATAN

arctg(x/y)

ATAN2

cosh(x)

COSH

sinh(x)

SINH

tgh(x)

TANH

rest din x/y

MOD

max(x,y,...)

MAX

MAX0
MAX1
AMAX0

Parametrii
Nr. Tip
R
1
D
C
R
1
D
C
1
R
D
R
1
D
C
1
R
D
1
R
D
1
R
D
1
R
D
2
R
D
1
R
D
1
R
D
1
R
D
I
2
I4
R
D
I
>1
I4
R
D
I
I4
R
R
I
I4

Funcia
Nume
EXP
DEXP
CEXP
ALOG
DLOG
CLOG
ALOG10
DLOG10
SQRT
DSQRT
CSQRT
TAN
DTAN
ACOS
DACOS
ASIN
DASIN
ATAN
DATAN
ATAN2
DATAN2
COSH
DCOSH
SINH
DSINH
TANH
DTANH
IMOD
JMOD
AMOD
DMOD
IMAX0
JMAX0
AMAX1
DMAX1
IMAX0
JMAX0
IMAX1
JMAX1
AIMAX0
AJMAX0

- 67 -

Efect
Tip
R
D
C
R
D
C
R
D
R
D
C
R
D
R
D
R
D
R
D
R
D
R
D
R
D
R
D
I
I4
R
D
I
I4
R
D
I
I4
I4
I4
R
R

Returneaz valoarea
exponenial a
argumentului.
Returneaz valoarea
logaritmului natural al
argumentului.
Logaritmul n baza 10 al
argumentului.
Returneaz radicalul
argumentului.
Tangenta argumentului
exprimat n radiani.
Arccosinusul argumentului
exprimat n radiani.
Arcsinusul argumentului
exprimat n radiani.
Arctangenta argumentului
exprimat n radiani.
Arctangenta argumentului
exprimat n radiani.
Cosinusul hiperbolic al
argumentului.
Sinusul hiperbolic al
argumentului.
Tangenta hiperbolic a
argumentului.
Returneaz restul mpririi
dintre argumente (cu
semnul primului argument).
Returneaz valoarea
maxim dintre elementele
cuprinse n lista de
argumente.
Valoarea maxim dintr-o
list de valori ntregi.
Maximul dintr-o list de
valori reale, ca ntreg.
Maximul dintr-o list de
valori ntregi, ca real.

Definiie
min(x,y,...)

Nume
generic
MIN

MIN0
MIN1
AMIN0
trunchiere [x] INT

IDINT
AINT
NINT
rotunjire la
cel mai
apropiat
ntreg
IDNINT
[x +
0.5*sign(x)] ANINT
x min(x,y)

DIM

IDIM
transferul
semnului
ntre dou
valori
generarea
unui numr

SIGN

ISIGN
RAN

Parametrii
Nr. Tip
I
>1
I4
R
D
I
I4
R
R
I
I4
R
1
R
D
D
D
D
R
D
R
1
R
D
D
D
D
R
D
I
2
I4
R
D
I
I4
I
2
I4
R
D
I
I4
1
I4
2
I

Funcia
Nume
IMIN0
JMIN0
AMIN1
DMIN1
IMIN0
JMIN0
IMIN1
JMIN1
AIMIN0
AJMIN0
IINT
JINT
IIDINT
JIDINT
IIDINT
JIDINT
AINT
DINT
ININT
JNINT
IIDNNT
JIDNNT
IIDNNT
JIDNNT
ANINT
DNINT
IIDIM
JIDIM
DIM
DDIM
IIDIM
JIDIM
IISIGN
JISIGN
SIGN
DSIGN
IISIGN
JISIGN
RAN
RAN

- 68 -

Efect
Tip
I
I4
R
D
I
I4
I4
I4
R
R
I
I4
I
I4
I
I4
R
D
I
I4
I
I4
I
I4
R
D
I
I4
R
D
I
I4
I
I4
R
D
I
I4
R
R

Returneaz valoarea
minim dintre elementele
cuprinse n lista de
argumente.
Valoarea minim dintr-o
list de valori ntregi.
Minimul dintr-o list de
valori reale, ca ntreg.
Minimul dintr-o list de
valori ntregi, ca real.
Returneaz valoarea
trunchiat a argumentului la
cel mai apropiat ntreg.

Valoarea real trunchiat


(cu zero la zecimale).
Returneaz valoarea
rotunjit a argumentului la
cel mai apropiat ntreg.

Valoarea real rotunjit (cu


zero la zecimale).
Returneaz valoarea
diferenei dintre cele dou
argumente, dac aceasta
este pozitiv. Altfel
returneaz zero.
Returneaz valoarea
primului argument cu
semnul celuilalt:
SIGN(y)*ABS(x)
Returneaz un numr
pseudoaleator cu distribuie
uniform ntre 0 i 1.

Definiie
conversii de
valori, ntre
diferite tipuri

Nume
generic
FLOAT
DFLOAT
IFIX
SNGL
DBLE
CMPLX

ICHAR
parte real

REAL

parte
imaginar
conjugare
produs, lungime dubl
I logic pe bit

AIMAG

SAU logic pe
bit
SAU exclusiv
pe bit
negaia logic
pe bit
deplasare
logic pe bit
lungimea
unui ir
poziia ntrun ir a unui
subir

Parametrii
Nr. Tip
I
1
I4
I
1
I4
R
1
R
D
1
I
I4
R
1
I
I4
I
1,2 I4
R
D
1
CH
C
1
I
I4
D
1
C

Funcia
Nume
FLOATI
FLOATJ
DFLOTI
DFLOTJ
IIFIX
JIFIX
SNGL
FLOATI
FLOATJ
DBLE
DFLOTI
DFLOTJ

CMPLX

ICHAR
REAL
FLOATI
FLOATJ
SNGL
AIMAG

Efect
Tip
R
R
D
D
I
I4
R
R
R
D
D
D
C
C
C
C
I
R
R
R
R
R

CONJG
DPROD

1
2

C
R

CONJG
DPROD

C
D

IAND

IOR

IEOR

NOT

ISHFT

LEN

I
I4
I
I4
I
I4
I
I4
I
I4
CH

IIAND
JIAND
IIOR
JIOR
IIEOR
JIEOR
INOT
JNOT
IISHFT
JISHFT
LEN

I
I4
I
I4
I
I4
I
I4
I
I4
I

INDEX

CH INDEX

- 69 -

Conversie ntreg n real.


Conversie ntreg n dubl
precizie.
Conversie real n ntreg prin
rotunjire.
Conversie n real (simpl
precizie).
Conversie n dubl precizie.
Conversie n valoare
complex a argumentului
(sau n parte real i
imaginar a argumentelor).
Conversie n codul ASCII.
Returneaz partea real a
argumentului.

Returneaz partea imaginar dintr-un numr complex.


Conjugatul unui complex.
n dubl precizie produsul
celor dou argumente reale.
AND logic ntre dou
argumente.
OR logic inclusiv ntre dou
argumente.
OR logic exclusiv ntre dou
argumente.
Complementul logic al
argumentului.
Deplasarea terminal logic
a biilor din argument.
Numrul de caractere din
irul considerat argument.
Poziia de nceput a
subirului n irul specificat
ca primul argument.

Definiie
comparaie
lexical

Not:

Nume
generic

Parametrii
Nr. Tip
CH
2
CH
CH
CH

Funcia
Nume
LLT
LLE
LGT
LGE

Efect
Tip
L
L
L
L

Returneaz o valoare logic


rezultat dintr-o comparaie
ntre argumente de tip
caracter.

Pentru tipul parametrilor i a funciilor s-au utilizat urmtoarele notaii:


I
I4
R
D
CH
C
L

INTEGER*2
INTEGER*4
REAL*4
DOUBLE PRECISION (REAL*8)
CHARACTER
COMPLEX
LOGICAL*2

Observaii:
Argumentul funciei logaritmice reale sau dubl precizie trebuie s fie pozitiv,
iar argumentul funciei CLOG trebuie s fie diferit de (0.,0.).
Argumentul funciei rdcin ptrat real sau dubl precizie trebuie s fie
pozitiv sau nul. Valoarea funciei CSQRT are ntotdeauna partea real mai mare
sau egal cu zero (cnd partea real a valorii funciei este zero, atunci partea sa
imaginar este mai mare sau egal cu zero).
Rezultatul funciilor ATAN i DATAN este n intervalul /2.../2, iar ale
funciilor ATAN2 i DATAN2 n intervalul ..., semnul fiind dat de primul
argument. Dac ambele argumente sunt nule atunci rezultatul este nedefinit.
Funcia MOD(x,y) fiind definit prin expresia x|x/y|*y, rezult nedefinit
dac al doilea argument este nul.
Funcia de transfer al semnului este nedefinit dac al doilea argument este nul.
Dac funcia CMPLX are un singur argument, acesta este convertit i atribuit
prii reale a valorii complexe rezultate, partea imaginar rezultnd nul.

- 70 -

CAPITOLUL 4: FORTRAN 90
4.1

TRECEREA DE LA FORTRAN 77 LA FORTRAN 90

n prezent se lucreaz la un compilator GNU Fortran 90, ceea ce impune discutarea unor
aspecte legate de scrierea programelor ntr-o manier mai modern. Dac se compar
posibilitile oferite de Fortran 77 cu cele din alte limbaje de programare (Forth, C, C++,
Pascal etc.) se observ foarte uor motivul pierderii interesului programatorilor pentru acest
limbaj. Dezvoltarea acestuia a survenit n mod firesc, ca o necesitate pentru susinerea i
adaptarea programelor deja existente pe lng realizarea de aplicaii noi, moderne i
competitive, n pas cu dezvoltarea domeniillor tiinifice conexe i cu cerinele utilizatorilor
de programe. Aspectele imputate n general versiunii consacrate a limbajului Fortran 77
sunt urmtoarele:
Lipsa facilitilor de stocare dinamic;
Lipsa tipurilor i structurilor de date definite de utilizator (exceptnd blocul
COMMON, considerat chiar revoluionar la momentul apariiei);
Uurina cu care se pot comite greeli nesesizate de compilator, n special la
apelarea procedurilor (subprograme sau funcii);
Portabilitatea uneori limitat a programelor (de multe ori coninnd caracteristici
dependente de platform, mai ales n cazul folosirii extensiilor specifice);
Structurile de control sunt slabe (de multe ori nu se pot evita instruciunile de salt
ceea ce conduce la complicarea nelegerii codului);
Reguli arhaice rmase din era cartelelor perforate (format fix pe 80 de coloane,
nume simbolice limitate la 6 caractere, etc.).
Schimbrile eseniale aduse de limbajul Fortran 90 sunt considerate a fi urmtoarele:
Format liber la scrierea sursei, concomitent cu alte mbuntiri simple;
Tablouri ca i obiecte, expresii de tablouri, asignri i funcii;
Alocare dinamic a memoriei, pointeri ce permit construcii de structuri
complexe i dinamice de date;
Tipuri de date definite de utilizator (pe lng posibilitatea definirii unor operatori
noi, operatorii existeni pot fi redefinii prin suprancrcare);
Modulul o unitate de program care poate conine date i seturi de proceduri
conexe (subprograme sau funcii). Se pot implementa clase i funcii
aparintoare pentru programarea orientat pe obiecte;
Procedurile pot fi recursive, pot avea nume generice, argumente opionale etc.;
Structuri noi de control (cum ar fi: SELECT CASE, CYCLE, EXIT) care permit
restrngerea utilizrii etichetelor i a salturilor explicite.
Programele pot fi redactate astfel ntr-o manier mai simpl, uurnd ntreinerea lor. Codul
generat poate deveni mai sigur i mai stabil deoarece compilatorul poate detecta mult mai
multe greeli n cazul utilizrii caracteristicilor de securitate avansat. Programele sunt mai
portabile, rmnnd foarte puine trsturi legate de main, nevoia de a utiliza extensii
specifice unor platforme fiind redus. Se pot scrie chiar aplicaii pentru procesare paralel,
- 71 -

asemenea operaii fiind suportate pe lng celelalte trsturi noi. n aceeai timp Fortran 77
rmne un subset acceptat pe deplin, deci noile trsturi se pot adopta gradual n funcie de
nevoile ivite. Exist ns anumite extensii obinuite ale limbajului Fortran 77 care nu au
fost incluse n varianta 90 de baz, dintre care menionm:
Formatul tabular (caracterul de tabulare <TAB> se convertete n spaii);
Declaraiile de tipul INTEGER*2 i REAL*8 (sintaxa nou este mai bun dar
mai complicat);
Constante hexadecimale, octale i binare n expresii (se admit doar n declaraiile
de tip DATA);
Structuri de date VAX (sintaxa structurilor este diferit n Fortran 90);
Expresii n cadrul instruciunilor FORMAT (se pot realiza indirect cu operaii
interne de intrare/ieire);
Anumite opiuni de la instruciunea OPEN (de exemplu ACCESS='APPEND'
schimbat cu POSITION='APPEND').
Dac se folosete varianta curat a standardului Fortran 77, atunci nu apar probleme la
compilarea dup standardul Fortran 90. Dei n Fortran 90 nu exist cuvinte strict rezervate,
sunt disponibile 75 de funcii intrinseci noi fa de versiunea anterioar a limbajului.
Problemele legate de eventuale coincidene la numele funciilor se pot evita folosind
instruciunea declarativ EXTERNAL.
4.1.1

Compilatoare

Compilatoarele Fortran 77 realizeaz n general stocarea variabilelor n mod static, deci


omiterea opiunii SAVE nu avea repercursiuni semnificative. Majoritatea sistemelor Fortran
90 stocheaz ns local variabilele, n proceduri (prin stiv), folosind alocare static doar
atunci cnd e nevoie (cum ar fi cazul variabilelor cu o valoare iniial, sau cu atributul
SAVE explicit), aa c omiterea opiunii SAVE n cadrul surselor vechi poate crea anumite
probleme.
Dei exist deja o varietate mare de compilatoare Fortran 90, att comerciale (ce-i drept mai
scumpe dect compilatoarele Fortran 77), ct i cu licen liber, necomerciale, nu toate
sunt eficiente sau stabile. Dintre cele accesibile la acest moment menionm compilatorul F
(fiind practic realizat pe baza unui subset din Fortran 90, produs de firma Imagine1,
disponibil la ora actual sub licen liber doar pentru sistemul de operare Linux, disponibil
la http://www.imagine1.com/imagine1/). Din pcate, compilatorul ELF90 (o variant mai
restrns a compilatorului Fortran 90, creat de firma Lahey, http://www.lahey.com/), la ora
actual nu mai este promovat. Dei se lucreaz la compilatorul GNU Fortran 90, va mai
trece ceva timp pn cnd acesta va fi finalizat. Predecesorul su, compilatorul GNU
Fortran 77 (g77) este poate cel mai cunoscut deocamdat, fiind disponibil pentru mai multe
platforme de lucru. Este stabil i accesibil dar, dei suport complet standardul Fortran 77,
nu accept dect cteva dintre trsturile noi introduse prin limbajul Fortran 90. Exist i
traductoare ntre diferite versiuni ale limbajului Fortran (cum ar fi cel creat de compania
Pacific-Sierra Research, http://www.psrv.com/, pentru a traduce codul surs din Fortran 90
n Fortran 77, n scopul compilrii cu g77).
- 72 -

4.1.2

Diferene formale

Sursa unui program poate fi scris n Fortran 90 att n form liber, ct i n form fix,
ns cele dou formate nu pot fi amestecate. n general compilatoarele consider fiierele
surs cu extensia .F90 ca fiind implicit n form liber. Liniile din cadrul sursei pot avea o
lungime maxim de 132 de caractere (incluznd i spaiile). n cazul unor rnduri mai lungi
ntreruperea se va marca prin caracterul ampersand (&) scris la captul rndului incomplet.
Pe rndul incomplet, dup marcajul de continuare se pot scrie comentarii (cu condiia s nu
se depeasc cele 132 de caractere n total). Dac prin ntreruperea rndului s-a desprit
un nume simbolic sau o constant, atunci urmtoarea linie (rndul de continuare) trebuie s
nceap cu caracterul &. Cei ce doresc s scrie cod valabil n ambele formate (se poate
dovedi util folosind instruciunea INCLUDE att pentru surse vechi ct i pentru surse de
tipul Fortran 90), pot marca continuarea unui rnd dup coloana 72 (se va considera
comentariu n formatul vechi) n acelai timp scriind caracterul & i n coloana 6 din rndul
de continuare.
n formatul liber spaiile (caracterele blank) sunt semnificative, ele nu pot aprea n nume
simbolice sau constante (cu excepia valorii citate a constantelor de tip caracter), avnd rol
de separare n anumite cazuri. La scrierea codului surs se pot folosi att litere mici ct i
litere mari (mrimea caracterelor conteaz doar n cadrul valorii constantelor de tip
caracter). Numele simbolice pot avea lungimi de pn la 31 de caractere, putnd conine pe
lng caracterele alfanumerice i caracterul de subliniere (_). Instruciunile scrise pe un
rnd comun trebuie s fie separate prin caracterul punct-virgul (;). Comentariile se marcheaz cu semnul exclamrii n fa, ele putnd ncepe oriunde n cadrul unui rnd (chiar i
dup o instruciune, dar n cazul formatului fix marcajul nu poate fi n coloana 6). Constantele de tip caracter pot fi citate ca i coninut prin delimitarea lor fie cu caracterul apostrof
(') fie folosind caracterul ghilimele ("). Operatorii relaionali pot fi scrii att sub forma
veche, ct i sub forma nou (a se vedea tabelul corespunztor din capitolul precedent).
4.1.3

Specificri noi

Declaraia IMPLICIT NONE este comun n Fortran 90, fiind recomandat i pentru
verificarea mai temeinic la compilare. Declaraia de tipul DOUBLE PRECISION este doar
un caz special al declaraiei de tip REAL, n consecin i datele de tip complex pot fi
reprezentate n mod firesc pe lungime dubl (DOUBLE COMPLEX). Dei se sprijin n
continuare instruciunea INCLUDE, o varianta nou: MODULE, ofer mai multe faciliti.
Declaraiile de tip accept o sintax nou (cu separator alctuit din dou puncte duble ntre
declaraii i list), permind definirea simultan a tuturor atributelor pentru elementele unei
liste, precum i iniializarea simultan, de exemplu:
INTEGER, DIMENSION(10,10) :: x, y, z
REAL, PARAMETER :: pi = 3.12159, ud = 180.0/pi
CHARACTER(LEN=12) :: fis = "intrare1.dat"

Declaraia DATA devine astfel aproape redundant (rmne util la iniializarea unor zone
pariale de tablou, a unor constante hexadecimale etc), iar atributul SAVE este aplicat

- 73 -

implicit asupra tuturor variabilelor cu valori iniiale (indiferent dac ele sunt declarate prin
tip sau DATA). Evoluia sintaxei permite alctuirea unor adevrate expresii de specificare.
Atributul INTENT permite declararea inteniei de folosire a unor argumente formale
(valorile admise fiind: IN, OUT i INOUT).
Declaraiile de tip LOGICAL*1, INTEGER*2, sau REAL*8 erau extensii obinuite ale
limbajului Fortran 77, dar ele nu se regsesc n Fortran 90. Aceast variant mai nou a
limbajului dispune de cinci tipuri intrinseci de valori (tip caracter, logic, ntreg, real i
complex) admind diferite feluri (specificate explicit prin atributul KIND) ale acestor
tipuri. Pentru valorile de tip complex i real exist dou feluri predefinite (al doilea
corespunznd reprezentrii pe lungime dubl). Felul se poate specifica printr-o valoare
ntreag, corespunztoare teoretic lungimii de reprezentare (standardul limbajului nu
precizeaz semnificaia acestei valori ntregi), cum ar fi de exemplu INTEGER(2) n loc
de INTEGER*2. Pentru a oferi o flexibilitate i implicit o portabilitate mrit programelor,
exist dou funcii intrinseci noi: SELECTED_INT_KIND (care selecteaz o valoare
ntreag pentru numrul minim de cifre zecimale dorite) i SELECTED_REAL_KIND
(care selecteaz pentru valori reale precizate numrul cifrelor zecimale i domeniul pentru
exponent). Astfel:
INTEGER, PARAMETER :: &
scurt = SELECTED_INT_KIND(4), &
lung = SELECTED_INT_KIND(9), &
dublu = SELECTED_REAL_KIND(15, 200)

!
!
!
!

intregi cu >= 4 cifre


intregi cu >= 9 cifre
valori reale cu 15 cifre si
cu domeniul 10**200

INTEGER(scurt) :: poza(1024,768)
INTEGER(lung) :: numar
REAL(dublu) :: tablou(20,20)

Cea mai bun metod este de a include definiiile parametrilor de fel (ca cele de mai sus)
ntr-un modul care s fie utilizat de-a lungul programului. La rndul lor, i constantele pot
avea ataate atribute de fel, acolo unde corespondena felului este cerut (de exemplu n
cadrul parametrilor unei proceduri). Iat un exemplu cu apelarea unui subprogram, folosind
pe post de parametri efectivi valori cu specificaie de fel (acestea fiind desprite de
constante prin caracterul _):
CALL subprogram( 3.14159265358_dublu, 12345_lung, 42_scurt)

Menionm c felul parametrilor (dublu, lung, scurt) din acest apel este cel definit n
exemplul anterior.
Funcia KIND returneaz la rndul su parametrul de fel al oricrei variabile, de exemplu:
WRITE(*,*) " felul pentru dubla precizie este ", KIND(0d0)

n principiu, regula de fel poate fi extins i la valorile de tip caracter, sistemele Fortran
putnd suporta seturi de caractere pe 16 bii (cum este setul Unicode).

- 74 -

4.2

STRUCTURI DE CONTROL NOI, INTRODUSE N FORTRAN 90

n varianta anterioar a limbajului Fortran nu exista instruciune corespunztoare


reprezentrii primitivei alternative generalizate. Pentru traducerea unei asemenea structuri
din pseudocod sau dintr-o schem logic era nevoie fie de un set de instruciuni de salt
calculate cu multitudinea de etichete corespunztoare, fie de un set de instruciuni IF (ELSE
IF) care rezulta destul de complex. n Fortran 90, asemenea structuri se pot scrie foarte
uor prin utilizarea instruciunii SELECT CASE. Iat un exemplu preluat din literatura de
specialitate de limb englez, referitor la alegerea indicelui corespunztor unui numr de
ordine pentru zilele unei luni:
SELECT CASE(numar_zi)
CASE(1, 21, 31)
! cazul
indice = st
CASE(2, 22)
! cazul
indice = nd
CASE(3, 23)
! cazul
indice = rd
CASE(4:20, 24:30)
! cazul
indice = th
CASE DEFAULT
! cazul
indice = ??
WRITE(*,*) data invalida: ,
END SELECT
WRITE(*, "(I4,A2)") numar_zi, indice

numerelor ce se termin cu unu


numerelor terminate cu doi
numerelor terminate cu trei
celorlaltor numere
implicit, cu valoare invalida
numar_zi

Expresiile utilizate pot fi de tip ntreg sau caracter, ns domeniile precizate la instruciunile
CASE nu pot s se suprapun sau s se intersecteze. Aceste domenii trebuie s fie foarte
clar precizate. Tratarea cazului implicit (CASE DEFAULT) este opional.
i n ceea ce privete instruciunile de ciclare/repetare s-au fcut mbuntiri semnificative. Instruciunea DO a fost actualizat n Fortran 90, eticheta ce marca sfritul modulului
de repetat nemaifiind necesar, ea fiind nlocuit prin instruciunea END DO. n plus,
instruciunea CYCLE va determina pornirea unui ciclu, iar instruciunea EXIT permite
ieirea din ciclu nainte de atingerea marcajului terminal (END CYCLE).
Exist i posibilitatea specificrii unui ciclu DO nedefinit, adic fr un contor explicit, n
acest caz ieirea din ciclu trebuie asigurat prin EXIT. Se poate folosi i instruciunea DO
WHILE (corespunztoare unei primitive repetitive pre-condiionate), aceasta va avea efect
similar cu instruciunea DO nedefinit, dup cum se poate observa i n urmtorul exemplu:
DO WHILE( ABS(x - xmin) > 1.0e-5)
CALL itereaza(x, xmin)
END DO
DO
IF( ABS(x - xmin) <= 1.0e-5) EXIT
CALL itereaza(x, xmin)
END DO

- 75 -

! varianta cu ciclu DO-WHILE


!... sau
! aceeasi ciclu, cu DO nedefinit

Pentru a facilita citirea i nelegerea programelor se pot boteza anumite structuri (cicluri
DO, blocuri IF, structuri CASE) n cazul n care sunt prea complexe i ar necesita EXIT
(sau CYCLE) suplimentar. Aceste nume ns nu pot fi folosite ca etichete pentru
instruciunile de salt GO TO. Iat un mic exemplu, cu numele exterior i interior pentru
dou cicluri:
!...
suma = 0.0
exterior: DO j = 1,ny
! suma pana la obtinerea lui zero
interior: DO i = 1,nx
IF(tablou(i,j) == 0.0) EXIT exterior
suma = suma + tablou(i,j)
END DO interior
END DO exterior

Etichetele marcheaz de regul instruciunile la care se ajunge printr-un salt. Multitudinea


salturilor poate complica claritatea programelor scrise, din acest motiv se recomand
utilizarea structurilor mai avansate acolo unde se poate. Folosirea etichetelor poate fi uor
evitat n urmtoarele situaii:
folosirea ciclurilor DO structurate (cu END DO), tratarea excepiilor putndu-se
realiza prin instruciunile EXIT sau RETURN;
nlocuirea instruciunilor de salt (GO TO) calculat prin structuri SELECT CASE;
citarea listei de descriptori n locul specificrii de format la instruciunile de
citire sau scriere. De exemplu:
CHARACTER(LEN=2) :: raspuns
!...
WRITE(*,"(A)") "raspundeti cu DA sau NU :"
READ(*,(A2)) raspuns

Funciile se puteau defini n Fortran 77 n dou moduri: printr-o singur expresie (pe o
linie) sau ca modul extern (subprogram FUNCTION). n Fortran 90 exist ns posibilitatea
declarrii unor proceduri interne, ntr-o manier structurat, ca n exemplul urmtor:
SUBROUTINE arie_poligon(laturi)
!
IMPLICIT NONE
!
!...
aria1 = arie_triunghi(a, b, x)
!...
aria2 = arie_triunghi(x, c, d)
!...
CONTAINS
!
REAL FUNCTION arie_triunghi(a, b, c) !
REAL, INTENT(IN) :: a, b, c
REAL :: s
!
s = 0.5 * (a + b + c)
arie_triunghi = sqrt(s * (s-a) * (s-b)
END FUNCTION arie_triunghi
!
SUBROUTINE inclus
!
!...
END SUBROUTINE inclus
!
END SUBROUTINE arie_poligon

- 76 -

o procedura externa
valabil peste tot

urmeaza procedura interna ...


procedura interna
variabila locala in functie
* (s-c))
sfarsitul procedurii interne
o alta procedura interna
sfarsitul procedurii

Astfel, specificarea funciilor nu mai este restrns la doar o singur linie. Procedurile
interne pot fi i subprograme (nu numai funcii). La fel ca n exemplul precedent, ele
trebuie s fie precedate de instruciunea declarativ CONTAINS care totodat marcheaz i
finalul descrierii procedurii externe gazd. n cadrul unei uniti de program se pot declara
oricte proceduri interne, care la rndul lor se pot apela i reciproc, ns nu se admite
combinarea (intersectarea) lor. Folosirea declaraiilor END SUBROUTINE i END FUNCTION sunt obligatorii pentru a marca finalul specificaiilor, precizarea numelor procedurilor dup aceste instruciuni fiind opional (se recomand doar pentru claritatea sursei).
Procedurile interne au acces la toate variabilele modulului gazd (cu excepia cazurilor n
care conin declaraii cu nume identice), dar acest aspect nu este valabil i invers.
4.3

TABLOURI DE DATE

Tablourile au o semnificaie i un rol mai extins ca n varianta anterioar a limbajului,


devenind obiecte de prim clas asupra crora se pot aplica operaii prin expresii generice.
Operaiile vor fi efectuate pentru fiecare element al tablourilor (fr a scrie cicluri explicite)
cu condiia ca tablourile s fie conforme (form i dimensiuni compatibile). Dac apar
valori scalare ntr-o expresie, ele se vor aplica prin operatorii specificai, pe fiecare element
al tablourilor vizate. De exemplu:
REAL :: scalar, vector(123), tablou(4,5,6)
CHARACTER(LEN=1), PARAMETER :: zi(0:6) = (/D,L,M,M,J,V,S/)
REAL, DIMENSION(768,1024) :: img, fundal, expunere, rezultat, std_err
!...
std_err = 0.0
! toate elementele din acest tablou primesc valoarea
! nul
rezultat = (img - fundal) / expunere
! expresie cu tablouri
fundal = 0.1 * expunere + 0.125
! expresie cu tablouri i scalari
!...

Noiunea de zon sau seciune desemneaz elemente de tablou referite prin indici de poziie
sau un domeniu definit prin elementele de tablou componente. Declararea acestor zone se
poate face prin numele tabloulului de care aparin i ele pot fi iniializate cu valori cuprinse
ntr-o list (ca n exemplul de mai sus, la tabloul zi). Fiecare zon sau element al tabloului
motenete proprietile corespunztoare de tip INTENT, PARAMETER i TARGET ale
tabloului, ns fr a moteni atributul POINTER. La definirea seciunilor nu trebuie s ne
referim neaprat la zone contigue, fiind permise i suprapuneri de elemente ntre diferite
zone. De exemplu:
! img(2:101,301:500)
! b(1:10:2)

este o referinta la o zon de 100x200 din tabloul img


este o referin la b(1), b(3), b(5), b(7) i b(9)
!...
a(2:10) = a(1:9)
! translatare n sus cu un element
b(1:9) = b(3:11)
! translatare n jos cu doua elemente

Bineneles, n asemenea cazuri compilatorul trebuie s genereze codul corespunztor, fr


a ncurca valorile referite. Se admite i folosirea unor zone de mrime zero, de exemplu:

- 77 -

b(3:2), primul indice fiind mai mare dect al doilea fr ca s fie precizat un pas negativ.
Se admite folosirea tablourilor unidimensionale (vectorilor) pe post de indici de tablouri.
Pentru a crea i atribui valori tablourilor unidimensionale (i tablourilor de constante) se pot
utiliza i constructori de tablouri, alctuind chiar expresii. Pentru tablouri cu mai multe
dimensiuni, unde constructorii nu pot fi utilizai, se recomand folosirea funciei
RESHAPE (al doilea argument al funciei specific forma dorit). Iat cteva exemple:
INTEGER :: lista(2,3) = &
! folosirea functiei RESHAPE:
RESHAPE( (/ 11, 12, 21, 22, 31, 32 /), (/2,3/))
!...
zona = (/ 3.14, x, 2.33, y, 3.51 /) ! utilizarea constructorilor,
indice = (/ (REAL(i), i = 1,10) /)
! ciclu implicit in cadrul
! constructorului de tablou,
! exemplu cu folosirea unui vector pe post de indice
INTEGER :: vector(4)
! vectorul ce va fi folosit ca indice
REAL :: tabel(100)
! tabloul declarat
vector = (/ 33, 11, 12, 13 /) ! initializarea vectorului (indicelor)
WRITE(*,*) tabel(vector)
! se vor scrie doar elementele de pe
! pozitiile 33, 11, 12 si 13 din
! tabloul tabel.

Indicii sub form de vectori pot fi utilizai n partea stng a unei asignri/atribuiri doar
dac nu apar valori repetate n lista cu indici (altfel un element ar trebui s fie asociat la
dou valori diferite). O seciune de tablou cu indice sub form de vector nu poate fi int
ntr-o instruciune de atribuire cu pointeri (a se vedea subcapitolul 4.10).
n Fortran 90 exist o serie de funcii intrinseci noi, dintre acestea prezentm sub form
tabelar cele referitoare la tablouri:
Tabel cu funcii intrinseci noi pentru tratarea tablourilor de date:
Funcie
Efect
ALL(ablon [, DIM=d])
Are valoarea .TRUE. dac toate
elementele filtrate cu ablon au aceast
valoare.
ANY(ablon [, DIM=d])
Are valoare .TRUE. dac cel puin un
element filtrat cu ablon are aceast
valoare.
COUNT(ablon [, DIM=d])
Returneaz numrul elementelor cu
valoarea .TRUE. din lista generat de
ablon.
CSHIFT(tablou, pas [, DIM=d])
Translatare circular a elementelor din
tablou (cu pasul pas).
EOSHIFT(tablou, pas [, DIM=d])
Translatare liniar (End-Off) a elementelor.
MATMUL(mata, matb)
Produsul matriceal dintre mata i matb.
MAXLOC(tablou[, ablon])
Locaia (poziia) elementului cel mai mare.
MINLOC(tablou[, ablon])
Locaia (poziia) elementului cel mai mic.
MAXVAL(tablou[, DIM=d, ablon])
Valoarea cea mai mare din tablou.
MINVAL(tablou[, DIM=d, ablon])
Valoarea cea mai mic din tablou.

- 78 -

Funcie

Efect
Combin tablourile conform ablonului
(utiliznd elementele corespunztoare din
sursaT pentru valorile .TRUE., i din
sursaF pentru valorile .FALSE. din
ablon).
mpacheteaz elementele tabloului conform
ablonului pasndu-le tabloului rezultat.
Produsul valorii elementelor din tablou.
Suma valorii elementelor din tablou.
Transpusa matricei (a tabloului
bidimensional matrice).

MERGE(sursaT, sursaF, ablon)

PACK(tablou, ablon [,rezultat])


PRODUCT(tablou[, DIM=d, ablon])
SUM(tablou[, DIM=d, ablon])
TRANSPOSE(matrice)

Meniune: funciile MAXLOC i MINLOC aplicate pe un vector vor returna un tablou cu


un element, ceea ce nu trebuie confundat cu un scalar (nu sunt identice).
Iat i cteva exemple pentru ilustrarea funciilor prezentate:
IF( ANY( a /= b)) THEN ...

!
!
!
!
!

compararea tablourilor a si b pentru


a vedea daca sunt identice (conditia
fiind pusa sub forma: DACA ORICE
element din A DIFERA fata de elementul corespunzator din B ATUNCI...

! ... un alt exemplu:


REAL :: tablou(2,3)
! declararea unui tablou de forma
tablou=(/ 1, 3, 5, 2, 4, 6 /) !
1 3 5
!
2 4 6
! si folosirea functiei SUM va returna:
SUM(tablou)
! suma tuturor elementelor: 21
SUM(tablou, DIM=1)
! suma dupa prima dimensiune,
! adica pe randuri: (/ 9, 12 /)
SUM(tablou, DIM=2)
! suma dupa a doua dimensiune,
! adica pe coloane: (/ 3, 7, 11 /)
! si inca un exemplu, pentru
! calculul variantzei intr-un tablou, ignorand elementele nule:
media = SUM(x, MASK= x /= 0.0) / COUNT(x /= 0.0)
variantza = SUM((x-media)**2, MASK= x /= 0.0) / COUNT(x /= 0.0)

Cnd unele elemente ale unui tablou trebuie tratate diferit, utilizarea structurii WHERE
poate fi foarte util, iat de exemplu:
WHERE(x /= 0.0)
inversa = 1.0 / x
ELSEWHERE
inversa = 0.0
END WHERE

Exist i o form pe o singur linie, iat de exemplu:


WHERE(tablou > 100.0) tablou = 0.0

- 79 -

4.4

ALOCAREA DINAMIC A MEMORIEI

Exist trei modaliti distincte pentru alocarea dinamic a memoriei la tablouri: automat,
prin declarare de tablou alocabil (ALLOCATABLE) i tablou pointer.
Tablourile automate sunt considerate ca variabile locale, find permise doar n funcii i
subprograme (declarate corespunztor). Limitele lor sunt stabilite n momentul n care se
face apel sau referire la modulul n care au fost declarate. Iat un exemplu:
SUBROUTINE finete(npct, spectrum)
IMPLICIT NONE
INTEGER, INTENT(IN) :: npct
REAL, INTENT(INOUT) :: spectrum
REAL :: zona(npct), mai_mare(2*npct)

! tablouri automate

Limitele dimensiunilor pot fi i expresii de tip ntreg, alctuite din variabile definite i
accesibile la momentul respectiv. n cadrul procedurii tablourile astfel definite se comport
n general la fel cu celelalte tablouri, pot fi utilizate i de ctre procedurile subordonate
incluse, dar n momentul n care controlul revine la nivelul procedurii gazd tablourile
devin nedefinite. Un tablou automat nu poate fi iniializat i nu poate fi folosit nici pentru a
salva valori de la un apel la altul. Cele mai multe sisteme stocheaz asemenea tablouri n
stiv (unele sisteme Unix nu aloc prea mult spaiu pentru stiv).
Tablourile alocabile sunt mai des utilizate deoarece dimensiunile lor se pot fixa n orice
moment (implicit ncep cu 1), doar rangul (numrul dimensiunilor) trebuie declarat n avans
(marcnd cu caracterul : fiecare dimensiune):
REAL, ALLOCATABLE :: vector(:), matrice(:,:), trei_d(:,:,:)
!...
ALLOCATE(vector(123), matrice(0:9,-2:7))
! declararea dimensiunii
!...
DEALLOCATE(matrice, vector)
! eliberarea memoriei

Tablourile alocabile pot fi pasate procedurilor subordonate fr probleme, ns nainte de


terminarea procedurii n care au fost declarate ele trebuie dealocate (folosind instruciunea
DEALLOCATE, ca n exemplul de mai sus) pentru a evita problemele de scurgeri de
memorie. Dac unui asememnea tablou i s-au fixat dimensiunile, acestea nu pot fi
modificate (doar printr-o nou alocare dup o dealocare prealabil). Nu se admite alocarea
dubl a aceluiai tablou, se poate folosi funcia intrinsec ALLOCATED pentru a evita
asemenea situaii:
IF(ALLOCATED(tablou)) THEN
DEALLOCATE(tablou)
END IF
ALLOCATE(tablou(1:nouadimensiune))

! utilizarea functiei
! dealocare daca se impune
! realocare

Pentru verificarea succesului alocrii spaiului n cazul unor asemenea tablouri, cu


dimensiuni extinse, se poate apela la interogarea unei variabile de stare care n mod normal
returneaz valoare nul, iar n cazul unei erori de alocare va returna o valoare diferit:

- 80 -

ALLOCATE(tablou_imens(1:npct), STAT=ierror)
IF(ierror /= 0) THEN
WRITE(*,*)"Eroare la incercarea de alocare pentru tablou_imens "
STOP
END IF

n cazul unor asemenea erori se recomand aplicarea unui alt algoritm, cu nevoi mai reduse
de memorie dac e posibil, altfel programul se va termina neateptat.
Un tablou alocabil nu poate fi specificat ntr-o instruciune COMMON, DATA,
EQUIVALENCE sau NAMELIST. Poate ns avea atributul SAVE, ceea ce-i furnizeaz un
caracter global n cadrul modulului.
Tablourile pointer sunt a treia modalitate de alocare dinamic. Un pointer nu conine date,
dar indic ctre un scalar sau un tablou n care sunt stocate date. Poate fi considerat deci, ca
o referin ctre o referin. Dat fiind natura lui, nu are spaiu de stocare de la nceput
alocat, ci doar la execuia programului. Un tablou alocabil nu poate fi transmis unei
proceduri dac nu a fost alocat n prealabil, dar cu un tablou pointer se poate realiza acest
lucru. Iat un exemplu:
PROGRAM pdemo
IMPLICIT NONE
REAL, POINTER :: ptablou(:)
! declararea unui tablou pointer
OPEN(UNIT=1, FILE=fisier, STATUS=old)
CALL citire(1, ptablou)
WRITE(*,*)tablou de , SIZE(tablou), puncte:
WRITE(*,*) ptablou
DEALLOCATE(ptablou)
STOP
! STOP-ul este optional
CONTAINS
SUBROUTINE citire(unitate, x)
INTEGER, INTENT(IN) :: unitate
REAL, POINTER :: x(:)
! pointer nu poate avea INTENT
INTEGER :: npuncte
READ(unitate) npuncte
! numarul punctelor de citit
ALLOCATE(x(1:npuncte))
! alocarea spatiului
READ(unitate) x
! citirea intregului tablou
END SUBROUTINE citire
END PROGRAM pdemo

Se poate observa din exemplul de mai sus, c la declararea tablourilor pointer se aplic o
sintax similar cu cea de la tablourile alocabile (se marcheaz cu caracterul : poziiile
dimensiunilor sau, altfel spus, rangul tabloului). Exemplul prezentat este simplu pentru c
prezint o procedur intern, deci compilatorul se va descurca foarte uor cunoscnd toate
detaliile interfeei la traducerea apelului subprogramului (la transmiterea unui pointer ctre
o procedur, se cere o asemenea interfa explicit, noiune ce va fi prezentat n
subcapitolul urmtor).

- 81 -

4.5

MODULE I INTERFEE

n Fortran 90 exist patru tipuri de uniti de program:


1.
2.
3.
4.

Programul principal (Main care ncepe de regul cu declaraia PROGRAM).


Proceduri externe sau subprograme (ce ncep fie cu declaraia SUBROUTINE, fie cu
FUNCTION).
Uniti cu blocuri de date (specificai prin declaraia BLOCK DATA).
Module (specificai prin declaraia MODULE) ce pot conine orice combinaie a
urmtoarelor elemente:
- definiii de constante;
- definiii de date derivate (structuri de date);
- declaraii de stocare;
- proceduri (subprograme i funcii).

Un modul poate fi accesat n orice unitate de program prin instruciunea USE (inclusiv
dintr-un alt modul). Instruciunea USE trebuie s precead celelalte declaraii, ea trebuie s
fie prima dup specificaia de identificare a unitii de program. Dei modulul poate fi
coninut ntr-un fiier separat sau n aceeai fiier cu celelalte uniti de program, el trebuie
compilat nainte de unitatea care conine referina la el. Cele mai multe compilatoare
suport compilarea separat a modulelor, genernd fiiere cu extensia .mod (sau ceva
similar) din ele. Din acest punct de vedere, utilizarea modulelor prin instruciunea USE s-ar
asemna cu inserarea prin instruciunea INCLUDE, dar de fapt utilizarea modulelor este o
facilitate mai performant din cauza procedurilor de modul.
Un modul ncepe de regul cu seciunea datelor urmat de o specificaie CONTAINS (dac
conine vreo procedur), dup care urmeaz descrierile procedurilor de modul. Aceste
proceduri de modul au acces direct la toate definiiile de date i specificaii de stocare prin
asociere. Permit ncapsularea datelor i a mulimii de proceduri ce opereaz cu aceste date
sau ce folosesc zona de stocare pentru schimb de valori (intercomunicare). Urmtorul
exemplu prezint un modul ce trateaz ieirea pe un videoterminal sau ntr-o fereastr de
tipul X-term (prin secvene escape, similare cu cele din ANSI.SYS sub DOS):
MODULE vt_mod
IMPLICIT NONE
CHARACTER(1), PARAMETER :: escape =
INTEGER, SAVE :: latime_ecran = 80,
CONTAINS
SUBROUTINE goleste

! specificarea modulului
! valabil intregului modul
achar(27)
inaltime_ecran = 24

! Goleste ecranul si muta


! cursorul in stanga sus
CALL afiseaza( escape // "[H" // escape // "[2J")
END SUBROUTINE goleste
SUBROUTINE fa_latime(latime)
! seteaza noua latime de ecran
INTEGER, INTENT(IN) :: latime
! la latimea dorita (80 sau 132)
IF(latime > 80) THEN
CALL afiseaza( escape // "[?3h" ) ! comutare la 132 de coloane
latime_ecran = 132
ELSE

- 82 -

CALL afiseaza( escape // "[?3l" ) ! comutare la 80 de coloane


latime_ecran = 80
END IF
END SUBROUTINE fa_latime
SUBROUTINE ia_latime(latime)
INTEGER, INTENT(OUT) :: latime
latime = latime_ecran
END SUBROUTINE ia_latime

! returneaza latimea ecranului


! (de 80 sau 132 de caractere)

SUBROUTINE afiseaza(rand)
! doar pentru uz intern
INTEGER, INTENT(IN) :: rand
WRITE(*, "(1X,A)", ADVANCE="NO") rand
END SUBROUTINE afiseaza
END MODULE vt_mod

Pentru a folosi acest modul, la nceputul sursei trebuie inserat doar:


USE vt_mod

dup ce exemplul de mai sus a fost compilat, fiind transformat ntr-un fiier imagine obiect
(cu extensia .mod).
Toate variabilele din modul sunt accesibile n mod implicit tuturor programelor care
utilizeaz modulul. Acest aspect ns poate fi deranjant: de multe ori, procedurile de modul
oferind toate funciunile necesare de acces, este preferabil ca utilizatorii s nu se amestece
cu aspectele interne. Pentru a schimba accesibilitatea generic de tip PUBLIC a numelor
simbolice dintr-un modul se poate utiliza specificaia PRIVATE n cadrul acestuia. Uneori
ns aceast soluie nu este suficient: se poate ntmpla ca un modul s conin nume de
proceduri sau de variabile care s intre n conflict cu cele alese deja de un utilizator. Pentru
asemenea situaii exist dou soluii. Dac nu se dorete utilizarea ntregului modul, din
motivul evitrii conflictului dintre unele nume folosite, se poate specifica o list coninnd
doar entitile publice sau identificatorii generici dorii a fi utilizai din modul, prin
combinaia USE ONLY, ca de exemplu:
USE vt_mod, ONLY: goleste

Cealalt soluie ar fi redenumirea entitii al crei nume deranjeaz (crearea unui alias
pentru numele simbolic al acesteia). De exemplu, dac numele ia_latime din modulul
prezentat mai sus ne creeaz probleme, putem proceda n felul urmtor:
USE vt_mod, e_lata => ia_latime

i astfel numele e_lata va nlocui temporar numele ia_latime n cadrul modulului vt_mod.
Modulele permit ncapsularea unei structuri de date mpreun cu mulimea procedurilor ce-l
manipuleaz, ceea ce n programarea orientat obiect nseamn c ele pot conine o clas i
metodele acesteia.
Atunci cnd o procedur de metod este apelat, se spune c este vorba de o interfa
explicit, ceea ce nseamn c compilatorul poate verifica consistena argumentelor actuale
efective i fictive. Aceasta se consider o trstur foarte valoroas deoarece n Fortran 77

- 83 -

asemenea interfee nu se puteau verifica i erorile erau obinuite din aceast cauz. Din
acest punct de vedere, utilizarea modulelor se dovedete mai avantajoas dect folosirea
blocurilor comune (COMMON), a blocurilor de date (BLOCK DATA) sau a punctelor de
intrare (ENTRY).
Modulele furnizeaz un nivel structural suplimentar n proiectarea programelor, putnd
clasifica nivelurile n ordine descresctoare n felul urmtor: programe; module; proceduri;
instruciuni.
Interfeele explicite derivate din module permit utilizarea multor faciliti avansate, cum ar
fi: tablourile de pointeri cu form presupus, argumententele opionale, operatorii definii
de ctre utilizator, numele generice etc. Exist ns i cteva dezavantaje:

fiecare modul trebuie compilat nainte de unitile de program apelante;


necesit atenie mrit;
scrise ntr-un singur fiier, modulele trebuie s precead programul principal;
dac un modul este modificat, vor trebui recompilate toate unitile de program
apelante ceea ce poate conduce la consum excesiv de timp;
un modul rezult de regul ntr-un singur fiier imagine obiect, reducnd
avantajele bibliotecilor imagine obiect, putnd conduce la fiiere executabile de
dimensiuni mari.
O interfa explicit nseamn c argumentele fictive ale procedurii sunt vizibile
compilatorului n momentul traducerii instanei de apel ctre procedura respectiv. O
interfa se consider explicit atunci cnd:
se apeleaz o procedur de modul de ctre o unitate de program sau de ctre o
alt procedur din cadrul aceluiai modul;
se apeleaz o procedur intern de ctre o unitate gazd sau de ctre orice alt
procedur din aceeai gazd;
se apeleaz o funcie intrinsec (intern);
se specific un bloc de interfa explicit;
o procedur recursiv se autoapeleaz direct sau indirect.
Specificarea unu bloc de interfa are urmtoarea form:
INTERFACE [specificator_generic]
[corp interfa]
[MODULE PROCEDURE list_nume]
END INTERFACE [specificator_generic]

Un bloc de interfa poate fi specificat i n cadrul unui modul, pentru a facilita utilizarea
acestuia. n cazul n care se folosesc biblioteci existente din Fortran 77, se recomand
crearea unui modul care s conin toate interfeele de proceduri (exist chiar programe de
conversie i generare pentru asemenea situaii).

- 84 -

4.6

PROCEDURI N FORTRAN 90

n cazul folosirii tablourilor pe post de parametri transferai ntre proceduri, se recomand


utilizarea tablourilor cu form presupus. Un asemenea tablou este un argument formal care
i asum mrimea tabloului din postura argumentului efectiv, ns rangul (i implicit
dimensiunile) poate s fie diferit fa de tabloul asociat (din postura argumentului efectiv).
De aici rezult c la specificarea unui asemenea tablou (cu form presupus) se specific
rangul, marcnd prin caracterul : fiecare dimensiune. Forma efectiv va fi luat de fiecare
dat doar n momentul realizrii apelului (prin argumentele efective). Limita inferioar a
indicilor este implicit 1, ea nu trebuie s corespund neaprat cu cea a tablourilor efective
din apel, ca atare funciile intrinseci LBOUND i UBOUND nu vor putea servi informaii
adiionale.
Dac exist o interfa implicit, se pot folosi cuvinte cheie n loc de notaiile poziionale
uzuale. De asemenea, toate funciile intrinseci pot fi apelate prin cuvinte cheie. Utilizarea
apelurilor prin cuvinte cheie se poate dovedi util cnd argumentele opionale se omit:
INTEGER :: vector(8)
CALL DATE_AND_TIME(VALUES=vector)

n cadrul unui apel se pot amesteca cuvintele cheie cu argumente poziionale, dar acestea
din urm trebuie s fie n fa. Argumente opionale pot fi furnizate n proceduri scrise de
utilizator, ns testarea existenei lor (prin funcia intrinsec PRESENT) este esenial
nainte de utilizarea lor (cu excepia cazului unui alt apel al unei proceduri cu un argument
opional):
SUBROUTINE scrie_text(sir, ngol)
CHARACTER(*), INTENT(IN) :: sir
INTEGER, INTENT(IN), OPTIONAL :: ngol
INTEGER :: localgol
IF(PRESENT(ngol)) then
localgol = ngol
ELSE
localgol = 0
END IF
! ...
END SUBROUTINE scrie_text

! linie de text,
! linii goale inainte,
! stocare locala

! valoare implicita,

Apelurile posibile din cadrul diverselor uniti de program, ctre subprogramul de mai sus,
pot arta n felul urmtor:
CALL scrie_text("titlu document")
CALL scrie_text("22 Decembrie 1989", 3)
CALL scrie_text(ngol=5, sir="un alt rand")

! al doilea argument omis


! in alta ordine

Argumentele opionale de la sfritul listei de parametri pot fi omise la apel fr probleme,


dar dac se omit argumentele din cadrul listei, atunci trebuie folosite cuvinte cheie pentru
cele urmtoare (nu este suficient utilizarea unor virgule succesive ca n anumite extensii
ale limbajului Fortran 77).

- 85 -

Funciile intrinseci au n general nume generice, astfel o funcie poate furniza valori diferite
n funcie de tipul argumentelor utilizate. Funciile definite de utilizator pot avea la fel,
nume generice. Presupunnd c am scrie un modul n care s avem mai multe funcii
similare, de exemplu pentru sortare: sortare_i pentru valori ntregi, sortare_r pentru valori
reale i sortare_s pentru iruri de caractere, numele generic sortare s-ar putea defini n felul
urmtor:
INTERFACE sortare
MODULE PROCEDURE sortare_i, sortare_r, sortare_s
END INTERFACE

Regulile pentru rezolvarea numelor generice sunt destul de complicate, ns este suficient
s ne asigurm ca fiecare procedur s difere de celelalte care au acelai nume prin tipurile
valorilor, rangul tablourilor sau cel puin printr-un argument utilizat efectiv.
Procedurile se pot autoapela n mod direct sau indirect dac sunt declarate recursive (prin
specificaia RECURSIVE). Cazurile tipice se ntlnesc la tratarea structurilor de date
similare cum ar fi arbori de directoare, de tip B etc. Un exemplu clasic este calculul
factorialului unui numr ntreg:
RECURSIVE FUNCTION factorial(n) RESULT(nfact)
IMPLICIT NONE
INTEGER, INTENT(IN) :: n
INTEGER :: nfact
IF(n > 0) THEN
nfact = n * factorial(n-1)
ELSE
nfact = 1
END IF
END FUNCTION factorial

La fel de simplu se poate realiza exemplul artat i utiliznd un ciclu DO. Folosirea
variabilei RESULT este opional, ea fiind necesar doar pentru a evita ambiguitatea
sintaxei (de exemplu, dac funcia ar returna un tablou, un element de tablou nu s-ar
distinge de un apel de funcie).
4.7

STRUCTURI DE DATE, TIPURI DERIVATE

Noiunile de date definite de utilizator, structuri de date i tipuri derivate de date nseamn
toate unul i acelai lucru. Instruciunea declarativ pentru tipuri derivate (TYPE) permite
specificarea proprietilor obiectelor i funciilor definite de utilizator. Iat un exemplu
simplu, ilustrnd tratarea unei liste de puncte:
TYPE :: tip_punct
CHARACTER(10) :: nume
REAL :: x, y, z
INTEGER :: culoare
END TYPE tip_punct

! numele obiectului
! coordonatele punctului
! culoarea punctului

- 86 -

Dup cum se poate observa, n asemenea structuri se pot amesteca i entiti de tip caracter
cu entiti numerice i logice (spre deosebire de blocurile comune), ajustarea aspectului
fizic pentru un acces eficient cznd n sarcina compilatorului. Exemplul de mai sus descrie
doar structura dorit, iar pentru a creea variabile cu tipul definit de date de mai sus
instruciunea TYPE trebuie folosit ntr-o alt form, i anume:
TYPE(tip_punct) :: punct_vechi, noua_lista(20)

Prin aceast specificare s-a creat o variabil structurat (sub numele: punct_vechi) i un
tablou cu 20 de elemente (noua_lista), fiecare dintre ele avnd cele cinci componente
specificate (nume, x, y, z i culoare). Bineneles, tipul derivat referit trebuie s fie definit
nainte de specificarea unor obiecte de acel tip.
Componentele unei structuri astfel definite sunt accesate utiliznd caracterul % (i nu
punctul ca n cele mai multe limbaje de programare). Astfel punct_vechi%nume este o
variabil de tip caracter, iar noua_lista(11)%x este o variabil de tip real. Asemenea entiti
structurale pot fi folosite n mod similar cu variabilele simple, de exemplu:
! ...
noua_lista(1)%nume = "primul"
noua_lista(1)%x = 23.4
noua_lista(1)%y = -2.15
noua_lista(1)%z = 0.0
noua_lista(1)%culoare = 8
! ...
noua_lista(2) = punct_vechi
! copierea tuturor componentelor
noua_lista(2)%x = noua_lista(2)%x + 1.5
! ...

Numele componentelor sunt considerate locale n cadrul structurii, deci nu apar probleme
dac aceai unitate de program folosete variabile simple cu denumiri similare (ca nume, x
etc. dac considerm exemplul prezentat).
Constructorii de structur permit specificarea valorii obiectelor de tip derivat, numele
tipului este folosit ca i cum ar fi vorba de o funcie de conversie, cu o list de valori ale
componentelor pe post de argumente:
noua_lista(3) = tip_punct("al treilea", 43.21, -15.3, 0.0, 2)

Dac exist un tablou declarat ca i tip derivat, fiecare component a structurii poate fi
tratat ca tablou (conform exemplului prezentat noua_lista%x va fi un tablou cu 20 de
valori de tip real). Elementele acestor entiti nu se pot situa n locaii adiacente n
memorie, de acest aspect se va ngriji compilatorul.
Variabilele structurate pot fi utilizate i n instruciuni de intrare/ieire. n cazul unor
operaii de citire/scriere fr format sau cu format implicit nu se pune nici o problem, ns
n cazul operaiilor formatate trebuie alctuit o list corespunztoare de descriptori:
WRITE(*,*) punct_vechi
READ(fisier, "(A,3F5.2,I2)") noua_lista(4)

- 87 -

! cu format implicit
! cu format explicit

De asemenea, putem defini structuri nlnuite, ca n exemplul urmtor:


TYPE :: punct
REAL :: x, y
END TYPE punct

! coordonatele punctului

TYPE :: linie
TYPE(punct) :: capat(2)
INTEGER :: grosime
END TYPE linie

! coordonatele capetelor
! grosimea liniei in pixeli

TYPE(line) :: v
REAL :: lungime
v = linie( (/ punct(1.2,2.4), punct(3.5,7.9) /), 2)
lungime = SQRT((v%capat(1)%x - v%capat(2)%x)**2 &
+ (v%capat(1)%y - v%capat(1)%y)**2)
! ...

O limitare a acestor structuri n Fortran este necesitatea fixrii n prealabil a lungimii


componentelor de tip tablou, adic, altfel spus un tablou alocabil nu poate fi componenta
unei structuri definite de utilizator. Din fericire ns, se admit pointeri ca i componente:
TYPE :: tip_document
CHARACTER(80), POINTER :: rand(:)
! componenta tip pointer
END TYPE tip_document
! ...
TYPE(tip_document) :: doc
! declara o variabila structurata
ALLOCATE(doc%rand(200))
! spatiu alocat pentru 200 de randuri

Pentru a face structura i mai flexibil am putea aloca un tablou de variabile de tip caracter
cu lungimea de cte un caracter a elementelor, pentru fiecare rnd (dei probabil ar fi mai
greu de utilizat aa). Pentru a transmite o variabil structurat ntr-o procedur, pe ambele
pri ale interfeei trebuie s asigurm aceeai definiie de structur. Cea mai simpl cale
pentru acest deziderat este folosirea unui modul. Exist ns dou limitri n ceea ce
privete utilizarea tipurilor derivate de date care conin pointeri:
ele nu se pot utiliza n listele de intrare/ieire ale instruciunilor de citire/scriere;
dac o instruciune de asignare copiaz valorile unei date derivate ntr-alta, dei
orice component de tip pointer va fi copiat, noul pointer va indica tot aceeai
zon de memorie.
Atunci cnd se definete un nou tip de date, ar fi de dorit ca obiectele de acel tip s se poat
utiliza n expresii obinuite. Evident, ar fi mai simplu s scriem a*b+c*d dect
add(mult(a,b),mult(c,d)). n acest scop ns, fiecare operator pe care dorim s-l
utilizm va trebui definit (sau suprancrcat) pentru fiecare tip derivat de date. Exemplul
urmtor prezint definirea unei structuri de date cu numele fuzzy, care conine un numr
real i eroarea sa standard. Cnd dou asemenea valori fuzzy sunt adunate, erorile se vor
aduna la ptrat. Pentru o astfel de adunare am suprancrcat operatorul +:
MODULE fuzzy_mate
IMPLICIT NONE

- 88 -

TYPE fuzzy
REAL :: valoare, eroare
END TYPE fuzzy
INTERFACE OPERATOR (+)
MODULE PROCEDURE fuzzy_plus_fuzzy
END INTERFACE

! interfata explicita

CONTAINS
FUNCTION fuzzy_plus_fuzzy(prim, secund) RESULT (suma)
TYPE(fuzzy), INTENT(IN) :: prim, secund
! INTENT necesar
TYPE(fuzzy), INTENT(OUT) :: suma
! INTENT opional
sum%valoare = prim%valoare + secund%valoare
sum%eroare = SQRT(prim%eroare**2 + secund%eroare**2)
END FUNCTION fuzzy_plus_fuzzy
END MODULE fuzzy_mate
PROGRAM test_fuzzy
IMPLICIT NONE
USE fuzzy_mate
TYPE(fuzzy) a, b, c
a = fuzzy(10.0, 4.0) ; b = fuzzy(12.5, 3.0)
c = a + b
PRINT *, c
END PROGRAM test_fuzzy

Rezultatul afiat de programul de test ar trebui s fie: 22.5 5.0 .


i operatorul = (instruciunea de asignare) poate fi suprancrcat pentru tipuri derivate de
date, ns n cazul de mai sus nu a fost necesar pentru c am folosit un subprogram cu un
argument avnd atributul INTENT(IN) i cellalt INTENT(OUT).
O implementare complet a clasei fuzzy ar trebui s cuprind suprancrcarea operatorilor
aritmetici, funcii intrinseci (ca de exemplu: SQRT), respectiv combinaii ntre operanzi de
tip real i fuzzy. Ulterior, reprezentarea intern poate fi schimbat fr a afecta programele
care folosesc tipul derivat fuzzy, cu condiia ca interfeele s rmn nemodificate.
Prioritatea la evaluare a unui operator existent rmne neschimbat prin suprancrcare, iar
operatorii unari noi vor avea o prioritate mai mare dect cei intrinseci existeni, pe cnd noii
operatori binari vor avea prioritate mai sczut. La suprancrcarea unui operator existent se
recomand ca semnificaia lui s nu fie alterat, altfel e mai sntos s se inventeze unul
nou pentru operaia dorit.
4.8

INTRRI I IEIRI

Intrrile i ieirile cuprind aspectele legate de transferul datelor, precum i cele referitoare
la conectarea, interogarea, modificarea, i poziionarea fiierelor. Ca i n cazul limbajului
Fortran 77, exist fiiere considerate externe (ntr-un mediu extern programului executabil)
i fiiere considerate interne (n spaiul de stocare al memoriei interne). Din punctul de

- 89 -

vedere al operaiilor posibile de citire i scriere, articolele (nregistrrile) din cadrul


fiierelor pot fi considerate de trei tipuri: formatate, neformatate, i marcajul de sfrit de
fiier (EOF, poate fi scris ntr-un fiier secvenial printr-o instruciune ENDFILE). Fiecrui
tip de articol i corespunde o modalitate de citire. nregistrrile formatate se citesc prin
instruciuni cu format explicit sau implicit, iar cele neformatate prin instruciuni fr
format. Articolele neformatate pot s fie goale (s nu conin date), reprezentarea intern a
datelor din asemenea nregistrri fiind dependent de echipamentul de calcul.
n ceea ce privete accesul la fiiere, prin dezvoltarea limbajului n varianta 90 exist cteva
parametri i opiuni noi pentru deschiderea acestora, iat-le n tabelul urmtor:
Tabel cu parametrii noi din instruciunea OPEN:
Cuvntul cheie
Valoarea
Funciunea
ACTION=
"READ"
Acces doar pentru citire.

POSITION=

"WRITE"

Acces pentru scriere.

"READWRITE"

Acces pentru citire i scriere.

"APPEND"

Adugarea la un fiier secvenial


existent.
Asigurarea poziionri la nceputul
fiierului deschis.
Suprascrierea unui fiier existent,
sau crearea unui fiier nou.
Se poate folosi la crearea unui fiier
secvenial n scopul precizrii
lungimii maxime a nregistrrilor.

"REWIND"
STATUS=

"REPLACE"

RECL=

lungime

Valoarea lungime a parametrului RECL semnific numrul de caractere n cazul accesului


formatat, iar n cazul accesrii neformatate (acces direct, binar) semnificaia este n funcie
de sistem. Instruciunea INQUIRE beneficiaz de asemenea de cuvinte cheie adiionale
pentru a returna informaii legate de deschiderea unei uniti. De exemplu, preciznd un
specimen pentru o list de intrare/ieire, ne poate returna valoarea lungimii necesare
parametrului RECL din instruciunea OPEN:
INQUIRE(IOLENGTH=lungime) specimen, lista, de, elemente
OPEN(UNIT=unitate, FILE=specfis, STATUS="new", &
ACCESS="direct", RECL=lungime)

Se pot utiliza citiri i scrieri dirijate prin liste (cu format implicit/liber) i asupra unor fiiere
interne, iat cum:
CHARACTER(LEN=10) :: sir
sir = " 3.14 "
READ(sir, *) variabila

- 90 -

De asemenea, pe lng descriptorii deja cunoscui sunt disponibile variante mai


performante i chiar noi, pentru formatul operaiilor de intrare/ieire, prezentate n tabelul
urmtor.
Tip
B
ES
EN
G
O
P
Q
Z
$
:

Tabel complementar, cu descriptori noi:


Efect
Pentru transferul valorilor sub form binar. Prin z se poate specifica numrul zerourilor premergtoare la afiare.
[n]ESw.d[Ee]
Form exponenial (notaie tiinific), cu zecimale
dup prima cifr semnificativ (exemplu: 1.234E-01 n
loc de 0.1234E-00).
[n]ENw.d[Ee]
Form exponenial (notaie tehnic), exponentul fiind
multiplu de 3 (exemplu: 123.4E-03 n loc de 0.1234E-00).
[n]Gw.d[Ee]
Descriptor modificat, cu caracter general, poate fi utilizat
att pentru valori numerice ct i pentru valori logice sau
de tip caracter.
[n]Ow[.z]
Pentru transferul valorilor sub form octal. Prin z se poate specifica numrul zerourilor premergtoare la afiare.
mP
Interpreteaz anumite numere reale cu un factor de
mrime m specificat.
Q
Returneaz numrul caracterelor rmase ntr-o
nregistrare citit.
[n]Zw[.z]
Pentru transferul valorilor sub form hexazecimal. Prin z
se poate specifica numrul zerourilor premergtoare la
afiare.
$
Inhib returul de car la operaia curent de intrare/ieire
(similar cu descriptorul \ din Fortran 77).
:
ncheie controlul formatrii (dac nu mai sunt elemente n
list).
Sintax
[n]Bw[.z]

Operaiile de citire/scriere trateaz n mod normal o nregistrare complet. Exist ns i o


facilitate nou de a trata nregistrrile, prin specificarea atributului ADVANCE n cadrul
acestor instruciuni, ca n exemplul urmtor:
WRITE(*, "(A)", ADVANCE="NO") "Numarul ciclurilor: "
READ(*,*) n_ciclu

n acest caz, n loc de trecerea la articolul urmtor se va muta doar un pointer teoretic n
cadrul articolului att ct este necesar, permind introducerea valorii variabilei n_ciclu pe
linia curent pe care s-a afiat mesajul (ca la un prompter) pe ecran. Acest atribut combinat
cu atributul SIZE permite i msurarea lungimii actuale a rndului citit:
CHARACTER(LEN=80) :: text
INTEGER :: n_car
READ(*, "(A)", ADVANCE="no", SIZE=n_car) text

Aceast facilitate se poate dovedi util n cazul citirii unor fiiere secveniale parial corupte
sau cu structuri neconvenionale.
- 91 -

4.9

TRATAREA IRURILOR DE CARACTERE

Aa cum am mai menionat, exist o sumedenie de funcii intrinseci noi i performante


introduse prin Fortran 90, dintre acestea unele fiind destinate tratrii irurilor sau a
subirurilor alctuite din caractere. n tabelul urmtor se pot vedea aceste funcii, mpreun
cu descrierea efectului produs prin apelarea lor.
Tabel cu noile funcii intrinseci pentru tratarea irurilor de caractere:
Funcie
Efect
Nume generic
Tip
ACHAR(n)
CH Returneaz caracterul de pe poziia n din tabela
ASCII.
IACHAR(c)
I
Returneaz poziia caracterului c din tabela
ASCII.
LEN_TRIM(ir)
I
Returneaz lungimea lui ir (n numr de
caractere) ignornd spaiile de la sfrit.
TRIM(ir)
CH Returneaz ir-ul fr spaiile de la sfrit.
ADJUSTL(ir)
CH Elimin spaiile premergtoare din ir.
ADJUSTR(ir)
CH Elimin spaiile finale din ir.
REPEAT(ir, n)
CH Concatenare repetat de n ori a ir-ului.
INDEX(ir, s[, BACK=v])
I
Poziia primului caracter al subirului s n ir
(dac v este .TRUE., ir va fi parcurs dinspre
capt ctre nceput).
SCAN(ir, s[, BACK=v])
I
Poziia primului caracter al subirului s n ir,
sau al ultimului caracter din s dac v este
.TRUE..
VERIFY(ir, s[, BACK=v])
I
Poziia primului caracter din ir care difer de
caracterele din subirul s (dac v este .TRUE.,
ir va fi parcurs dinspre capt).
Prin noua sintax sunt admise i suprapuneri de subiruri, ca n exemplul urmtor:
text(1:5) = text(3:7)

! nepermis in Fortran77, acum admis

Operatorul de concatenare // poate fi aplicat fr restricii i asupra argumentelor (cu


lungimea transmis) din proceduri.
Funciile care trateaz entiti de tip caracter pot returna iruri cu o lungime ce depinde de
argumentele specificate, de exemplu:
FUNCTION concat(s1, s2)
IMPLICIT NONE
CHARACTER(LEN=LEN_TRIM(s1)+LEN_TRIM(s2)) :: concat ! numele functiei
CHARACTER(LEN=*), INTENT(IN) :: s1, s2
concat = TRIM(s1) // TRIM(s2)
END FUNCTION concat

- 92 -

Se pot folosi iruri cu lungimea zero, cum ar fi referine de genul subir(i:j) unde i >
j, i constante de forma "". Sunt admise i subiruri de constante, iat un exemplu pentru
convertirea unei valori n de tip ntreg, din domeniul 09, n caracterul corespunztor:
caracter_n = "0123456789"(n:n)

! alocarea cifrei ca si caracter.

Variabila caracter_n va conine cifra corespunztoare valorii lui n, cu condiia ca n-ul


precizat s nu fie mai mic dect zero sau mai mare dect 9 (altfel va rezulta eroare).
4.10

POINTERI

Foarte multe limbaje de programare suport pointeri pentru c utilizarea acestora uureaz
implementarea structurilor dinamice de date: liste nlnuite, stive i arbori. Programele
scrise n limbajul C depind n mare msur de pointeri deoarece transmiterea unui tablou
ctre o funcie genereaz instantaneu o referin de acest tip. ns utilizarea pointerilor
poate crea i greuti:
Folosirea lor poate fora programatorul s ia n considerare aspecte de un nivel
apropiat mainii, ceea ce ar fi mai eficient dac s-ar lsa pe seama compilatorului.
Utilizarea lor excesiv conduce la surse greu inteligibile i greu mentenabile.
Conduc foarte uor la erori detectabile doar n faza de rulare (o mare parte din
greelile sub limbajul C sunt datorate utilizrii accidental eronate a pointerilor).
Inhib optimizarea automat a codului la compilare (dou obiecte aparent distincte
se pot dovedi a fi doar pointeri indicnd ctre aceeai locaie de memorie).
Limbajul Java este considerat de ctre unii ca fiind un dialect fr pointeri al limbajului
C++. Dei pointerii din Fortran sunt relativ blnzi, ei trebuie folosii totui cu atenie.
Dup cum am menionat n subcapitolul referitor la tablouri, un pointer poate fi perceput ca
o referin ctre o referin. Deci un pointer nu conine date, el indic doar ctre o variabil
care conine date. n Fortran, poate indica doar ctre un alt pointer sau ctre o variabil
declarat explicit ca fiind o int valid (prin specificatorul TARGET). Fiecare pointer are o
stare de asociere care-l determin s indice sau nu, la un moment dat, ctre un obiect int.
Funcia intrinsec ASSOCIATED permite interogarea acestei stri. Aceast funcie va
returna valoarea .FALSE. n cazul unei stri neasociate (iar n caz contrar valoarea
.TRUE.).
n Fortran 90, din pcate, la declararea iniial a unui pointer (prin atributul POINTER)
starea acestuia este nedefinit (n Fortran 95 acest aspect este ns rezolvat). Din acest
motiv, cea mai bun metod este ca la nceput s setm fiecare pointer ntr-o stare
neasociat (prin instruciunea NULLIFY), dup care se va putea testa starea lor (apelnd
funcia intern ASSOCIATED) naintea alocrii lor unor inte valide. Starea de asociere a
pointerilor poate fi desetat i prin instruciunea DEALLOCATE (sau prin apelarea funciei
intrinseci NULL).

- 93 -

Limbajul Fortran 90 nu permite crearea unor tablouri din pointeri, dar permite crearea unor
tablouri de obiecte definite de utilizator (de tip derivat) care s conin pointeri:
TYPE :: tablou_de_ptr
REAL, DIMENSION(:), POINTER :: tp
END TYPE tablou_de_ptr
TYPE(tablou_de_ptr), ALLOCATABLE :: x(:)
!...
ALLOCATE(x(nx))
DO i = 1,nx
ALLOCATE(x(i)%tp(m))
END DO

Pointerilor le pot fi asignate valori de tip int, printr-o operaie special marcat cu
simbolul => (pentru a se deosebi de operaiile curente de asignare sau de atribuire). Dac
inta nu este definit sau asociat, pointerul primete acelai statut ca i variabila dinamic
reprezentat de int. Pointerii se pot dovedi foarte utili la notarea prescurtat a seciunilor
de tablouri, ca i alias, de exemplu:
REAL, TARGET :: poza(1024,768)
! declarare ca tinta
REAL, DIMENSION(:,:), POINTER :: alfa, beta
alfa => poza(1:512, 385:768)
! asignare la un sfert din poza
beta => poza(1:1024:1, 768:1:-1)
! asignare la poza oglindita

Iat i ilustrarea unei situaii (printr-o funcie de realocare cuprins ntr-un modul) n care
se poate dovedi util returnarea unui pointer pentru un tablou, de ctre o funcie:
MODULE realocare_m
CONTAINS
FUNCTION realoca(p, n)
REAL, POINTER, DIMENSION(:) :: p, realoca
INTEGER, intent(in) :: n
INTEGER :: n_vechi, i_eroare
ALLOCATE(realoca(1:n), STAT=i_eroare)
IF(i_eroare /= 0) STOP "Eroare de alocare"
IF(.NOT. ASSOCIATED(p)) RETURN
n_vechi = MIN(SIZE(p), n)
realoca(1:n_vechi) = p(1:n_vechi)
DEALLOCATE(p)
END FUNCTION realoca
END MODULE realocare_m
PROGRAM test_realocare
USE realocare_m
IMPLICIT NONE
REAL, POINTER, DIMENSION(:)
INTEGER :: j, n_elem = 2
ALLOCATE(p(1:n_elem))
p(1) = 12345
p => realoca(p, 10000)
!
WRITE(*,*) "sunt alocate ",
WRITE(*,*) "p(1)=", p(1)
END PROGRAM test_realocare

! realoca de tip real


! declarare pointeri

! tratarea erorii
! testarea asocierii
! atribuire "comuna"
! eliberare pointer p

! specificarea utilizarii modulului


! declaraie obisnuita in Fortran 90
:: p

observati maniera specifica de asignare


n_elem, size(p), " elemente"

- 94 -

Pointerii se pot folosi i la alctuirea unor structuri de date dinamice complexe, cum ar fi
listele nlnuite, arborii binari etc. Acest lucru este posibil deoarece o variabil de tip
derivat poate conine pointeri care s indice ctre sine sau ctre alte obiecte similare (cu
condiia ca intele s fie valide). n exemplul urmtor prezentm o posibil implementare a
unei cozi:
PROGRAM coada
IMPLICIT NONE
TYPE :: tip_element
CHARACTER(20) :: sir

! specificarea unei structuri de date

! pointer catre un obiect similar:


TYPE(tip_element), POINTER :: urmator
END TYPE tip_element
TYPE(tip_element), POINTER :: fata, spate, pozitie
CHARACTER(20) :: tampon
INTEGER :: stare
NULLIFY(fata, spate)
! setarea initial goala a cozii, apoi
! ciclu pentru citirea unor caractere
DO
! tastate de utilizator, in tampon
READ(*, "(A)", IOSTAT=stare) tampon
IF(stare /= 0) EXIT
! iesirea din ciclu
IF( .NOT. ASSOCIATED(fata)) THEN
ALLOCATE(fata)
! crearea locatiei pentru prima pozitie
spate => fata
! spre care indica fata si spate
ELSE
ALLOCATE(spate%urmator)
! locatia pentru pozitia urmatoare
spate => spate%urmator
! spre care indica spate
END IF
spate%sir = tampon
! stocarea sir-ului in pozitia noua si
NULLIFY(spate%urmator)
! marcarea acesteia ca ultima din coada
END DO
! dupa iesirea din ciclu urmeaza parcurgerea cozii
! cu afisarea continutului fiecarui element:
pozitie => fata
! repozitionare pe inceputul cozii,
! si ciclu pentru
DO WHILE(ASSOCIATED(pozitie))
WRITE(*,*) pozitie%sir
! afisarea continutului din pozitia
! curenta, si
pozitie => pozitie%urmator ! asignarea pointerului la urmatorea
! pozitie din coada
END DO
STOP
END PROGRAM coada

4.11

ALTE ASPECTE

Valorile de tip binar, octal, i hexadecimal se pot citi sau scrie utiliznd descriptorii noi de
tipul B, O, i Z, iar constantele numerice de acest fel se scriu cu litera corespunztoare
tipului n faa valorii citate (de exemplu, valoarea decimal 15 se poate scrie sub form
binar ca: B"1111", sub form octal ca: O"17", sub form hexadecimal ca: Z"F").
Specificaiile DATA pot s conin de asemenea constante binare, octale i hexadecimale.

- 95 -

4.11.1

Funcii intrinseci i faciliti noi

Standardul limbajului Fortran a fost extins i cu o serie de funcii intrinseci ce faciliteaz


manipulrile valorilor la nivel de bii. Numerotarea biilor se face de regul dinspre dreapta
spre stnga, pornind de la poziia zero (sau de la captul cel mai puin semnificativ).
Tabel cu noile funcii intrinseci pentru operaii la nivel de bit asupra valorilor ntregi:
Funcie
Efect
BIT_SIZE(t)
Returneaz numrul biilor din variabila de tipul t.
BTEST(i, p)
Testeaz bitul de pe poziia p din valoarea i de tip ntreg.
IAND(i, j)
I logic ntre dou argumente de tip ntreg.
IBCLR(i, p)
Golete coninutul bitului de pe poziia p din ntregul i
(valoarea bitului va fi zero).
IBCHNG(i, p)
Inverseaz valoarea bitului de pe poziia p din ntregul i.
IBITS(i, p, l)
Extrage irul de bii cu lungimea l ncepnd de la p din i.
IBSET(i, p)
Seteaz valoarea bitului de pe poziia p din ntregul i pe unu.
IEOR(i, j)
SAU exclusiv ntre dou argumente de tip ntreg.
IOR(i, j)
SAU inclusiv ntre dou argumente de tip ntreg.
ISHFT(i, n)
Translatare logic de bii la stnga (sau la dreapta dac n este
negativ) cu n poziii n cadrul lui i.
ISHFTC(i, n)
Deplasare circular logic de bii la stnga (sau la dreapta
dac n este negativ) cu n poziii n cadrul lui i.
NOT(i)
Complementul logic al argumentului i de tip ntreg.
Noile funcii intrinseci FLOOR i MODULO au sintaxe i efecte similare cu cele ale
funciilor AINT i MOD deja cunoscute, cu deosebiri doar n cazul numerelor negative.
Funcia CEILING, similar acestora ca form, rotunjete argumentul n sus, la cel mai
apropiat ntreg.
Funcia intrinsec TRANSFER poate fi folosit pentru copierea biilor dintr-o valoare de un
anume tip ntr-o valoare de alt tip (o alternativ mai sigur dect artificiile posibile prin
declaraii EQUIVALENCE). Iat spre exemplu, cum se poate folosi aceast funcie pentru
testarea unui calculator din cadrul unui program, cu privire la reprezentarea caracterelor:
LOGICAL, PARAMETER :: bigend = IACHAR(TRANSFER(1,"a")) == 0

Dac platforma este de tip big-endian atunci parametrul bigend va primi valoarea .TRUE.
(altfel va avea valoarea .FALSE.).
Dintre funciile numerice intrinseci menionm funciile TINY (care returneaz cel mai mic
numr pozitiv de tipul i felul argumentului) i HUGE (care returneaz cel mai mare numr
pozitiv de tipul i felul argumentului), care accept ca argument att valori ntregi ct i
valori reale, de orice fel. Dei exist nc multe alte funcii intrinseci noi, ne limitm doar la
a meniona cteva: BIT_SIZE, DIGITS, EPSILON, MAXEXPONENT, MINEXPONENT,
PRECISION, RADIX, RANGE etc.

- 96 -

4.11.2

Subprograme predefinite

Pe lng multitudinea funciilor noi exist i cteva subprograme interne, apelabile din
orice unitate de program. Dintre acestea menionm:
returneaz data i ora curent sub
forma unui ir sau sub forma unui
tablou de valori ntregi;

DATE_AND_TIME([data][,timp][,zona][,valori])

returneaz un tablou de valori


pseudoaleatoare uniform distribuite n
intervalul 01;

RANDOM_NUMBER([HARVEST=]tablou)

RANDOM_SEED([msuma][,pune][,ia])

SYSTEM_CLOCK([contor][,rata][,maxim])

permite tratarea unor intervale de timp


n funcie de ceasul calculatorului (n
Fortran 95 exist o rutin mai curat:
CPU_TIME).

4.11.3

iniializeaz sau recupereaz valoarea


iniial a generatorului de numere
pseudoaleatoare;

Aspecte legate de evoluia limbajului

Anumite aspecte din Fortran au fost considerate att de depite nct au fost excluse din
standardele noi ale limbajului. Dup saltul imens produs de apariia standardului Fortran 90
limbajul a fost dezvoltat n continuare, iar pn n 1996 s-a elaborat o nou versiune sub
specificaia de Fortran 95. Diferenele dintre aceste dou versiuni nu sunt att de mari, ns
caracteristicile considerate depite au fost lsate uitrii. Folosirea lor nu este recomandat,
chiar dac unele compilatoare Fortran 95 semnaleaz doar erori de atenionare la ntlnirea
acestora. Iat cteva dintre aceste aspecte problematice:
Cicluri DO cu variabil de control de tip real (sau dubl precizie).
Cicluri DO finalizate prin alte instruciuni dect CONTINUE sau END DO.
Dou sau mai multe cicluri DO (incluse) finalizate prin aceeai instruciune.
Instruciunea IF aritmetic.
Folosirea constantelor Hollerith (sau descriptorului H) n listele de descriptori
din instruciunile FORMAT.
Folosirea instruciunii PAUSE (se poate nlocui lesne cu o instruciune de citire
fr list de intrare).
Folosirea instruciunii ASSIGN (i implicit a instruciunii GO TO asignate, a
etichetelor asignate pentru FORMAT etc.).
Folosirea facilitii de revenire (RETURN) alternativ.
Specificarea unei ramuri ctre instruciunea END IF din afara blocului IF
(posibil n Fortran 77 din greeal).

- 97 -

Excluderea acestor faciliti nu reprezint o problem, cu att mai puin pentru cei ce nu
uzau de ele. Exist i alte aspecte care dei sunt utilizate n mod obinuit n Fortran 77, sunt
considerate ca fiind redundante i ca atare se recomand a fi evitate n scrierea surselor. De
exemplu: formatul fix, tipurile de date implicite (nedeclararea explicit a tipurilor),
blocurile comune (COMMON), tablourile cu mrime presupus, instruciunile INCLUDE,
EQUIVALENCE, ENTRY, unitile de program BLOCK DATA etc.
Dintre principalele caracteristici noi ale limbajului Fortran 95 menionm:

instruciunea FORALL (i facilitile noi oferite i pentru WHERE);


subprogramele pure (PURE) i elementare (ELEMENTAL) definite de utilizator;
starea de asociere iniial a pointerilor, prin => NULL();
iniializarea implicit a obiectelor de tip derivat;
referirile la proceduri pure n expresiile de specificare;
dealocarea automat a tablourilor alocabile;
formatarea prin specificator cu lungime zero produce considerarea numrului
minim de poziii necesare (de exemplu: I0);
noua funcie intrinsec CPU_TIME;
schimbri ale unor funcii intrinseci etc.
Pentru detalii suplimentare v recomandm consultarea sitului realizat de Bo Einarsson (la
adresa http://www.nsc.liu.se/~boein/f77to90/f95.html).
Ultima variant dezvoltat a fost botezat Fortran 2000. Dintre noutile aduse de aceasta i
facilitile oferite menionm:
performane ridicate n domeniul calculelor tiinifice i inginereti (operaii
asincrone de citire/scriere, tratarea excepiilor de virgul flotant, interval
aritmetic);
abstractizarea datelor cu extensibilitatea oferit ctre utilizatori (componente
alocabile, intrri/ieiri de tip derivat);
orientare pe obiecte (constructori/destructori, motenire, polimorfism);
tipuri derivate parametrizate;
pointeri la proceduri;
internaionalizare;
interoperabilitate cu limbajul C.
Ca i resurse disponibile (standarde i versiuni ale limbajului, compilatoare, medii de
programare, generatoare de interfee, programe de conversie, programe gratuite, produse
comerciale, documentaii, liste cu ntrebri frecvente i forumuri etc.) v recomandm
consultarea adresei http://www.fortran.com/fortran/ .

- 98 -

CAPITOLUL 5: G77
5.1

COMPILATORUL GNU FORTRAN 77

GNU Fortran 77 (cunoscut i ca g77) este un compilator realizat de ctre o echip condus
de Craig Burley n cadrul organizaiei Free Software Foundation (Fundaia pentru Software
Liber) cu scopul de a sprijini dezvoltarea programelor n acest limbaj. Ofer suport complet
pentru fiiere surs scrise n Fortran 77, acceptnd i unele extensi comune derivate n
specificaii de tip Fortran 90. Fiierele executabile (programele) rezultate sunt la fel de
rapide ca cele realizate cu compilatoare comerciale. Compilatorul g77 este accesibil prin
internet tuturor celor interesai pornind de la urmtoarea adres, ca parte a pachetului gcc
(GNU Compiler Collection):
http://www.gnu.org/directory/gcc.html
sau
http://www.gnu.org/software/gcc/gcc.html
Pentru cei ce folosesc sistemul de operare Windows, merit s menionm i unul dintre
siturile educaionale, cum ar fi cea de la Universitatea Statului Utah, la adresa:
http://www.engineering.usu.edu/cee/faculty/gurro/Classes/Classes_Main.htm
unde pe lng pachetul G77.ZIP exist i cursuri de iniiere n programare cu ajutorul
limbajului Fortran 77, folosind i facilitile noi permise de compilatorul g77.
Sursele programelor pot fi redactate cu ajutorul oricrui editor de text ce poate salva fiiere
text curate (ASCII). Compilatorul g77 lansat sub sistemul de operare Windows ruleaz n
mod normal sub fereastr DOS. Acest aspect implic respectarea conveniilor din DOS
pentru specificatorii de fiiere i directoare (cel mult 8 caractere alfanumerice pentru nume
i 3 pentru extensie). Exist ns i cteva interfee grafice accesibile (cu licen de utilizare
liber) care conin i editoare de text adecvate pe lng compilatorul g77, asemntoare cu
medii de dezvoltare comerciale, uneori prea scumpe. Dintre cele mai simple asemenea
interfee amintim dou: Vfort (printre primele aprute, autorii fiind N. i P. Vabicevici din
Rusia, http://www.imamod.ru/~vab/vfort/), i Force2 (un proiect realizat i dezvoltat de
ctre G. Lepsch Guedes, http://www.forceproject.hpg.com.br/).
Pentru a creea fiiere executabile cu ajutorul compilatorului g77, se poate folosi o linie de
comand de genul:
G77 nume1.F[ op][ nume2.EXE]
unde:

G77 numele compilatorului GNU Fortran 77;


nume1.F specificatorul fiierului surs;
op opiune pentru compilare;
nume2.EXE specificatorul fiierului executabil ce se creeaz.

- 99 -

Fiierul executabil nume2.exe rezultat poate fi lansat n execuie prin invocarea numelui
nume2 ntr-o linie nou de comand, cu condiia ca s nu existe erori care s impieteze
asupra generrii lui.
Dac n timpul compilrii sursei erorile de sintax afiate n fereastra DOS curent sunt
prea numeroase, depind zona afiajului curent, se poate redirecta ieirea stderr (Standard
Error) ntr-un fiier text. Aceast facilitate este oferit de cele mai multe medii de
programare, dar poate fi realizat i prin programul ETIME.EXE (program de temporizare
cu redirectare cuprins n pachetul G77.ZIP oferit de Gilberto E. Urroz de la Utah State
University, la adresa deja menionat) sub DOS printr-o linie de comand de forma:
ETIME 2specfis G77 nume1.F
unde:

ETIME numele programului de redirectare;


2 opiune pentru redirectarea descriptorului de fiiere 2 (stderr);
specfis specificatorul fiierului n care se vor nregistra mesajele
redirectate;
G77 numele compilatorului GNU Fortran 77 (g77.exe);
nume1.F specificatorul fiierului surs.

n acest caz nu se va genera nici un mesaj (ecou) pe ecran, nu se va crea nici imagine obiect
nici imagine executabil pentru fiierul surs nume1.F, ns fiierul specificat prin specfis
va conine toate mesajele ce ar fi aprut pe ecran n urma compilrii cu g77. Vizualiznd
coninutul fiierului specfis generat se poate depana mai uor sursa coninut n nume1.F.
5.2

COMPILAREA CU G77

Comanda G77 sub forma primului exemplu din subcapitolul precedent va determina
compilarea i editarea legturilor din programul scris, genernd un fiier executabil ce va
putea fi rulat sub DOS sau Windows 9x/NT (n fereastr DOS). Dac numele fiierului
executabil nu se specific n linia de comand, se va genera un fiier cu numele identic cu
cel al sursei (dar cu extensia .EXE). Exist mai multe opiuni ce se pot specifica dup
numele fiierului surs (atenie la litere mici i la majuscule!), dintre care menionm:
c
ffreeform
fpedantic
fnoautomatic
fnobackslash
fvxt

doar compilare (Compile-only), se va genera doar imagine


obiect fr imagine executabil (rezult doar fiier cu
extensia .OBJ);
pentru fiier surs redactat sub form liber;
va avertiza asupra codului neportabil sau nestandard;
pentru alocare static la toate variabilele (similar cu SAVE
universal):
va interpreta \ ca i caracter normal n iruri;
pentru interpretarea anumitor sintaxe de tipul VAX Fortran;

- 100 -

va produce informaii pentru depanare;


pentru specificarea directorului cu fiiere de inclus (prin
INCLUDE);
O
pentru optimizarea codului generat;
Wimplicit
va avertiza asupra numelor de date cu tip neexplicit;
Wuninitialised va avertiza n anumite cazuri asupra variabilelor fr
valoare (dac s-a folosit opiunea O);
Wall
va genera mesaje de avertizare referitoare la variabile
neutilizate sau nedeclarate (ca cele dou opiuni precedente
combinate).
g
Idirector

n linia de comand se pot specifica mai multe fiiere surs, se admite i caracterul * n
specificaii (conform conveniilor din DOS). De asemenea, se pot specifica fiiere
compilate (imagini obiect cu extensia .OBJ) i fiiere de bibliotec (numite arhiv n
jargonul utilizatorilor de Unix, fiiere cu extensia .A). La specificarea opiunilor trebuie s
avem grij la respectarea formei de scriere, ns specificatorii de fiiere sub DOS (i sub
Windows) nu sunt sensibili la mrimea caracterelor utilizate (caracterele mici sunt
echivalente cu majusculele corespunztoare). Iat i un scurt exemplu pentru ilustrarea
compilrii cu G77:
Creeai un fiier text (ASCII) cu un editor convenabil (de exemplu NotePad sub Windows),
cu urmtorul coninut, innd cont de faptul c n format fix instruciunile ncep din coloana
a 7-a i se termin pn n coloana 72:
C2345678901234567890123
Program TEST
integer i
real x(10)
do 1 i=1,10
x(i)=i*i
1
write(*,*)i,x(i)
end

! ciclu finalizat fara CONTINUE

Salvai fiierul sub numele TEST.F alturi de programul G77.EXE i deschidei o fereastr
DOS (avnd grij s v aflai n directorul n care avei compilatorul i fiierul surs creat).
Pentru a compila sursa scris i pentru a creea o imagine executabil tastai linia de
comand:
G77 TEST.F O TEST
Dac ai lucrat corect, dup terminarea procesului lansat se va afia din nou prompterul
curent din fereastra DOS. n cazul n care vi se afieaz mesaje de eroare, citii-le cu
atenie, dac trebuie editai din nou fiierul surs i corectai inadvertenele nainte de a-l
salva din nou. Pentru a verifica existena programului generat putei tasta comanda:
DIR TEST.*

- 101 -

Dac pe ecran vi se afieaz printre altele i specificatorul de fiier TEST.EXE, atunci


putei lansa n execuie programul creat, tastndu-i numele:
TEST
Programul va afia pe ecran valorile de la 1 la 10 cu ptratul lor, succesiv. Prin comanda
DIR putei vedea i diferena de mrime dintre fiierul surs (TEST.F) i programul creat
(TEST.EXE). Evident, vei putea creea fiiere surs i programe i n alte directoare, pentru
acest fapt ns vei fi nevoii s v configurai mediul de lucru corespunztor (setarea
variabilei PATH etc.).
Dac folosii mediile de programare cu interfa grafic VFort sau Force2 amintite, atunci
va trebui s inei cont de setrile i opiunile acestora, compilarea i editarea legturilor
realizndu-se cu comenzile grafice corespunztoare (prin activarea butoanelor oferite prin
interfaa grafic). Pentru informaii mai detaliate recomandm consultarea adreselor de web
menionate.
5.3

BIBLIOTECI PENTRU G77

Fortran fiind un limbaj de programare dezvoltat n scopuri tiinifice, exist o varietate


foarte mare de biblioteci matematice, mai ales cu implementri de metode numerice. Ne
rezumm ns s amintim doar dou pachete disponibile prin internet (pornind de la adresa:
http://www.geocities.com/Athens/Olympus/5564/ ,
la care se gsete pagina dedicat compilatorului G77 pentru variantele pe 32 de bii ale
sistemului de operare Windows) i compatibile cu GNU Fortran 77.
Primul pachet este biblioteca matematic SLATEC, dezvoltat la Laboratoarele Naionale
Americane (din Los Alamos, Lawrence Livermore, NIST, Oak Ridge, Sandia etc.), ce
conine 902 de module apelabile de ctre utilizatori, fiind de fapt o colecie compus din
rutinele considerate ca cele mai utile din cadrul altor pachete de bibliotec (BLAS,
LINPACK, EISPACK, SLAP, FFTPACK, FISHPACK, LLSQ, MINPACK, MP, PCHIP,
QUADPACK i SPLPACK).
Al doilea pachet este o bibliotec grafic cu numele PSPLOT, ce permite generarea
imaginilor n format PS (PostScript). Acest format este independent de sistemul de operare
folosit, fiind acceptat i utilizat de ctre multe periferice de imprimare, pentru vizualizarea
imaginilor pe ecran fiind ns nevoie de o aplicaie corespunztoare (cum ar fi pachetele
Aladdin Ghostscript i GSView, disponibile sub licene libere pentru diverse platforme).

- 102 -

CAPITOLUL 6: EXERCIII
6.1

EXERCIII ELEMENTARE INTRODUCTIVE

6.1.1

S se schieze o schem logic pentru alegerea celei mai mari valori dintre a, b, i
c, i s se scrie un program FORTRAN pe baza schemei respective.

Soluie propus:
!2345678901234567890123456789012345678
!randul de mai sus arata doar coloana.
! incepem direct cu
! afisarea mesajului pentru cerere:
write(*,*)' a, b, c: '

START
a, b, c :
a, b, c
Nu

a<b

! citirea valorilor pentru a, b, c:


read(*,*)a,b,c

Da
a := b

Nu

a<c

Da
a := c

max:, a
STOP

6.1.2

! testarea primei conditii


! (si in caz afirmativ atribuire):
if(a.lt.b) a=b
! testarea urmatoarei conditii
! (si in caz afirmativ atribuire):
if(a.lt.c) a=c
! afisarea rezultatului stocat in a:
write(*,*)' max: ', a
stop
end

S se schieze o schem logic pentru ordonarea cresctoare a valorilor a, b, i c,


dup care s se scrie un program FORTRAN pe baza schemei ntocmite.

Soluie propus:
START
a, b, c :
a, b, c
1

! incepem cu declaratia de program:


program abcordc
! afisarea mesajului pentru cerere:
write(*,*)' a, b, c: '
! citirea valorilor pentru a, b, c:
read(*,*)a,b,c
! schema logica este continuata pe
! pagina urmatoare, la fel si
! programul, scris alaturat.

- 103 -

! continuarea schemei
! si a programului,

1
Nu

a>b

Da
t := a
a := b
b := t

Nu

a>c

Da
t := a
a := c
c := t

Nu

b>c

Da
t := b
b := c
c := t

crescator:,a,b,c
STOP

6.1.3

! cu testarea primei conditii


! (in caz afirmativ schimbam valorile
! dintre a si b cu ajutorul lui t):
if(a.gt.b) then
t=a
a=b
b=t
endif
! testarea urmatoarei conditii
! (in caz afirmativ schimbam valorile
! dintre a si c cu ajutorul lui t):
if(a.gt.c) then
t=a
a=c
c=t
endif
! testarea urmatoarei conditii
! (in caz afirmativ schimbam valorile
! dintre b si c cu ajutorul lui t):
if(b.gt.c) then
t=b
b=c
c=t
endif
! afisarea rezultatului:
write(*,*)' crescator: ',a,b,c
! si implicit sfarsitul programului
end

S se scrie un program FORTRAN care n urma citirii de la tastatur a unui numr


ntreg din intervalul [1,7], afieaz ziua din sptmn care corespunde acelui
numr (1 luni, 2 mari etc.).

Soluie propus:
! --!
!
!
!
33

program saptamana
programul indica ziua saptamanii pe baza unui nr. intreg
din intervalul [1,7]
nu a fost declarat explicit tipul variabilelor, in mod implicit
variabilele ale caror nume incepe cu i, j, k, l, m, n sunt de
tip intreg, iar restul de tip real (de evitat acest stil!)
write(*,*)' dati un nr. intreg din intervalul [1,7] : '
read(*,*)i
write(*,*)
! se tipareste o linie goala

- 104 -

6.1.4

testare caz
select case (i)
case (1)
write(*,*) 'ziua corespunzatoare
case (2)
write(*,*) 'ziua corespunzatoare
case (3)
write(*,*) 'ziua corespunzatoare
case (4)
write(*,*) 'ziua corespunzatoare
case (5)
write(*,*) 'ziua corespunzatoare
case (6)
write(*,*) 'ziua corespunzatoare
case (7)
write(*,*) 'ziua corespunzatoare
case default
write(*,*) 'nr. eronat !! '
write(*,*)
goto 33
end select
end

nr. ales este LUNI'


nr. ales este MARTI'
nr. ales este MIERCURI'
nr. ales este JOI'
nr. ales este VINERI'
nr. ales este SAMBATA'
nr. ales este DUMINICA'

S se scrie un program FORTRAN care pe baza lungimilor a 3 segmente, decide


dac acestea pot forma un triunghi.

Soluie propus:
program triunghi
! --- decide daca 3 segmente pot fi laturile unui triunghi
!
pe baza inegalitatilor cunoscute de la geometrie
!
!
se foloseste regula implicita
!
deci fara declaratii explicite ale tipului variabilelor
!
write(*,*)' dati lungimea primului segment : '
read(*,*)s1
write(*,*)' dati lungimea celui de-al doilea segment : '
read(*,*)s2
write(*,*)' dati lungimea celui de-al treilea segment : '
read(*,*)s3
!
testare inegalitati
if((s1.lt.(s2+s3)).and.(s2.lt.(s1+s3)).and.
+
(s3.lt.(s1+s2))) then
write(*,*) 'segmentele POT fi laturile unui triunghi'
else
write(*,*) 'segmentele NU pot fi laturile unui triunghi'
endif
end

- 105 -

6.1.5

S se scrie un program FORTRAN care afieaz pe ecran urmtorul tabel, folosind


instruciunea FORMAT.
*********************
| N |
Npatrat
|
*********************
| 1 |
1
|
--------------------| 2 |
4
|
--------------------| 3 |
9
|
--------------------| 4 |
16
|
--------------------| 5 |
25
|
--------------------| 6 |
36
|
--------------------| 7 |
49
|
--------------------| 8 |
64
|
--------------------| 9 |
81
|
--------------------| 10 |
100
|
---------------------

Soluie propus:
program tabel
! --- creeaza un tabel, utilizand FORMAT
!
implicit none
integer n
100
format(1x,a21)
print 100, '*********************'
print*,
'| N |
Npatrat
|'
print 100, '*********************'
do n=1,10
print 200,'| ',n,' |
',n*n,'
print*,
'---------------------'
enddo
200
format(1x,a2,i2,a8,i3,a6)
end

- 106 -

|'

6.2

EXERCIII CU EXPRESII ARITMETICE

6.2.1

S se scrie un program FORTRAN care calculeaz valorile expresiei


a + 2b
e=
dac a, b, c, i d iau toate valorile ntregi din intervalul [0,2].
cd

Soluie propus:
program expresie
! --- calculul valorii unei expresii in functie
!
de 4 variabile care parcurg un interval de nr. intregi
implicit none
integer a,b,c,d
integer i
! contor al nr. de operatii/linii
real e
!
initializare contor
i=0
!
4 cicluri DO imbricate
do 1 a=0,2
do 2 b=0,2
do 3 c=0,2
do 4 d=0,2
i=i+1
! --- se pune problema afisarii unui nr. dorit de linii pe ecran
!
adica derulare controlata a rezultatelor
! --- sa presupunem ca se doreste afisarea a cate 21 de linii
if(mod(i,21).eq.0) pause
! --- functia MOD testeaza daca i este multiplu de 21
! --- instructiunea PAUSE opreste temporar executia programului
! --- urmeaza acum un test de numitor nul
if(c.eq.d) then
write(*,*) 'a=',a,' b=',b,' c=',c,' d=',d,
&
'
e nu se poate calcula'
else
e=(a+2.0*b)/(c-d)
write(*,*) 'a=',a,' b=',b,' c=',c,' d=',d,'
-> e=',e
endif
4
continue
3
continue
2
continue
1
continue
! --- cite operatii s-au efectuat
write(*,'(//,1x,a14,i2,a9)')'s-au efectuat ',i,' operatii'
! --- pt. afisare au fost utilizati descriptori de format
end

6.2.2

S se scrie un program FORTRAN care calculeaz suma 12 + 22 + 32 + ... + 102.

Soluie propus:
program spatrat
! --- calculul sumei patratelor primelor 10 nr. naturale

- 107 -

implicit none
integer n
parameter (n=10)
! in F90, s-ar fi scris INTEGER,PARAMETER::n=10
integer s,i
s=0
do i=1,n
s=s+i*i
enddo
write(*,*) 'suma patratelor primelor ',n,' nr. naturale este : ',
&
s
end

6.2.3

S se scrie un program FORTRAN care calculeaz media aritmetic a primelor 10


numere naturale impare. Se cere deci calculul expresiei:
1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19
10

Soluie propus:
program medimpar
! --- calculul mediei aritmetice a primelor 10 nr. naturale impare
!
implicit none
integer n
parameter (n=10)
integer s,i
integer k !contor
s=0 !initializarea sumei
i=1 !initializarea primului nr. impar
k=1 !initializarea contorului
333
s=s+i
i=i+2
k=k+1
if(k.le.n) goto 333
write(*,*) 'media aritmetica a primelor ',n,
&
' nr. naturale impare este : ',s*1./n
end

6.2.4

S se scrie un program FORTRAN care decide dac un triunghi este echilateral, pe


baza coordonatelor vrfurilor.

Soluie propus:
program echilat
! --- decide daca un triunghi este echilateral
!
pe baza coordonatelor varfurilor
!
implicit none
real x1,y1,x2,y2,x3,y3
real l1,l2,l3

- 108 -

print*,'dati coordonatele varfurilor triunghiului :'


write(*,'(/,a3,$)')'x1='
read*,x1
write(*,'(a3,$)')'y1='
read*,y1
write(*,'(/,a3,$)')'x2='
read*,x2
write(*,'(a3,$)')'y2='
read*,y2
write(*,'(/,a3,$)')'x3='
read*,x3
write(*,'(a3,$)')'y3='
read*,y3
l1=sqrt((x2-x1)**2+(y2-y1)**2)
l2=sqrt((x2-x3)**2+(y2-y3)**2)
l3=sqrt((x3-x1)**2+(y3-y1)**2)
! urmeaza un exemplu de folosire periculoasa a operatorului .EQ.
! in realitate, nr. reale in calculator pot fi "egale" doar in
! limitele unei tolerante admise
if(l1.eq.l2.and.l2.eq.l3) then
print*
print*,'triunghiul ESTE echilateral'
else
print*
print*,'triunghiul NU ESTE echilateral'
endif
end

6.2.5

S se scrie un program FORTRAN care calculeaz valorile funciei:


f(x) = x2 + sin(x)
n intervalul [0,2], cu pasul 0,1.

Soluie propus:
program functie
! --- calculeaza valorile functiei x**2+sin(x) in [0,2]
!
cu pasul 0.1
!
implicit none
real x,y
integer i
do i=0,20,1
! este recomandabil a utiliza contor de tip intreg in ciclul DO
! chiar daca F90 accepta si contor nr. real, exista pericolul
! de a nu "inchide" ciclul DO
x=i/10.
y=x*x+sin(x)
write(*,'(a9,f3.1,a7,f8.6)')'pentru x=',x,' f(x)=',y
! mai simplu, se putea scrie neformatat
PRINT*,x,y
enddo
end

- 109 -

6.2.6

S se scrie un program FORTRAN care rezolv un sistem liniar de 2 ecuaii cu 2


necunoscute.

Soluie propus:
program sistem
! --- rezolva un sistem liniar 2x2, de tipul
!
ax+by=c
!
dx+ey=f
!
implicit none
real a,b,c,d,e,f
real delta,x,y
print*,'dati a,b,c din prima ecuatie : ax+by=c '
read*,a,b,c
print*,'dati d,e,f din a doua ecuatie : dx+ey=f '
read*,d,e,f
delta=a*e-b*d
if(delta.eq.0) then
if(b*f.eq.c*e) then
print*
print*,'sistemul este compatibil nedeterminat'
else
print*
print*,'sistemul este incompatibil'
endif
else
x=(c*e-b*f)/delta
y=(a*f-c*d)/delta
print*
print*,'sistemul este compatibil determinat'
print*,'x=',x
print*,'y=',y
endif
end

6.3

EXERCIII CU TABLOURI DE DATE

6.3.1

S se scrie un program FORTRAN care determin cte numere pare exist ntr-un
ir de n numere naturale. Seria de n numere naturale va fi introdus de la tastatur.

Soluie propus:
program par
! --- determina cate nr. pare exista intr-un sir de N nr. naturale
!
implicit none
integer a(50)
! dimensiunea maxima a sirului este 50
integer n
! dimensiunea efectiva a sirului va fi n
integer i,k
503
print*,'dati nr. de elemente din sir : N < 50'

- 110 -

read*,n
! --- verificare
if(n.lt.1.or.n.gt.50) goto 503
! --- introducerea elem. sirului
print*
print*,'Introduceti elem. sirului:'
print*
do i=1,n
write(*,'(1x,a2,i2,a2,$)') 'a(',i,')='
read(*,*) a(i)
enddo
! --- initializare contor
k=0
! --- determinarea nr. de elemente pare
do i=1,n
if(mod(a(i),2)==0) k=k+1
enddo
! --- afisarea rezultatului
print*
write(*,'(a26,i2,a9)')'In sirul introdus exista ',k,' nr. PARE'
print*
end

6.3.2

S se scrie un program FORTRAN care determin intersecia a dou mulimi


avnd fiecare m elemente numere ntregi.

Soluie propus:
program intersectie
! --- intersectia a 2 multimi A,B avand ambele M elemente intregi
!
implicit none
integer a(50),b(50),inters(50)
! dimensiunea maxima a multimilor
integer m
! dimensiunea efectiva a multimilor
integer i,j,k
999
print*,'dati dimensiunea efectiva a multimilor : M < 50'
read*,m
! --- sa ne asiguram ca utilizatorul respecta cerinta :
if(m.lt.1.or.m.gt.50) goto 999
! --- introducerea elem. multimii A
print*
print*,'Elem. multimii A (nr. intregi distincte, max. 3 cifre!):'
print*
do i=1,m
22
write(*,'(1x,a2,i2,a2,$)') 'a(',i,')='
read(*,*) a(i)
! --- verificarea prezentei elem. duble
do j=1,i-1
if(a(i).eq.a(j)) then
! exista elem. duble
print*,' *** Elementele trebuie sa fie toate distincte ***'
print*
goto 22
endif

- 111 -

! ---

33
! ---

! --! ---

! ---

6.3.3

enddo
enddo
introducerea elem. multimii B
print*
print*,'Elem. multimii B (nr. intregi distincte, max. 3 cifre!):'
print*
do i=1,m
write(*,'(1x,a2,i2,a2,$)') 'b(',i,')='
read(*,*) b(i)
verificarea prezentei elem. duble
do j=1,i-1
if(b(i).eq.b(j)) then
! exista elem. duble
print*,' *** Elementele trebuie sa fie toate distincte ***'
print*
goto 33
endif
enddo
enddo
initializare contor elemente comune
k=0
determinarea intersectiei
do i=1,m
do j=1,m
if(a(i).eq.b(j)) then
k=k+1
inters(k)=a(i)
endif
enddo
enddo
afisarea rezultatului
print*
print*,'Intersectia multimilor este :'
print*
if(k.ne.0) then
do i=1,k
write(*,'(i4,$)') inters(i)
enddo
else
print*,' vida'
endif
end

S se scrie un program FORTRAN care efectueaz produsul a dou matrici de


numere reale.

Soluie propus:
program produs
! --- produsul a 2 matrici reale AxB
*
A este de tip MxN
*
B este de tip NxP
!
implicit none

- 112 -

1
! --2
! ---

! --! ---

! ---

! ---

66
55
44
! ---

real a(50,40),b(40,60),prod(50,60)
! dimens. maxime ale matricilor
integer m,n,n2,p
! dimensiunile efective
integer i,j,k
print*,'dati dimensiunile efective ale matricii A : M<50,N<40'
read*,m,n
verificare dimensiuni A
if(m.lt.1.or.m.gt.50.or.n.lt.1.or.n.gt.40) goto 1
print*,'dati dimensiunile efective ale matricii B : N<40,P<60'
read*,n2,p
verificare compatibilitate
if(n.ne.n2) then
print*,'Inmultirea nu poate fi facuta !'
goto 1
endif
verificare dimensiuni B
if(p.lt.1.or.p.gt.60) goto 2
introducerea elem. matricii A
print*
print*,'Elementele matricii A :'
print*
do i=1,m
do j=1,n
write(*,'(1x,a2,i1,a1,i1,a2,$)') 'a(',i,',',j,')='
read(*,*) a(i,j)
enddo
enddo
introducerea elem. matricii B
print*
print*,'Elementele matricii B :'
print*
do i=1,n
do j=1,p
write(*,'(1x,a2,i1,a1,i1,a2,$)') 'b(',i,',',j,')='
read(*,*) b(i,j)
enddo
enddo
inmultirea propriu-zisa
do 44 i=1,m
do 55 j=1,p
prod(i,j)=0.
do 66 k=1,n
prod(i,j)=prod(i,j)+a(i,k)*b(k,j)
continue
continue
continue
afisarea rezultatului, pe linii
print*
print*,'Matricea produs AxB este :'
print*
do i=1,m
write(*,*) (prod(i,j),j=1,p)
enddo
end

- 113 -

6.3.4

S se scrie un program FORTRAN care determin cte elemente sunt pozitive,


negative, respectiv nule ntr-o matrice patrat nxn.

Soluie propus:
program inventar
! --- determina cate nr. >0,<0,=0 exista intr-o matrice NxN reala
!
implicit none
real a(50,50)
! dim maxima a matricii
integer n
! dimensiunea efectiva a matricii
integer i,j,plus,minus,zero
print*,'Dati dimensiunea efectiva a matricii A : N < 9'
read*,n
! --- introducerea elem. matricii A
print*
print*,'
Dati elementele matricii A :'
print*,'
... primul indice
-> linia'
print*,'
... al doilea indice
-> coloana'
print*
do i=1,n
do j=1,n
write(*,'(1x,a2,i1,a1,i1,a2,$)') 'a(',i,',',j,')='
read(*,*) a(i,j)
enddo
enddo
! --- initializare contori
plus=0
minus=0
zero=0
! --- inventar dupa semnul elementelor
do 4 i=1,n
do 5 j=1,n
if(a(i,j).gt.0.)then
plus=plus+1
elseif(a(i,j).lt.0.) then
minus=minus+1
else
zero=zero+1
endif
5
continue
4 continue
! --- afisarea rezultatului
print*
print*,' *** Rezultat inventar ***'
print*
print*,'Nr. pozitive : ',plus
print*,'Nr. negative : ',minus
print*,'Nr. nule : ',zero
end

- 114 -

6.3.5

S se scrie un program FORTRAN care determin cte elemente dintr-un ir de n


numere naturale sunt divizibile cu 3.

Soluie propus:
program diviz3
! --- determina cate nr. divizibile cu 3 exista intr-un
!
sir de N nr. naturale
!
implicit none
integer a(50)
! dim maxima a sirului
integer n
! dimensiunea efectiva a sirului
integer i,k
11
print*,'dati nr. de elemente din sir : N < 50'
read*,n
! --- verificare nr. elem. (utilizatorii pot sa nu fie atenti !!)
if(n.lt.1.or.n.gt.50) goto 11
! --- introducerea elem. sirului
print*
print*,'Introduceti elem. sirului:'
print*
do i=1,n
write(*,'(1x,a2,i2,a2,$)') 'a(',i,')='
read(*,*) a(i)
enddo
! --- initializare contor
k=0
! --- determinarea nr. de elemente divizibile cu 3
do i=1,n
if(mod(a(i),3)==0) k=k+1
enddo
! --- afisarea rezultatului
write(*,'(//,a26,i2,a20)')'In sirul introdus exista ',k,
+
' nr. DIVIZIBILE cu 3'
end

6.3.6

S se scrie un program FORTRAN care calculeaz media aritmetic a termenilor


irului de numere reale x1, x2, ..., xn cuprini ntre a i b, a < b (reali).

Soluie propus:
program sirmedie
! --- calculeaza media elem. dintr-un sir, cuprinse intre A si B
!
implicit none
real x(50)
! dim maxima a sirului
integer n
! dimensiunea efectiva a sirului
integer i,k
real a,b
! intervalul [A,B]
real suma,media
113
print*,'dati nr. de elemente din sir : N < 50'
read*,n
! --- verificare nr. elem. (utilizatorii pot sa greseasca !!)

- 115 -

if(n.lt.1.or.n.gt.50) goto 113


! --- introducerea elem. sirului
print*
print*,'Introduceti elem. sirului:'
print*
do i=1,n
write(*,'(1x,a2,i2,a2,$)') 'x(',i,')='
read(*,*) x(i)
enddo
! --- introducerea capetelor intervalului de control [A,B]
888
print*
print*,' Dati capetele intervalului [A,B]:'
write(*,'(/,5x,a2,$)') 'A='
read*,a
write(*,'(/,5x,a2,$)') 'B='
read*,b
! --- verificare A<B
if(a.ge.b) goto 888
! --- initializare contor pt. elemente ; initializare suma
k=0
suma=0
! --- determinarea nr. de elemente care se gasesc in intervalul [A,B]
do i=1,n
if((x(i).ge.a).and.(x(i).le.b)) then
k=k+1
suma=suma+x(i)
endif
enddo
!
media=suma/k
!
! --- afisarea rezultatului
print*
if(k.ne.0)then
print*
print*,'Media elem. din [A,B] este :',media
else
print*
print*,'Nu exista nici un elem. al sirului in [A,B] !!'
print*,'
deci media lor nu se poate calcula'
endif
end

6.3.7

Se introduce de la tastatur un ir de n numere ntregi. S se scrie un program


FORTRAN care calculeaz produsul elementelor mai mici dect 100 i suma celor
mai mari dect 10.

Soluie propus:
program sirSP
! --- calculeaza suma, respectiv produsul elem. dintr-un sir
!
care satisfac anumite conditii
!
implicit none

- 116 -

116
! --! ---

! --! --! ---

! ---

integer a(30)
! dim maxima a sirului
integer n
! dimensiunea efectiva a sirului
integer i,ks,kp
real suma,prod
! produsul poate genera usor OVERFLOW in INTEGER
print*,'dati nr. de elemente din sir : N < 30'
read*,n
verificare nr. elem.
if(n.lt.1.or.n.gt.30) goto 116
introducerea elem. sirului
print*
print*,'Introduceti elem. sirului (nr. intregi !):'
print*
do i=1,n
write(*,'(1x,a2,i2,a2,$)') 'a(',i,')='
read(*,*) a(i)
enddo
initializare contori pt. elemente
ks=0
kp=0
initializare suma si produs
suma=0.
prod=1.
determinarea nr. de elemente pt. care calculez suma si prod
do i=1,n
if(a(i).gt.10) then
ks=ks+1
suma=suma+a(i)
endif
if(a(i).lt.100) then
kp=kp+1
prod=prod*a(i)
endif
enddo
afisarea rezultatului
print*
if(ks.ne.0)then
print*
print*,'Suma elem. >10 este :',suma
else
print*
print*,'Nu exista nici un elem. >10 in sir !!'
print*,' deci suma lor nu se poate calcula'
endif

!
print*
if(kp.ne.0)then
print*
print*,'Produsul elem. <100 este :',prod
else
print*
print*,'Nu exista nici un elem. <100 in sir !!'
print*,' deci produsul lor nu se poate calcula'
endif
end

- 117 -

6.3.8

S se scrie un program FORTRAN care genereaz transpusa unei matrici de


dimensiuni nxn.

Soluie propus:
program transp
! --- transpusa unei matrici reale NxN
!
implicit none
real a(50,50),at(50,50)
! dim maxima a matricilor
integer n
! dim efectiva
integer i,j
1
print*,'dati dimens. efectiva a matricii patrate A: N < 50'
read*,n
! --- verificare
if(n.lt.1.or.n.gt.50) goto 1
! --- introducerea elem. matricii A, linie dupa linie
print*
print*,'
Dati elementele matricii A, pe linii :'
print*,'...deci cate n valori despartite de spatiu sau virgula'
print*,'
apoi <Enter>'
print*
do i=1,n
read(*,*) (a(i,j),j=1,n)
enddo
! --- generarea matricii transpuse
do 44 i=1,n
do 55 j=1,n
at(i,j)=a(j,i)
55 continue
44 continue
! --- afisarea rezultatului, pe linii
print*
print*,'Matricea transpusa este :'
print*
do i=1,n
write(*,*) (at(i,j),j=1,n)
enddo
end

6.3.9

S se scrie un program FORTRAN care determin elementul maxim dintr-un ir


de n numere naturale.

Soluie propus:
program emaxim
! --- determina elem. MAXIM dintr-un sir de N nr. naturale
!
implicit none
integer a(50)
! dim maxima a sirului
integer n
! dimensiunea efectiva a sirului
integer i,emax
50
print*,'dati nr. de elemente din sir : N < 50'

- 118 -

read*,n
! --- verificare
if(n.lt.1.or.n.gt.50) goto 50
! --- introducerea elem. sirului
print*
print*,'Introduceti elem. sirului:'
print*
do i=1,n
write(*,'(1x,a2,i2,a2,$)') 'a(',i,')='
read(*,*) a(i)
enddo
! --- initializare
emax=a(1)
! --- determinarea elem. MAXIM
do i=2,n
if(emax.lt.a(i)) emax=a(i)
enddo
! --- afisarea rezultatului
print*
print*,'Elementul maxim din sir este : ',emax
print*
end

6.3.10

Folosind problema precedent, s se scrie un program FORTRAN care ordoneaz


descresctor un ir de n numere naturale.

Soluie propus:
program ordsir
! --- ordoneaza descrescator un sir de N nr. naturale
!
implicit none
integer a(50)
! dim maxima a sirului
integer n
! dimensiunea efectiva a sirului
integer i,j,emax,idxmax
50
print*,'dati nr. de elemente din sir : N < 50'
read*,n
! --- verificare
if(n.lt.1.or.n.gt.50) goto 50
! --- introducerea elem. sirului
print*
print*,'Introduceti elem. sirului:'
print*
do i=1,n
write(*,'(1x,a2,i2,a2,$)') 'a(',i,')='
read(*,*) a(i)
enddo
! --- ordonare
do i=1,n-1
emax=a(i)
idxmax=i
do j=i+1,n
if(emax.lt.a(j)) then
emax=a(j)

- 119 -

idxmax=j
endif
enddo
! manevra SWAP
a(idxmax)=a(i)
a(i)=emax
enddo
! --- afisarea rezultatului
print*
print*,'Sirul ordonat descrescator este : ',(a(i),i=1,n)
print*
end

6.3.11

S se scrie un program FORTRAN care ordoneaz cresctor un ir de n numere


reale prin interschimbarea elementelor consecutive.

Soluie propus:
program ordswap
! --- ordoneaza crescator un sir de N nr. reale prin interschimbare
!
implicit none
real a(30)
! dim maxima a sirului
integer n
! dimensiunea efectiva a sirului
integer i
logical flag
real manevr
30
print*,'dati nr. de elemente din sir : N < 31'
read*,n
! --- verificare
if(n.lt.1.or.n.gt.30) goto 30
! --- introducerea elem. sirului
print*
print*,'Introduceti elem. sirului:'
print*
do i=1,n
write(*,'(1x,a2,i2,a2,$)') 'a(',i,')='
read(*,*) a(i)
enddo
! --- ordonare prin interschimbare
1000 flag=.true.
! sirul este ordonat daca flag nu se mai modifica
do i=1,n-1
if(a(i).gt.a(i+1)) then
flag=.false. ! adica sirul nu este inca ordonat
! urmeaza SWAP (interschimbare), cu variabila de manevra
manevr=a(i+1)
a(i+1)=a(i)
a(i)=manevr
endif
enddo
if(flag.eqv..false.) goto 1000
! --- afisarea rezultatului
print*
print*,'Sirul ordonat crescator este : ',(a(i),i=1,n)

- 120 -

print*
end

6.3.12

S se scrie un program FORTRAN care ordoneaz elevii unei clase n ordinea


descresctoare a mediilor. Datele se vor introduce de la tastatur.

Soluie propus:
program clasa
! --- ordoneaza elevii unei clase in ordinea descrescatoare a mediilor
!
implicit none
character*30 nume(40) ! max 40 elevi, nume+pren. max 30 caractere
real media(40)
integer n
! dimensiunea efectiva a clasei
integer i,j,pozitia
real medmax
character*30 manevra
300
print*,'dati nr. de elevi din clasa : N < 41'
read*,n
! --- verificare
if(n.lt.1.or.n.gt.40) goto 300
! --- introducerea elem. sirului
print*
print*,'Introduceti elevii si mediile lor:'
print*
do i=1,n
write(*,'(/,a7,i2,a3,$)') 'Elevul ',i,' : '
read(*,'(a)') nume(i) !format pentru lungime oarecare
! in executie, se vor introduce fara apostrof nume+prenume
write(*,'(a10,a30,a3,$)') 'Media lui ',nume(i),' : '
read*, media(i)
enddo
! --- ordonare dupa medii
do i=1,n-1
medmax=media(i)
pozitia=i
do j=i+1,n
if(medmax.lt.media(j)) then
medmax=media(j)
pozitia=j
endif
enddo
! manevra de interschimbare
media(pozitia)=media(i)
media(i)=medmax
! se deplaseaza si numele la noua pozitie
manevra=nume(i)
nume(i)=nume(pozitia)
nume(pozitia)=manevra
enddo
! --- afisarea rezultatului
print '(//)'
print*,'
Elevii ordonati in ordinea mediilor :'

- 121 -

print*
do i=1,n
print '(1x,i2,a2,a30,a8,f5.2)',i,'. ',nume(i),' Media: ',media(i)
enddo
end

6.3.13

S se scrie un program FORTRAN care determin cel mai mic element dintr-o
matrice cu numere ntregi, de dimensiuni mxn.

Soluie propus:
program minmatr
! --- determina elem. MINIM dintr-o matrice MxN de nr. intregi
!
implicit none
integer a(40,30)
! dim maxima a matricii
integer m,n
! dimensiunile efective ale matricii
integer i,j,emin
1
print*,'dati dimensiunile efective ale matricii : M<40,N<30'
read*,m,n
! --- verificare dimensiuni A
if(m.lt.1.or.m.gt.40.or.n.lt.1.or.n.gt.30) goto 1
! --- introducerea elem. matricii A
print*
print*,'
Dati elementele matricii (nr. INTREGI):'
print*,'
... primul indice
-> linia'
print*,'
... al doilea indice
-> coloana'
print*
do i=1,m
do j=1,n
write(*,'(1x,a2,i1,a1,i1,a2,$)') 'a(',i,',',j,')='
read(*,*) a(i,j)
enddo
enddo
! --- initializare
emin=a(1,1)
! --- determinare MINIM
do 4 i=1,m
do 5 j=1,n
if(a(i,j).lt.emin) emin=a(i,j)
5
continue
4 continue
! --- afisarea rezultatului
print*
print*,'Elementul MINIM al matricii este: ',emin
end

- 122 -

6.3.14

S se scrie un program FORTRAN care nlocuiete elementul maxim de pe fiecare


coloan a unei matrici mxn cu suma elementelor de pe coloana respectiv.

Soluie propus:
program sumcol
! --- se inlocuieste elem. MAXIM de pe fiecare coloana a unei
!
matrici reale MxN cu suma elem. de pe coloana respectiva
!
implicit none
real a(40,30)
! dim maxima a matricii
integer m,n
! dim efectiva
integer i,j,idx
real emax,suma
1
print*,'dati dimensiunile efective ale matricii : M<40,N<30'
read*,m,n
! --- verificare dimensiuni A
if(m.lt.1.or.m.gt.40.or.n.lt.1.or.n.gt.30) goto 1
! --- introducerea elem. matricii A, linie dupa linie
print*
print*,'
Dati elementele matricii A, pe linii :'
print*,'...deci cate n valori despartite de spatiu sau virgula'
print*,'
apoi <Enter>'
print*
do i=1,m
read(*,*) (a(i,j),j=1,n)
enddo
! --- prelucrare
do 44 j=1,n
! este convenabila parcurgerea pe coloane
emax=a(1,j)
idx=1
suma=a(1,j)
do 55 i=2,m
suma=suma+a(i,j)
if(a(i,j).gt.emax) then
emax=a(i,j)
idx=i
endif
55 continue
a(idx,j)=suma
! dar pentru mai multe maxime egale ?
! studiati acest caz particular si
! modificati programul
44 continue
! --- afisarea rezultatului, pe linii
print '(//)'
print*,'Matricea modificata este :'
print*
do i=1,m
write(*,*) (a(i,j),j=1,n)
enddo
end

- 123 -

6.4

EXERCIII CU SUBPROGRAME

6.4.1

S se scrie un program FORTRAN care calculeaz suma 1!+2!+3!+...+10!. Se va


utiliza un subprogram de tip FUNCTION pentru calculul lui n!.

Soluie propus:
program sumfact
! --- calculul sumei factorialelor primelor 10 nr. naturale
!
utilizand FUNCTION
!
implicit none
integer n
parameter (n=10) !in F90, s-ar fi scris INTEGER,PARAMETER::n=10
integer fact,s,i
s=0
do 55 i=1,n
s=s+fact(i)
55
continue
write(*,*) 'suma factorialelor primelor ',n,
&
' nr. naturale este : ',s
end
integer function fact(n)
! mai corect ar fi REAL function, caci exista pericol de Overflow
integer n,j,i
j=1
do i=1,n
j=j*i
enddo
fact=j
return
end

6.4.2

S se scrie un program FORTRAN care calculeaz perimetrul i aria unui patrat de


latura L, n 3 variante: folosind funcie definit aritmetic, funcie definit ca modul
(FUNCTION), respectiv subprogram (SUBROUTINE).

Soluie propus (utiliznd funcie definit aritmetic):


program patrat1
! --- calculul perimetrului si ariei unui patrat de latura L
!
utilizand o functie definita aritmetic
!
implicit none
real aria,perim,latura
real a,p,l
! --- aici se definesc aritmetic 2 functii cu parametrul formal LATURA
perim(latura)=4*latura
aria(latura)=latura**2
!
print*, 'Dati latura patratului :'

- 124 -

read*,l
! --- la apel, se inlocuieste parametrul formal cu cel efectiv L
!
rezultatul este returnat prin intermediul numelui functiei
p=perim(l)
a=aria(l)
! --- afisare rezultate
print*
print*
write(*,*) 'Perimetrul patratului de latura ',l,' este : ',p
write(*,*) 'Aria patratului de latura ',l,' este : ',a
end

Soluie propus (utiliznd FUNCTION):


program patrat2
! --- calculul perimetrului si ariei unui patrat de latura L
!
utilizand FUNCTION
!
implicit none
real aria,perim
real p,a,l
print*, 'Dati latura patratului :'
read*,l
! --- la apel, se inlocuieste parametrul formal cu cel efectiv L
!
rezultatul este returnat prin intermediul numelui functiei
p=perim(l)
a=aria(l)
! --- afisare rezultate
print*
print*
write(*,*) 'Perimetrul patratului de latura ',l,' este : ',p
write(*,*) 'Aria patratului de latura ',l,' este : ',a
end
real function perim(latura)
real latura
perim=4*latura
end
real function aria(latura)
real latura
aria=latura**2
end

Soluie propus (utiliznd SUBROUTINE):


program patrat3
! --- calculul perimetrului si ariei unui patrat de latura L
!
utilizand SUBROUTINE
!
implicit none
real l,p,a
print*, 'Dati latura patratului :'
read*,l
! --- la apel, se inlocuiesc parametrii formali cu cei efectivi

- 125 -

!
!

parametrul de intrare este l


rezultatul este returnat prin parametrii p,a (de iesire)
call calcul(l,p,a)
! --- afisare rezultate
print*
print*
write(*,*) 'Perimetrul patratului de latura ',l,' este : ',p
write(*,*) 'Aria patratului de latura ',l,' este : ',a
end
subroutine calcul(latura,perim,aria)
real latura,perim,aria
perim=4*latura
aria=latura**2
end

6.4.3

S se scrie un program FORTRAN care transform un numr din baza 2 n baza


10, folosind un subprogram de tip SUBROUTINE.

Soluie propus:
program trans2_10
! --- converteste un nr. din baza 2 in baza 10
!
utilizand SUBROUTINE
!
implicit none
character*20 nrbin
integer nrzece
write(*,*)'Transformarea unui nr. din baza 2 in baza 10'
666
write(*,*)
write(*,*) 'Dati nr. binar (max 20 cifre, doar 0 si 1): '
read(*,'(a)')nrbin
call tr210(nrbin,nrzece)
if(nrzece.eq.-1) goto 666
! input gresit
write(*,*) 'Nr. in baza 10 este : ',nrzece
end
subroutine tr210(doi,zece)
character*(*) doi
integer zece
integer cifre,i,aport
! --- initializare
cifre=0
zece=0
! --- determinare nr. de cifre
do i=len(doi),1,-1 ! LEN determina lungimea var. tip caracter
if(doi(i:i).ne.' ') goto 888
! test subsir de 1 caracter
enddo
888
cifre=i
! --- validare cifre (in nr. binar sa fie numai 0 sau 1 !!)
if(cifre.eq.0.or.doi(1:1).eq.'0') then
print*, ' Numar gresit ! '
zece=-1
goto 77

- 126 -

endif
! --- transformare
do i=1,cifre
if(doi(i:i).eq.'0') then
aport=0
elseif(doi(i:i).eq.'1') then
aport=2**(cifre-i)
zece=zece+aport
else
print*, ' Numar gresit ! '
zece=-1
exit
! iesire fortata din DO
endif
enddo
77
return
end

6.4.4

S se scrie un program FORTRAN care calculeaz cel mai mare divizor comun a
dou numere naturale, pe baza algoritmului lui Euclid. Se va utiliza un subprogram
de tip FUNCTION.

Soluie propus:
program divcom
! --- determina CMMDC a 2 nr. naturale nenule
!
utilizand subprogram FUNCTION
!
implicit none
integer a,b
integer cmmdc
44
print*,'Dati primul nr. natural : '
read*,a
if(a.le.0) then
print*, 'NUMAR GRESIT !'
goto 44
endif
55
write(*,*) 'Dati al doilea nr. natural : '
read(*,*)b
if(b.le.0) then
print*, 'NUMAR GRESIT !'
goto 55
endif
print '(//)'
write(*,*) 'Cel mai mare divizor comun este : ',cmmdc(a,b)
end

integer function cmmdc(nr1,nr2)


integer nr1,nr2,x,y,rest
x=nr1
y=nr2
rest=mod(x,y)
if(rest.ne.0) then
x=y
y=rest

- 127 -

rest=mod(x,y)
goto 1
else
cmmdc=y
endif
end

6.4.5

S se scrie un program FORTRAN care afieaz toate numerele prime mai mici
dect 1000. Se va utiliza un subprogram de tip SUBROUTINE.

Soluie propus:
program nrprime
! --- determina toate nr. prime mai mici decat 1000
!
folosind subprogram SUBROUTINE
!
implicit none
integer limita
parameter (limita=1000)
print*, ' Nr. prime de la 1 la ',limita,' sunt : '
print*
print '(1x,i3,1x,i3,1x,$)',1,2
! primele 2 nr. prime
call prim(limita)
end
subroutine prim(limsup)
integer limsup,i,j,k
logical iprim
do i=3,limsup,2 ! nr. prime sunt o submultime a celor impare
iprim=.true.
j=int(sqrt(i*1.))
! SQRT cere argument real
! j este limita pana la care caut divizori
do k=2,j
if(mod(i,k)==0) then
iprim=.false.
exit
! iesire fortata din DO
endif
enddo
if(iprim.eqv..true.) then
write(*,'(1x,i3,$)')i
endif
enddo
end

- 128 -

6.4.6

S se scrie un program FORTRAN care determin ctul i restul mpririi unui


polinom de grad n la binomul (X-a), folosind schema lui Horner. Se va utiliza un
subprogram de tip SUBROUTINE.

Soluie propus:
program polinom
! --- determina catul si restul impartirii unui polinom P(x) la (X-a)
!
folosind subprogram SUBROUTINE pt. schema lui Horner
!
implicit none
real a(0:30)
! sirul coeficientilor polinomului P(X)
real b(0:29)
! sirul coeficientilor catului Q(X)
integer n
! gradul polinomului P(X), n<30
real rest,alfa
integer i
90
print '(a35,$)', ' Dati gradul polinomului P (n<30): '
read*,n
if(n.lt.1.or.n.gt.30) goto 90
print*
print*,'Dati coef. lui P in ordine descr. a puterilor lui X :'
print*
do i=n,0,-1
print '(a15,i2,a8,$)','- coef. lui X**',i,' este : '
read*,a(i)
enddo
print*
print '(a44,$)', ' Dati coeficientul "a" al binomului (X-a) : '
read*,alfa
! --- apel
call horner(a,b,n,alfa,rest)
! --- afisare rezultat
print '(//)'
print*,'
************ REZULTAT **************'
print*
print*,'Coef. catului, in ordine descr. a puterilor lui X :'
print*
do i=n-1,0,-1
print '(a15,i2,a8,f7.3)','- coef. lui X**',i,' este : ',b(i)
enddo
print*
print*, 'Restul impartirii lui P la (X-',alfa,') este :',rest
end
subroutine horner(p,q,gradp,a,r)
integer gradp,i
real p(0:gradp),q(0:(gradp-1))
real a,r
q(gradp-1)=p(gradp)
do i=gradp-2,0,-1
q(i)=q(i+1)*a+p(i+1)
enddo
r=q(0)*a+p(0)
end

- 129 -

6.5

EXERCIII CU INTRRI/IEIRI FOLOSIND FIIERE

6.5.1

S se modifice soluia propus pentru problema 6.2.1, folosind un fiier de ieire


pentru rezultate, n locul afirii pe ecran. Fiierul creat se va numi L51.REZ.

Soluie propus:
program expresie
! --- calculul valorii unei expresii in functie
!
de 4 variabile care parcurg un interval de nr. intregi
!
foloseste FISIER de iesire pentru rezultate
!
implicit none
integer a,b,c,d
integer i
!contor al nr. de operatii/linii
real e
!
initializare contor
i=0
!
deschidere fisier pentru rezultate
open(1,file='l51.rez',status='unknown')
!
4 cicluri DO
do 1 a=0,2
do 2 b=0,2
do 3 c=0,2
do 4 d=0,2
i=i+1
! --- urmeaza acum un test de numitor nul
if(c.eq.d) then
write(1,456) 'a=',a,' b=',b,' c=',c,' d=',d,
&
'
e nu se poate calcula'
else
e=(a+2.0*b)/(c-d)
write(1,567) 'a=',a,' b=',b,' c=',c,' d=',d,'
-> e=',e
endif
4
continue
3
continue
2
continue
1
continue
!
inchidere fisier
close(1)
! --- se afiseaza (pe ecran) cite operatii s-au efectuat
write(*,'(//,1x,a14,i2,a9)') 's-au efectuat ',i,' operatii'
456
format(a2,i1,a3,i1,a3,i1,a3,i1,a25)
567
format(a2,i1,a3,i1,a3,i1,a3,i1,a9,f7.3)
end

Not:

Coninutul fiierului de rezultate L51.REZ se gsete n anexa A-1.

- 130 -

6.5.2

S se modifice soluia propus pentru problema 6.2.5, folosind un fiier de ieire


pentru rezultate, n locul afirii pe ecran. Fiierul rezultat se va numi L52.REZ.

Soluie propus:
program functie
! --- calculeaza valorile functiei x**2+sin(x) in [0,2]
!
cu pasul 0.1
!
foloseste FISIER de iesire pentru rezultate
!
implicit none
real x,y
integer i
!
deschidere fisier de iesire
open(2,file='l52.rez',status='unknown')
!
ciclul DO
do i=0,20,1
! este recomandabil a utiliza contor de tip intreg in ciclul DO
! chiar daca F90 accepta si contor nr. real, rezultatele pot fi
! eronate
x=i/10.
y=x*x+sin(x)
write(2,'(a9,f3.1,a7,f8.6)')'pentru x=',x,' f(x)=',y
! mai simplu, se putea scrie neformatat
PRINT*,x,y
enddo
!
inchidere fisier
close(2)
end

Not:

Coninutul fiierului L52.REZ cu rezultate se gsete n anexa A-2.

6.5.3

S se modifice soluia propus pentru problema 6.3.3, folosind un fiier de intrare


pentru cele dou matrici i un fisier de ieire pentru rezultat. Fiierul cu datele de
intrare se va numi L53.DAT iar cel cu rezultate L53.REZ.

Soluie propus:
program produs
! --- produsul a 2 matrici reale AxB
!
A este de tip MxN
!
B este de tip NxP
!
foloseste un FISIER pentru input (cele 2 matrici)
!
un FISIER pentru output (matricea produs)
!
implicit none
real a(50,40),b(40,60),prod(50,60)
! dim maxima a matricilor
integer m,n,n2,p
! dimensiunile efective
integer i,j,k
character*26 separa
! --- deschidere fisier de date
open(1,file='l53.dat',status='old')
! --- citire dimens. efective ale matricii A

- 131 -

read(1,*) m,n
! --- verificare dimensiuni A
if(m.lt.1.or.m.gt.50.or.n.lt.1.or.n.gt.40) goto 1
! --- citire dimens. efective ale matricii B
read(1,*) n2,p
! --- verificare compatibilitate
if(n.ne.n2) then
print*,'Inmultirea nu poate fi facuta ! Date ERONATE'
stop
endif
! --- verificare dimensiuni B
if(p.lt.1.or.p.gt.60) goto 2
! --- citire separator
read(1,*) separa
! --- citire elem. matricii A, linie cu linie
do i=1,m
read(1,*) (a(i,j),j=1,n)
enddo
! --- citire separator
read(1,*) separa
! --- citire elem. matricii B, linie cu linie
do i=1,n
read(1,*) (b(i,j),j=1,p)
enddo
! --- inchidere fisier de intrare date
close(1)
! --- inmultirea propriu-zisa
do 44 i=1,m
do 55 j=1,p
prod(i,j)=0.
do 66 k=1,n
prod(i,j)=prod(i,j)+ a(i,k)*b(k,j)
66
continue
55 continue
44 continue
! --- deschidere fisier de iesire (rezultat=matricea produs)
open(2,file='l53.rez',status='unknown')
! --- afisarea rezultatului, pe linii
write(2,*)
write(2,*)'Matricea produs AxB este :'
write(2,*)separa
write(2,*)
do i=1,m
write(2,*) (prod(i,j),j=1,p)
enddo
! --- inchidere fisier de rezultate
close(2)
stop
! --- tratarea erorilor din fisierul de intrare
1
print*,'EROARE DATE : dim. efective pt. matr. A vor fi M<50,N<40'
stop
2
print*,'EROARE DATE : dim. efective pt. matr. B vor fi N<40,P<60'
stop
end

Not:

n anexa A-3 este prezentat un exemplu pentru coninutul fiierului de date


L53.DAT urmat de coninutul fiierului rezultat L53.REZ corespunztor.
- 132 -

6.5.4

S se modifice soluia propus pentru problema 6.4.5, folosind un fiier de ieire


numit T54.REZ pentru rezultate, n condiiile n care trebuie determinate toate
numerele prime pn la 10000.

Soluie propus:
program prim_fisier
! --- determina toate nr. prime mai mici decat 10000
!
si scrie rezultatul intr-un fisier
!
implicit none
integer limita,fis
parameter (limita=10000)
parameter (fis=1)
open(fis,file='t54.rez',status='unknown')
write(fis,*) ' Nr. prime de la 1 la ',limita,' sunt : '
write(fis,*)
write(fis,'(1x,i5,1x,i5,1x,$)') 1,2
! primele 2 nr. prime
call prim(limita,fis)
close(fis)
end
subroutine prim(limsup,fisier)
integer limsup,i,j,k,fisier
logical iprim
do i=3,limsup,2
! nr. prime sunt o submultime a celor impare
iprim=.true.
j=int(sqrt(i*1.)) ! SQRT cere argument real
! j este limita pana la care caut divizori
do k=2,j
if(mod(i,k)==0) then
iprim=.false.
exit
! iesire fortata din DO
endif
enddo
if(iprim.eqv..true.) then
write(fisier,'(1x,i5,$)')i
endif
enddo
end

Not:

Coninutul fiierului de rezultate T54.REZ este prezentat n anexa A-4.

6.5.5

S se modifice soluia propus pentru problema 6.3.12, folosind un fiier de intrare


numit T55.DAT pentru date i un fisier de ieire numit T55.REZ pentru
rezultate.

Soluie propus:
program clasa_fisier
! --- ordoneaza elevii unei clase in ordinea descrescatoare a mediilor
!
utilizand fisiere pt. input, respectiv output

- 133 -

! --! --788

500
! ---

! ---

44

Not:

implicit none
integer nmax
parameter (nmax=40)
character*30 nume(nmax) !max NMAX elevi, nume+pren. max 30 caract.
real media(nmax)
integer n
! dimensiunea efectiva a clasei
integer i,j,pozitia
real medmax
character*30 manevra
character*1 separator
initializare nr. inregistrari in fisier
n=0
citirea datelor din fisier
open(1,file='t55.dat',status='old')
read(1,'(a30,a1,f5.2)',END=500)nume(n+1),separator,media(n+1)
! daca se atinge END OF FILE se continua cu CLOSE(1)
n=n+1
! verificare nr. elevi
if(n.gt.nmax) then
print*,'EROARE : fisierul contine mai mult de 40 nume elevi !'
stop !gata
else
goto 788 !se continua cu un nou elev
endif
close(1)
ordonare dupa medii
do i=1,n-1
medmax=media(i)
pozitia=i
do j=i+1,n
if(medmax.lt.media(j)) then
medmax=media(j)
pozitia=j
endif
enddo
! manevra de interschimbare
media(pozitia)=media(i)
media(i)=medmax
! se deplaseaza si numele la noua pozitie
manevra=nume(i)
nume(i)=nume(pozitia)
nume(pozitia)=manevra
enddo
fisierul de rezultate
open(2,file='t55.rez',status='unknown')
write(2,'(//)')
write(2,*)'
Elevii ordonati in ordinea mediilor :'
write(2,'(//)')
do i=1,n
write(2,44)i,'. ',nume(i),' Media: ',media(i)
format(1x,i2,a2,a30,a8,f5.2)
enddo
close(2)
end

n anexa A-5 se prezint coninutul fiierelor T55.DAT i T55.REZ.

- 134 -

6.6

EXERCIII DIVERSE

6.6.1

S se scrie un program FORTRAN care simuleaz aruncarea simultan a 2 zaruri.

Soluie propus:
program zaruri
! --- simularea aruncarii simultane a 2 zaruri
!
implicit none
real r(2)
integer zar(2),i
!initializare generator de numere pseudoaleatoare
r(1) = RAND(TIME())
!
do i=1,2
r(i) = RAND(0)
zar(i)=int(6*r(i))+1
print*,zar(i)
enddo
end
! Varianta scrisa in Fortran 90 standard
!
!
program zaruri
!
implicit none
!
real,dimension(2)::r
!
integer,dimension(2)::zar
!
integer::i
!
call random_seed()
!
call random_number(r)
!
do i=1,2
!
zar(i)=int(6*r(i))+1
!
print*,zar(i)
!
enddo
!
end program zaruri

6.6.2

S se scrie un program FORTRAN cu ajutorul cruia s se simuleze o extragere


LOTO 6/49.

Soluie propus:
program loto
! --- simuleaza o extragere LOTO 6/49
!
implicit none
integer nmax,cite,idx,i,manevra
parameter(nmax=49)
parameter(cite=6)
integer sir(nmax)
real r(nmax)
! initializare generator de numere pseudoaleatoare

- 135 -

r(1)=rand(time())
! initializare sir de numere intregi de la 1 la 49
do i=1,nmax
sir(i) = i
enddo
! extragere (fara repetarea vreunui nr. !)
do i=1,cite
r(i)=rand(0)
idx = INT(r(i) * (nmax - i + 1)) + i
manevra=sir(i)
sir(i)=sir(idx)
sir(idx)=manevra
print*, sir(i)
enddo
end

- 136 -

6.7

ANEXE

A-1

Coninutul fiierului de rezultate L51.REZ de la exerciiul 6.5.1:

a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=0
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1
a=1

b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=2
b=2
b=2
b=2
b=2
b=2
b=2
b=2
b=2
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=2
b=2
b=2
b=2
b=2
b=2
b=2

c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2

d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0

e nu se poate
-> e= 0.000
-> e= 0.000
-> e= 0.000
e nu se poate
-> e= 0.000
-> e= 0.000
-> e= 0.000
e nu se poate
e nu se poate
-> e= -2.000
-> e= -1.000
-> e= 2.000
e nu se poate
-> e= -2.000
-> e= 1.000
-> e= 2.000
e nu se poate
e nu se poate
-> e= -4.000
-> e= -2.000
-> e= 4.000
e nu se poate
-> e= -4.000
-> e= 2.000
-> e= 4.000
e nu se poate
e nu se poate
-> e= -1.000
-> e= -0.500
-> e= 1.000
e nu se poate
-> e= -1.000
-> e= 0.500
-> e= 1.000
e nu se poate
e nu se poate
-> e= -3.000
-> e= -1.500
-> e= 3.000
e nu se poate
-> e= -3.000
-> e= 1.500
-> e= 3.000
e nu se poate
e nu se poate
-> e= -5.000
-> e= -2.500
-> e= 5.000
e nu se poate
-> e= -5.000
-> e= 2.500

calcula

calcula

calcula
calcula

calcula

calcula
calcula

calcula

calcula
calcula

calcula

calcula
calcula

calcula

calcula
calcula

calcula

- 137 -

a=1
a=1
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2
a=2

b=2
b=2
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=0
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=1
b=2
b=2
b=2
b=2
b=2
b=2
b=2
b=2
b=2

c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2
c=0
c=0
c=0
c=1
c=1
c=1
c=2
c=2
c=2

d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2
d=0
d=1
d=2

-> e= 5.000
e nu se poate
e nu se poate
-> e= -2.000
-> e= -1.000
-> e= 2.000
e nu se poate
-> e= -2.000
-> e= 1.000
-> e= 2.000
e nu se poate
e nu se poate
-> e= -4.000
-> e= -2.000
-> e= 4.000
e nu se poate
-> e= -4.000
-> e= 2.000
-> e= 4.000
e nu se poate
e nu se poate
-> e= -6.000
-> e= -3.000
-> e= 6.000
e nu se poate
-> e= -6.000
-> e= 3.000
-> e= 6.000
e nu se poate

calcula
calcula

calcula

calcula
calcula

calcula

calcula
calcula

calcula

calcula

A-2

Coninutul fiierului de rezultate L52.REZ de la exerciiul 6.5.2:

pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru
pentru

x=0.0
x=0.1
x=0.2
x=0.3
x=0.4
x=0.5
x=0.6
x=0.7
x=0.8
x=0.9
x=1.0
x=1.1
x=1.2
x=1.3
x=1.4
x=1.5
x=1.6
x=1.7
x=1.8
x=1.9
x=2.0

f(x)=0.000000
f(x)=0.109833
f(x)=0.238669
f(x)=0.385520
f(x)=0.549418
f(x)=0.729426
f(x)=0.924643
f(x)=1.134218
f(x)=1.357356
f(x)=1.593327
f(x)=1.841471
f(x)=2.101207
f(x)=2.372039
f(x)=2.653558
f(x)=2.945450
f(x)=3.247495
f(x)=3.559574
f(x)=3.881665
f(x)=4.213847
f(x)=4.556300
f(x)=4.909297

- 138 -

A-3

Pentru exerciiul 6.5.3:

Exemplu de fiier cu date (L53.DAT) pentru exerciiul 6.5.3:


2,2
2,3
===================
1 2
3 4
===================
5 6 7
8 9 5

Coninutul fiierului cu rezultate (L53.REZ) de la exerciiul 6.5.3:


Matricea produs AxB este :
===================
21.
47.

A-4

24.
54.

17.
41.

Coninutul fiierului de rezultate T54.REZ de la exerciiul 6.5.4:

Nr. prime de la 1 la
1
41
101
167
239
313
397
467
569
643
733
823
911
1009
1091
1187
1283
1381
1481
1567
1657
1753
1871
1979
2069
2153
2273
2371

2
43
103
173
241
317
401
479
571
647
739
827
919
1013
1093
1193
1289
1399
1483
1571
1663
1759
1873
1987
2081
2161
2281
2377

3
47
107
179
251
331
409
487
577
653
743
829
929
1019
1097
1201
1291
1409
1487
1579
1667
1777
1877
1993
2083
2179
2287
2381

5
53
109
181
257
337
419
491
587
659
751
839
937
1021
1103
1213
1297
1423
1489
1583
1669
1783
1879
1997
2087
2203
2293
2383

10000 sunt :
7
59
113
191
263
347
421
499
593
661
757
853
941
1031
1109
1217
1301
1427
1493
1597
1693
1787
1889
1999
2089
2207
2297
2389

11
61
127
193
269
349
431
503
599
673
761
857
947
1033
1117
1223
1303
1429
1499
1601
1697
1789
1901
2003
2099
2213
2309
2393

13
67
131
197
271
353
433
509
601
677
769
859
953
1039
1123
1229
1307
1433
1511
1607
1699
1801
1907
2011
2111
2221
2311
2399

- 139 -

17
71
137
199
277
359
439
521
607
683
773
863
967
1049
1129
1231
1319
1439
1523
1609
1709
1811
1913
2017
2113
2237
2333
2411

19
73
139
211
281
367
443
523
613
691
787
877
971
1051
1151
1237
1321
1447
1531
1613
1721
1823
1931
2027
2129
2239
2339
2417

23
79
149
223
283
373
449
541
617
701
797
881
977
1061
1153
1249
1327
1451
1543
1619
1723
1831
1933
2029
2131
2243
2341
2423

29
83
151
227
293
379
457
547
619
709
809
883
983
1063
1163
1259
1361
1453
1549
1621
1733
1847
1949
2039
2137
2251
2347
2437

31
89
157
229
307
383
461
557
631
719
811
887
991
1069
1171
1277
1367
1459
1553
1627
1741
1861
1951
2053
2141
2267
2351
2441

37
97
163
233
311
389
463
563
641
727
821
907
997
1087
1181
1279
1373
1471
1559
1637
1747
1867
1973
2063
2143
2269
2357
2447

2459
2591
2687
2767
2861
2971
3089
3217
3323
3433
3533
3623
3727
3847
3931
4051
4157
4261
4391
4507
4621
4723
4831
4957
5051
5171
5297
5417
5507
5641
5737
5843
5939
6079
6199
6299
6379
6547
6659
6763
6869
6977
7103
7219
7349
7489
7577
7687
7817
7927
8069
8179
8291
8423
8543
8669
8753

2467
2593
2689
2777
2879
2999
3109
3221
3329
3449
3539
3631
3733
3851
3943
4057
4159
4271
4397
4513
4637
4729
4861
4967
5059
5179
5303
5419
5519
5647
5741
5849
5953
6089
6203
6301
6389
6551
6661
6779
6871
6983
7109
7229
7351
7499
7583
7691
7823
7933
8081
8191
8293
8429
8563
8677
8761

2473
2609
2693
2789
2887
3001
3119
3229
3331
3457
3541
3637
3739
3853
3947
4073
4177
4273
4409
4517
4639
4733
4871
4969
5077
5189
5309
5431
5521
5651
5743
5851
5981
6091
6211
6311
6397
6553
6673
6781
6883
6991
7121
7237
7369
7507
7589
7699
7829
7937
8087
8209
8297
8431
8573
8681
8779

2477
2617
2699
2791
2897
3011
3121
3251
3343
3461
3547
3643
3761
3863
3967
4079
4201
4283
4421
4519
4643
4751
4877
4973
5081
5197
5323
5437
5527
5653
5749
5857
5987
6101
6217
6317
6421
6563
6679
6791
6899
6997
7127
7243
7393
7517
7591
7703
7841
7949
8089
8219
8311
8443
8581
8689
8783

2503
2621
2707
2797
2903
3019
3137
3253
3347
3463
3557
3659
3767
3877
3989
4091
4211
4289
4423
4523
4649
4759
4889
4987
5087
5209
5333
5441
5531
5657
5779
5861
6007
6113
6221
6323
6427
6569
6689
6793
6907
7001
7129
7247
7411
7523
7603
7717
7853
7951
8093
8221
8317
8447
8597
8693
8803

2521
2633
2711
2801
2909
3023
3163
3257
3359
3467
3559
3671
3769
3881
4001
4093
4217
4297
4441
4547
4651
4783
4903
4993
5099
5227
5347
5443
5557
5659
5783
5867
6011
6121
6229
6329
6449
6571
6691
6803
6911
7013
7151
7253
7417
7529
7607
7723
7867
7963
8101
8231
8329
8461
8599
8699
8807

2531
2647
2713
2803
2917
3037
3167
3259
3361
3469
3571
3673
3779
3889
4003
4099
4219
4327
4447
4549
4657
4787
4909
4999
5101
5231
5351
5449
5563
5669
5791
5869
6029
6131
6247
6337
6451
6577
6701
6823
6917
7019
7159
7283
7433
7537
7621
7727
7873
7993
8111
8233
8353
8467
8609
8707
8819

- 140 -

2539
2657
2719
2819
2927
3041
3169
3271
3371
3491
3581
3677
3793
3907
4007
4111
4229
4337
4451
4561
4663
4789
4919
5003
5107
5233
5381
5471
5569
5683
5801
5879
6037
6133
6257
6343
6469
6581
6703
6827
6947
7027
7177
7297
7451
7541
7639
7741
7877
8009
8117
8237
8363
8501
8623
8713
8821

2543
2659
2729
2833
2939
3049
3181
3299
3373
3499
3583
3691
3797
3911
4013
4127
4231
4339
4457
4567
4673
4793
4931
5009
5113
5237
5387
5477
5573
5689
5807
5881
6043
6143
6263
6353
6473
6599
6709
6829
6949
7039
7187
7307
7457
7547
7643
7753
7879
8011
8123
8243
8369
8513
8627
8719
8831

2549
2663
2731
2837
2953
3061
3187
3301
3389
3511
3593
3697
3803
3917
4019
4129
4241
4349
4463
4583
4679
4799
4933
5011
5119
5261
5393
5479
5581
5693
5813
5897
6047
6151
6269
6359
6481
6607
6719
6833
6959
7043
7193
7309
7459
7549
7649
7757
7883
8017
8147
8263
8377
8521
8629
8731
8837

2551
2671
2741
2843
2957
3067
3191
3307
3391
3517
3607
3701
3821
3919
4021
4133
4243
4357
4481
4591
4691
4801
4937
5021
5147
5273
5399
5483
5591
5701
5821
5903
6053
6163
6271
6361
6491
6619
6733
6841
6961
7057
7207
7321
7477
7559
7669
7759
7901
8039
8161
8269
8387
8527
8641
8737
8839

2557
2677
2749
2851
2963
3079
3203
3313
3407
3527
3613
3709
3823
3923
4027
4139
4253
4363
4483
4597
4703
4813
4943
5023
5153
5279
5407
5501
5623
5711
5827
5923
6067
6173
6277
6367
6521
6637
6737
6857
6967
7069
7211
7331
7481
7561
7673
7789
7907
8053
8167
8273
8389
8537
8647
8741
8849

2579
2683
2753
2857
2969
3083
3209
3319
3413
3529
3617
3719
3833
3929
4049
4153
4259
4373
4493
4603
4721
4817
4951
5039
5167
5281
5413
5503
5639
5717
5839
5927
6073
6197
6287
6373
6529
6653
6761
6863
6971
7079
7213
7333
7487
7573
7681
7793
7919
8059
8171
8287
8419
8539
8663
8747
8861

8863
9001
9127
9227
9343
9439
9551
9689
9803
9907

A-5

8867
9007
9133
9239
9349
9461
9587
9697
9811
9923

8887
9011
9137
9241
9371
9463
9601
9719
9817
9929

8893
9013
9151
9257
9377
9467
9613
9721
9829
9931

8923
9029
9157
9277
9391
9473
9619
9733
9833
9941

8929
9041
9161
9281
9397
9479
9623
9739
9839
9949

8933
9043
9173
9283
9403
9491
9629
9743
9851
9967

8941
9049
9181
9293
9413
9497
9631
9749
9857
9973

Pentru exerciiul 6.5.5:

Exemplu de fiier cu date T55.DAT:


Iliescu Dan
Gheorghe Adrian
Alexandrescu Valentin
Zorila Sorin Claudiu
Achim Horatiu
Pascu Cristina
Crisan Adelina
Olteanu Cristian

: 5.89
:10.00
: 8.85
: 7.26
: 8.88
: 9.83
: 9.57
: 7.22

Coninutul fiierului T55.REZ cu rezultate:

Elevii ordonati in ordinea mediilor :

1.
2.
3.
4.
5.
6.
7.
8.

Gheorghe Adrian
Pascu Cristina
Crisan Adelina
Achim Horatiu
Alexandrescu Valentin
Zorila Sorin Claudiu
Olteanu Cristian
Iliescu Dan

Media: 10.00
Media: 9.83
Media: 9.57
Media: 8.88
Media: 8.85
Media: 7.26
Media: 7.22
Media: 5.89

- 141 -

8951
9059
9187
9311
9419
9511
9643
9767
9859

8963
9067
9199
9319
9421
9521
9649
9769
9871

8969
9091
9203
9323
9431
9533
9661
9781
9883

8971
9103
9209
9337
9433
9539
9677
9787
9887

8999
9109
9221
9341
9437
9547
9679
9791
9901

- 142 -

BIBLIOGRAFIE
1.

COMPAQ FORTRAN. Language Reference Manual, Compaq Computer Corporation,


Houston, Texas, 1999.

2.

E. W. Dijkstra A Discipline of Programming, Prentice-Hall, Englewood Cliffs, New


Jersey, 1976.

3.

FORTRAN -77, Operare, I.T.C.I. Filiala Cluj-Napoca, 1988.

4.

FORTRAN -77, Programare, I.T.C.I. Filiala Cluj-Napoca, 1988.

5.

F. Gobesz, A. Ctrig Programarea calculatoarelor electronice, Institutul Politehnic


Cluj, 1974.

6.

IBM FORTRAN/2, Language Reference, I.B.M. Corp., 1987

7.

H. M. Kienle History, Architecture & Evolution of Compilers, SENG420, University


of Victoria, Canada, 2002.

8.

A. C. Marshall Fortran 90 Course Notes, The University of Liverpool, 1997.

9.

S. Niculescu FORTRAN, Iniiere n programare structurat, Editura Tehnic,


Bucureti, 1979.

10. E. Petac, C. Partale Limbajul FORTRAN, Programare i aplicaii, Matrix Rom,


Bucureti, 2002.
11. M. Petrina, A. Ctrig Programare, teorie i aplicaii pe PC-uri compatibile IBM,
Universitatea Tehnic din Cluj-Napoca, 1993.
12. T. Roberts, S. Egdorf A Face-Lift for Aging FORTRAN Scientific Applications, LAUR 01-6629, Los Alamos National Laboratory, 2001.
13. G. E. Urroz Getting started with GNU FORTRAN G77, Utah State University, 2002.
14. http://www.cfm.brown.edu/tutorials/Fortran.html
15. http://www.engineering.usu.edu/cee/faculty/gurro/
16. http://www.forceproject.hpg.ig.com.br/
17. http://www.fortran.com/
18. http://www.geocities.com/Athens/Olympus/5564/
19. http://www.geog.nottingham.ac.uk/~mather/useful/Computing.html#FORTRAN
20. http://www.hep.man.ac.uk/guide/unix_tutorial/section3.6.html
21. http://www.hpctec.mcc.ac.uk/hpctec/courses/Fortran90/mc_f90.html
22. http://www.imamod.ru/~vab/vfort/
23. http://www.levenez.com/lang/

- 143 -

Zsongor F. GOBESZ

Ciprian BACOIU

INIIERE N PROGRAMARE I N LIMBAJUL FORTRAN

INIIERE N
PROGRAMARE I
N LIMBAJUL FORTRAN

U.T.PRES

S-ar putea să vă placă și