Sunteți pe pagina 1din 145

Zsongor F.

GOBESZ

Ciprian BACOIU

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 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) 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 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 7 11 14 16

21 22 22 24 24 26 26 29 30 31

33 34 38 64 66

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 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 BIBLIOGRAFIE

99 100 102

103 107 110 124 130 135 137 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. 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. 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.

2.

3.

-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. 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. Calculatoarele electronice mixte (hibride) rezult de fapt din asocierea celor dou clase precedente cumulnd avantajele lor.

2.

3.

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 EVOLUIA LIMBAJELOR DE PROGRAMARE

1.2

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. NOIUNI REFERITOARE LA REPREZENTAREA DATELOR

1.3

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.) 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.

2.

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. NOIUNI REFERITOARE LA PROGRAME

1.4

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

MODEL LOGIC EXISTENT

MODEL LOGIC NOU

FIZIC MODEL FIZIC EXISTENT PLAN: EXISTENT MODEL FIZIC NOU 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: 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. Definibilitatea 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 Da A Nu B

REPET pn cnd C Procedura A

REPEAT UNTIL C DO A ENDREPEAT

A C Da Nu

REPET ct timp C Procedura A

WHILE C DO A ENDWHILE

C Nu

Da A

2.2.3

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 Identificatorul tabelei: TD1 TD1 C1 C2 A1 A2 A3 (AX2+BX+C=0) Coeficientul A nul Discriminant negativ Respinge coeficienii Determin soluiile reale Determin soluiile complexe marcarea regulilor pe vertical: R1 R4 R1 DA DA DA R2 DA NU DA R3 NU DA R4 NU NU DA DA Zona 4: cu valorile aciunilor Zona 3: cu valorile condiiilor

Zona 2: aciuni

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 Nul Determin soluiile reale Nenul Discriminant Nenegativ Negativ Determin soluiile complexe 2.2.5 Scheme logice

Coeficientul A

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. 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 Marcarea operaiilor de citire Marcarea operaiilor de scriere Punerea n eviden a operaiilor de calcul i a atribuirii de valori Marcarea operaiilor de evaluare prin decidere (apariia ramificaiilor) Marcarea pailor ce vor fi detaliai ulterior Punerea n eviden a operaiilor de la nceputul/sfritul prelucrrii fiierelor Precizarea modului de nlnuire a blocurilor (i marcarea salturilor) Marcarea ntreruperii i continurii unei scheme logice n cadrul aceleiai pagini Marcarea ntreruperii i continurii unei scheme logice de pe o pagin pe alta

Simbol

Bloc de intrare Bloc de ieire

Bloc de atribuire

Bloc de decizie Bloc de procedur sau modul Bloc de procedur sau modul (pentru fiiere) Linie de legtur sau Conector intern

Conector extern

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 A=0 NU := B2 4AC COEFICIENI RESPINI DA 0 NU PR(X1) := B/(2A) PR(X2) := B/(2A) PI(X1) := PI(X2) :=
/(2A) /(2A)

PR(X1) := (B+ )/(2A) PR(X2) := (B )/(2A) PI(X1) := 0 PI(X2) := 0

PR(X1), PI(X1) PR(X2), PI(X2) STOP 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 EC.GRD.2o SCRIE SOLUII

0 DET.SOL.REALE o

DET.SOL.COMPLEXE o

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: T 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: DO A DO B Schem logic: A B Diagram de structur (tip Jackson): A B

2.

Structurile alternative (decizionale sau selective) apar atunci cnd operaiile se execut opional, n funcie de condiii precizate: Schem logic: Da DO A ELSE DO B ENDIF A Nu B Diagram de structur (tip Jackson): C Ao

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

B o

b. varianta cu ramur vid (IF-THEN): Pseudocod: Schem logic: Da IF C DO A A C Nu C Ao o Diagram de structur (tip Jackson):

- 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: C 1 A B 2 P n C=1 C=2 Bo Ao C=n Po Diagram de structur (tip Jackson):

Structurile repetitive apar cnd anumite operaii se execut de mai multe ori, n funcie de o condiie precizat: Schem logic: Da A Diagram de structur (tip Jackson): C A*

a. varianta condiionat anterior (WHILE-DO): Pseudocod:

WHILE C DO A ENDWHILE

C Nu

b. varianta condiionat posterior (DO-UNTIL): Pseudocod: Schem logic: Diagram de structur (tip Jackson): Da

REPEAT UNTIL C DO A ENDREPEAT

A C Nu

c. varianta combinat (LOOP-EXIT IF-ENDLOOP): Pseudocod: Schem logic: Diagram de structur (tip Jackson): Da B

LOOP DO A IF NOT C EXIT DO B ENDLOOP

A C 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). 7380 Comentariu implicit.

- 33 -

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 trebuit s scriem X/(Y)*Z sau X/Y*Z ).

x x (pentru z ar fi y yz

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. 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)

Operator Fortran 77 Fortran 90 .LT. < .LE. <= .EQ. == .NE. /= .GT. > .GE. >=

Operator .NOT. .AND. .OR. .EQV. .NEQV. .XOR.

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. 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. ACCEPT *[,list]

Efect:

Variant cu format implicit:

Atribuire aritmetic/logic/caracter: v=exp unde: v variabil, element de tablou sau subir de caractere; = simbolul pentru operaia de atribuire; exp expresie. Atribuie valoarea unei expresii aritmetice, logice sau caracter variabilei v. Se recomand ca tipul variabilei v i tipul expresiei exp s corespund. - 38 -

Efect:

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. 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.

Efect:

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. 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.

Efect:

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). 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.

Efect:

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. 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.

Efect:

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: Efect: CONTINUE instruciunea executabil. 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 n este o constant ntreag fr semn, diferit de zero; val o valoare constant.

Efect:

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. 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).

Efect:

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: n este o expresie ntreag semnificnd lungimea lui var n octei (n cazul entitilor caracter semnific numrul de caractere).

Efect:

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). 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.

Efect:

Varianta de ciclu implicit: ([list,] c=i,f[,p]) unde: list list de intrare/ieire; celelalte valori avnd semnificaiile de la instruciunea DO. 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.

Efect:

Not:

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: Efect: END instruciunea declarativ; 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. 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.

Efect:

- 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. Permite crearea unor puncte de intrare multiple n unitile de program declarate ca FUNCTION i SUBROUTINE.

Efect:

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. Aloc fiecrei entiti din nlist aceeai locaie de memorie.

Efect:

EXTERNAL, declararea unor module externe: EXTERNAL nume[,nume]... sau EXTERNAL *nume[,*nume]... unde: EXTERNAL instruciunea declarativ; nume numele unei uniti de program. Definete numele specificat ca fiind numele unei uniti de program. Cnd nume este precedat de *, definete o unitate (subprogram) extern furnizat de utilizator.

Efect:

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. 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.

Efect:

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). 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.

Efect:

Funcie aritmetic definit: nume([p[,p]...])=exp unde: nume nume simbolic (denumirea funciei); p nume simbolic (al parametrului formal); exp expresie. 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.

Efect:

- 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). 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.

Efect:

GO TO, salt necondiionat: GO TO e sau GOTO e unde: GO TO cuvinte cheie ale instruciunii executabile; e eticheta unei instruciuni executabile. Determin transferul controlului la executarea instruciunii cu eticheta e din cadrul aceleiai uniti de program.

Efect:

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). 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.

Efect:

- 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. 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).

Efect:

IF aritmetic: IF(exp)e1,e2,e3 unde: IF instruciunea executabil; exp expresie aritmetic; e1, e2, e3 etichetele unor instruciuni executabile. 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.

Efect:

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). 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.

Efect:

- 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. 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.

Efect:

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). Atribuie tipul specificat tuturor entitilor al cror nume simbolic ncepe cu una din literele aparinnd domeniului descris ntre paranteze.

Efect:

- 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). 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.

Efect:

OPEN, deschiderea fiierelor: OPEN(p[,p]...) unde: OPEN instruciunea executabil; p parametru, fiind specificaia unui cuvnt cheie, de forma: cuv unde 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).

Efect:

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 'SAVE' DISPOSE 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'

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

Implicit Nu exist maximum nregistrrile pot traversa blocurile 'SEQUENTIAL'

READONLY RECL sau RECORDSIZE val

Lungimea nregistrrii

RECORDTYPE

'FIXED' 'VARIABLE' 'SEGMENTED'

Structura nregistrrii Acces partajat la fiier

SHARED

STATUS sau TYPE UNIT

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

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

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

Nu este implicit Nu exist opiune

USEROPEN

nume

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. Definete un nume simbolic pentru o constant.

Efect:

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. Suspend execuia programului i afieaz ir la terminal. Execuia programului se continu doar dup comanda dat de la tastatur de ctre utilizator.

Efect:

PRINT, scriere secvenial: PRINT f[,list] unde: PRINT instruciunea executabil; f referin la format (specificator de format); list list de ieire. 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. PRINT *[,list]

Efect:

Varianta cu format implicit:

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). 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.

Efect:

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). 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.

Efect:

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: 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.

Not:

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 -

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). 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.

Efect:

Not:

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: Efect: RETURN intruciune executabil. 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. 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.

Efect:

SAVE, salvarea entitilor: SAVE [a[,a]...] unde: SAVE instruciunea declarativ; a numele unui bloc comun (incadrat de /-uri), nume de variabil sau de tablou. Pstreaz definirea curent a entitilor a dup ntlnirea unei instruciuni END sau RETURN a unui subprogram.

Efect:

- 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. Termin execuia programului, afind la terminalul utilizatorului ir-ul specificat.

Efect:

SUBROUTINE, declararea unui subprogram: SUBROUTINE nume[([p[,p]...])] unde: SUBROUTINE instruciunea declarativ; nume nume simbolic (asociat subprogramului); p nume simbolic (parametru formal). 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.

Efect:

TYPE, scriere secvenial: TYPE f[,list] unde: TYPE instruciunea executabil; f referin la format (specificator de format); list list de ieire. 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. TYPE *[,list]

Efect:

Varianta cu format implicit:

- 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. 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.

Efect:

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). 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 -

Efect:

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. 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.

Efect:

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). 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.

Efect:

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. DESCRIPTORII DE INTRARE/IEIRE

3.4

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]

F G

[n]Fw.d [n]Gw.d[Ee]

cHa[a...]

I L Z

[n]Iw [n]Lw [n]Zw

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 Sintax /[/...] /

\[\...]

BN BN BZ BZ S SP SS S SP SS

Tip T TL TR X Not:

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)

Descriptorii de formatare / i \ nu trebuie separai neaprat prin virgul de restul descriptorilor din list, ei nii avnd i rol de separare. FUNCIILE INTRINSECI DIN FORTRAN 77

3.5

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: 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.

Definiie

|x|

cos(x)

sin(x)

- 66 -

Definiie ex

Nume generic EXP

ln(x) log(x)

LOG LOG10

x tg(x) arccos(x) arcsin(x) arctg(x) arctg(x/y) cosh(x) sinh(x) tgh(x)

SQRT TAN ACOS ASIN ATAN ATAN2 COSH SINH 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

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.

- 67 -

Definiie

Nume generic MIN

min(x,y,...)

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

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.

- 68 -

Definiie

Nume generic FLOAT DFLOAT IFIX

conversii de valori, ntre diferite tipuri

SNGL

DBLE

CMPLX

ICHAR parte real REAL

parte imaginar conjugare produs, lungime dubl I logic pe bit 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

AIMAG CONJG DPROD IAND IOR IEOR NOT ISHFT LEN INDEX

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 1 2 2 2 2 1 2 1 2 C R I I4 I I4 I I4 I I4 I I4 CH

Funcia Nume FLOATI FLOATJ DFLOTI DFLOTJ IIFIX JIFIX SNGL FLOATI FLOATJ DBLE DFLOTI DFLOTJ CMPLX ICHAR REAL FLOATI FLOATJ SNGL AIMAG CONJG DPROD IIAND JIAND IIOR JIOR IIEOR JIEOR INOT JNOT IISHFT JISHFT LEN

Efect Tip R R D D I I4 R R R D D D C C C C I R R R R R C D I I4 I I4 I I4 I I4 I I4 I I 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.

CH INDEX

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.

- 69 -

Definiie comparaie lexical

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.

Not:

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) INTEGER(scurt) :: poza(1024,768) INTEGER(lung) :: numar REAL(dublu) :: tablou(20,20) ! ! ! ! intregi cu >= 4 cifre intregi cu >= 9 cifre valori reale cu 15 cifre si cu domeniul 10**200

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 ! varianta cu ciclu DO-WHILE

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

- 75 -

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 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

- 76 -

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
MERGE(sursaT, sursaF, ablon)

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

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).

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) ! cu format implicit ! cu format explicit

- 87 -

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


TYPE :: punct REAL :: x, y END TYPE punct TYPE :: linie TYPE(punct) :: capat(2) INTEGER :: grosime END TYPE linie ! coordonatele punctului

! 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. INTRRI I IEIRI

4.8

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. "WRITE" "READWRITE" POSITION= "APPEND" "REWIND" STATUS= RECL= "REPLACE" lungime Acces pentru scriere. Acces pentru citire i scriere. 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.

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 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]

EN G

O P Q 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:
DATE_AND_TIME([data][,timp][,zona][,valori])

returneaz data i ora curent sub forma unui ir sau sub forma unui tablou de valori ntregi;
returneaz un tablou de valori pseudoaleatoare uniform distribuite n intervalul 01;

RANDOM_NUMBER([HARVEST=]tablou)

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

iniializeaz sau recupereaz valoarea iniial a generatorului de numere pseudoaleatoare; permite tratarea unor intervale de timp n funcie de ceasul calculatorului (n Fortran 95 exist o rutin mai curat: CPU_TIME).

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

4.11.3

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 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;

ffreeform fpedantic fnoautomatic fnobackslash fvxt

- 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 6.1.1 EXERCIII ELEMENTARE INTRODUCTIVE 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: ' ! citirea valorilor pentru a, b, c: read(*,*)a,b,c

START a, b, c : a, b, c Nu a<b Da a := b Nu Da a := c max:, a STOP

! testarea primei conditii ! (si in caz afirmativ atribuire): if(a.lt.b) a=b

a<c

! testarea urmatoarei conditii ! (si in caz afirmativ atribuire): if(a.lt.c) a=c

! afisarea rezultatului stocat in a: write(*,*)' max: ', a stop end

6.1.2

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 -

1 Nu a>b Da t := a a := b b := t Nu Da t := a a := c c := t Nu Da t := b b := c c := t crescator:,a,b,c STOP

! continuarea schemei ! si a programului, ! 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

a>c

! 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

b>c

! 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

6.1.3

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 -

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'

6.1.4

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 6.2.1

EXERCIII CU EXPRESII ARITMETICE 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 6.3.1

EXERCIII CU TABLOURI DE DATE 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 ! ---

! --! ---

! ---

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

6.3.3

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 6.4.1

EXERCIII CU SUBPROGRAME 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 6.5.1

EXERCIII CU INTRRI/IEIRI FOLOSIND FIIERE 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. 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.

6.5.3

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. 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.

6.5.5

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

- 133 -

! --! --788

500 ! ---

! ---

44

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

Not:

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

- 134 -

6.6 6.6.1

EXERCIII DIVERSE 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 A-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

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


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
pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru pentru

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


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. 24. 54. 17. 41.

A-4

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


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 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

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

- 139 -

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

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

- 140 -

8863 9001 9127 9227 9343 9439 9551 9689 9803 9907

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

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

A-5

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 -

- 142 -

BIBLIOGRAFIE
1. 2. 3. 4. 5. 6. 7. 8. 9. COMPAQ FORTRAN. Language Reference Manual, Compaq Computer Corporation, Houston, Texas, 1999. E. W. Dijkstra A Discipline of Programming, Prentice-Hall, Englewood Cliffs, New Jersey, 1976. FORTRAN -77, Operare, I.T.C.I. Filiala Cluj-Napoca, 1988. FORTRAN -77, Programare, I.T.C.I. Filiala Cluj-Napoca, 1988. F. Gobesz, A. Ctrig Programarea calculatoarelor electronice, Institutul Politehnic Cluj, 1974. IBM FORTRAN/2, Language Reference, I.B.M. Corp., 1987 H. M. Kienle History, Architecture & Evolution of Compilers, SENG420, University of Victoria, Canada, 2002. A. C. Marshall Fortran 90 Course Notes, The University of Liverpool, 1997. 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 -

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