1.- programació en fortraniqc.udg.es/~perico/docencia/qtc/prog_fortran.pdf · 1.1- ordinadors,...

34
Tècniques Computacionals, Curs 2007-2008. Pedro Salvador 4 1.- Programació en FORTRAN 1.1- Ordinadors, llenguatges d'alt nivell, compiladors Els ordinadors digitals Les aplicacions principals d’un ordinador podríem dir que són dues: Càlcul numèric Emmagatzematge, processament i anàlisi de dades. En l’actualitat existeixen infinitat d’aplicacions (software) que permeten realitzar tasques específiques com processament de textos, edició d’imatges, bases de dades, o fins i tot programes de càlcul simbòlic matemàtic com el Mathematica o Maple. Nosaltres ens dedicarem més aviat a les aplicacions de càlcul numèric i, en concret, a la programació en el llenguatge FORTRAN. Els avantatges que comporta tenir uns coneixements de programació en son vàries: Permet resoldre problemes específics que potser no serien resolubles amb el software standard de què es disposi. S’elimina la dependència del software comercial i potencialment costós, a més d’haver d’adaptar-se a les successives revisions i versions. Amb la programació es fomenta el desenvolupament intel·lectual, el pensament lògic i estructurat. De fet, difícilment es pot programar un mètode o algorisme que no s’entengui prèviament. Per tant, si fer un programa per realitzar una tasca podem estar segurs que haurem entès com es fan les coses. El FORTRAN (FORmula TRANslator) és un dels llenguatges de programació d’alt nivell més utilitzats en l’actualitat en l’àmbit científic i tècnic, juntament amb el C. L’avantatge del FORTRAN respecte al C, és que és relativament més senzill d’aprendre. Pels objectius d’aquest curs, el FORTRAN es més que suficient.

Upload: others

Post on 12-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

4

1.- Programació en FORTRAN

1.1- Ordinadors, llenguatges d'alt nivell, compiladors

Els ordinadors digitals

Les aplicacions principals d’un ordinador podríem dir que són dues:

• Càlcul numèric

• Emmagatzematge, processament i anàlisi de dades.

En l’actualitat existeixen infinitat d’aplicacions (software) que permeten realitzar

tasques específiques com processament de textos, edició d’imatges, bases de dades, o

fins i tot programes de càlcul simbòlic matemàtic com el Mathematica o Maple.

Nosaltres ens dedicarem més aviat a les aplicacions de càlcul numèric i, en concret, a la

programació en el llenguatge FORTRAN. Els avantatges que comporta tenir uns

coneixements de programació en son vàries:

• Permet resoldre problemes específics que potser no serien resolubles amb el

software standard de què es disposi.

• S’elimina la dependència del software comercial i potencialment costós, a més

d’haver d’adaptar-se a les successives revisions i versions.

• Amb la programació es fomenta el desenvolupament intel·lectual, el pensament

lògic i estructurat. De fet, difícilment es pot programar un mètode o algorisme que

no s’entengui prèviament. Per tant, si fer un programa per realitzar una tasca podem

estar segurs que haurem entès com es fan les coses.

El FORTRAN (FORmula TRANslator) és un dels llenguatges de programació d’alt

nivell més utilitzats en l’actualitat en l’àmbit científic i tècnic, juntament amb el C.

L’avantatge del FORTRAN respecte al C, és que és relativament més senzill

d’aprendre. Pels objectius d’aquest curs, el FORTRAN es més que suficient.

Page 2: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

5

Una de les característiques dels ordinadors actuals és la representació binària de la

informació. Internament, l’ordinador està composat de commutadors que poden tenir

posició oberta o tancada, i serveixen per representar els nombres 0 i 1. Per tant, dos és

la base natural de representació dels nombres en l’entorn informàtic. És a dir, mentre

que en base deu representem el nombre 113 com

113 = 1(102) + 1(101)+ 3(100)

en base dos tindríem

113 = 1(26)+ 1(25)+ 1(24)+ 0(23)+ 0(22)+ 0(21)+ 1(20) = 64 + 32 + 16 +1 = (1110001)2

Val a dir que també es poden representar de la mateixa manera altres tipus de dades,

com per exemple lletres (caràcters alfanumèrics) , simplement assignant-ne un valor a

cada lletra de l’abecedari.

Cada unitat d’informació binària rep el nom de bit. Normalment els bits s’agrupen en

blocs de 8 unitats formant un byte. Les dades que s’emmagatzemen i amb les que

treballarem a l’ordinador poden ser de 1 fins a 16 bytes, segons el tipus.

Per exemple, en FORTRAN el nombres sencers (integer) es representen per defecte

amb 4 bytes (o 32 bits). Això vol dir que amb aquest tipus de dades poden representar

nombres en el rang +231 -231 (cal un bit per especificar el signe).

Pels caràcters alfanumèrics només ens caldrà un byte, amb el que podem codificar 28 =

256 caràcters diferents.

La memòria principal d’un ordinador està formada per milions de circuits integrats

capaços emmagatzemar zeros o uns. Hi ha dos valors associats a cada element de la

memòria: la dada que conté i la direcció de la mateixa que ens permet accedir a la

mateixa.

El temps d’accés a la dada es un paràmetre molt important en la informàtica actual. De

fet, un suma es fa en menys temps que es triga en trobar els sumands a la memòria. En

les memòries RAM, el temps d’accés es independent de la posició que ocupa l’element

(random access memory).

Els PC’s actuals tenen també l’anomenada memòria cache, situada físicament a prop del

Page 3: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

6

processador on es realitzen les operacions, que té un temps d’accés molt mes curt que la

memòria RAM i on s’emmagatzemen les dades més recentment accedides a la memòria

principal. Aquesta memòria ultraràpida és molt petita (típicament 256-1024 Kb). Una

bona estratègia de programació avançada és aconseguir que les dades estiguin el major

temps possible a la memòria cache.

A més de la memòria principal, hi ha altres llocs on s’emmagatzema la informació de

manera permanent però a canvi d’un temps d’accés superior. Són els dispositius de

memòria massiva o secundaria (discs durs, CD-ROM, DVD, diskettes, pen drives,

etc...). Per tant, un altra estratègia de programació eficient és la d’accedir el mínim

numero de vegades possible al disc dur (treballant sempre en memòria RAM o bé

llegint les dades necessàries en grans blocs).

En la comunicació amb l’ordinador cal tenir presents el dispositius d’entrada i sortida

(Input/output devices). Com a dispositius d’entrada tenim el teclat i les memòries

massives (disk dur, etc...), i són les vies per les quals li entrem les dades a l’ordinador.

Pel que fa a la sortida, tenim la pantalla, la impressora i les mateixes memòries

massives.

A l’hora d’escollir un dispositiu o un altre cal tenir en compte l’ús que en fem de la

informació. Per exemple, moltes vegades els nostres programes tindran unes opcions

típiques que ens pot interessar no introduir mitjançant el teclat cada vegada que

l’executem sinó que poden ser llegides d’un fitxer creat prèviament.

De la mateix manera, ens pot interessar guardar de manera permanent la sortida del

programa (output), per exemple per fer-la servir com a entrada (input) d’un altre

programa. En aquest cas convé, doncs, fer servir el disc dur com a dispositiu de sortida.

Per últim comentarem com li comuniquem a l’ordinador què volem fer. De fet, el

llenguatge primari de l’ordinador consta d’instruccions del tipus:

• Porta el numero X de la direcció de memòria Y

• Emmagatzemar-lo a la CPU

• Suma dos nombres

Page 4: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

7

Aquest llenguatge màquina (ensamblador, assembler), però, no resulta gaire útil per

l’usuari. Els anomenats llenguatges d’alt nivell el que permeten es codificar de manera

més “humana” les instruccions, de manera que siguin, a més, independent de la màquina

on es treballi. El conjunt d’instruccions escrites en aquest llenguatge rep el nom de codi

font.

El programa que realitza la traducció a llenguatge màquina és el compilador, i el

resultat de la traducció es codi objecte. Per últim, el procés de creació del fitxer

executable final rep el nom de link i el duu a terme, generalment, el propi compilador

després de la compilació (exitosa).

Tant el codi objecte com el programa executable final depenen de l’arquitectura de

l’ordinador de treball (i per tant només podrà executar-se en aquell tipus de màquina i

sistema operatiu) mentre que només el codi font és universal.

FORTRAN

En l’actualitat existeixen vàries revisions del llenguatge FORTRAN original:

FORTRAN 77, FORTRAN 90 i FORTRAN 95. Les versions 90 i 95 es poden

considerar, de fet, com ampliacions del FORTRAN 77, pel què la pràctica totalitat de

les instruccions de FORTRAN 77 estan incloses en les versions posteriors.

Per tant, tot i que farem servir el compilador de FORTRAN 95, ens limitarem a fer

servir instruccions de FORTRAN 77. De fet, l’actualització dels programes científics

existents a versions posteriors és pràcticament inexistent avui en dia. A més, existeixen

compiladors de FORTRAN77 gratuïts pel sistema operatiu Linux (GNU g77).

Bibliografia

Programación en FORTRAN77, G. J. Borse, Ed. Anaya 1989.

Page 5: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

8

1.2- Fonaments del FORTRAN 77

A l’hora d’elaborar el codi font en FORTRAN77 hi ha una sèrie de pautes que cal

seguir:

• Les instruccions o expressions (sentencies) s’escriuen en línies independents,

de tal manera que les instruccions s’executen seqüencialment (una darrera de

l’altra).

• El compilador ignora les línies en blanc

• Cada línia té una amplada màxima de 80 caràcters.

• Les instruccions han de situar-se entre les columnes 7 i 72 de cada línia.

• Les columnes 1 a 5 estan reservades per etiquetar les sentencies amb

números (opcional).

• La columna 6 és de continuació. Si una sentencia és massa llarga es pot

continuar a la següent línia (a partir de la columna 7) escrivint un caràcter

diferent del 0 en la columna 6 (típicament es fa servir “+” o “1”, “2”, etc...)

• Qualsevol línia que contingui a la columna 1 el caràcter “C” o bé “*” es

considera comentari i el compilador l’ignora. És molt important incloure

comentaris en el codi font per tal de millorar la seva comprensió

posterior!

Tot programa escrit en FORTRAN comença per la sentència PROGRAM i termina amb

la sentència END (o END PROGRAM).

La comanda PROGRAM pot venir acompanyada d’una paraula, que dóna nom al

programa. És important recalcar que aquest nom no te res a veure amb el nom del fitxer

que conté el codi font o el nom del fitxer executable final.

Page 6: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

9

Tipus de dades

El FORTRAN ofereix una certa varietat en la referència i emmagatzematge de dades.

En concret n’hi ha de cinc tipus: INTEGER, REAL, COMPLEX, CHARACTER i

LOGICAL que serveixen per codificar nombres enter, decimals (o de coma flotant) i

complexes, caràcters alfanumèrics i expressions booleanes (vertader o fals).

Per defecte les variables de tipus INTEGER, REAL i COMPLEX ocupen 4 bytes,

mentre que les LOGICAL i CHARACTER n’ocupen 1 byte.

Molt sovint es treballa amb dades de tipus DOUBLE PRECISION, que de fet son

variables de tipus REAL però de 8 bytes. De fet, REAL*8 és un sinònim de DOUBLE

PRECISION. Això és així perquè amb dades de tipus REAL de 4 bytes podem

emmagatzemar números decimals dins el rang 10-38 – 1038 amb 8 dígits de precisió. En

canvi, amb les DOUBLE PRECISION s’arriba fins a un rang de 10-308.- 10308. amb 16

xifres significatives.

Les dades que s’utilitzen en el programa poden ser constants o variables i han de tenir

un nom. Les constants designen un valor específic que cal introduir i que no canvia al

llarg del mateix. Pera altra banda, el concepte de variable coincideix amb l’habitual, és a

dir, un nom simbòlic que fa referència a una dada que pot prendre diferents valors. Hi

ha algunes restriccions al respecte de quins noms es poden assignar a les variables o

constants:

• Han de començar per un caràcter alfanumèric (una lletra).

• No poden contenir caràcters especials (accents, signes, asterisc, etc..).

• És convenient, tot i que no obligatori, denominar les variables o constants amb

noms que recordin al concepte que representen.

Quan s’escriu un programa en FORTRAN77 s’utilitzen sentencies d’especificació o

declaració on s’explicita quin tipus de dades es faran servir al programa. Aquestes

sentencies s’inclouen en el codi font just després de la sentència PROGRAM.

Les constants es declaren i especifiquen a la vegada mitjançant la sentència parameter

de tal manera que amb l’expressió

parameter (MAXDIM=100, PI = 3.1415926)

estem dient al programa que hem definit dues dades constants amb els noms MAXDIM i

Page 7: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

10

PI , el valor de les quals queda fixat i no es pot modificar posteriorment.

En el cas de les variables cal tenir en compte el següent:

• Per defecte, totes les variables el nom de les quals comenci per les lletres

i, j, k, l, m, n seran considerades com INTEGER. La resta seran de tipus

REAL.

• Els casos per defecte es poden modificar amb la sentència implicit. Per

exemple, la sentència següent (desprès de la sentència program):

implicit double precision (a-h,o-z)

fa que es conservi que les variables que comencin per les lletres i fins n siguin

considerades INTEGER però aquelles que comencin per les lletres a fins h i o

fins z seran reals de doble precisió (8 bytes)

• Es pot assignar de forma explícita un o més variables. Per exemple, amb les

sentències

real x,y,z

integer dia,mes, any

character linia*80, nom*20

declarem que les variables x, y ,z seran considerades dins el programa de

tipus REAL; les variables dia, mes, any seran de tipus INTEGER; les

variables línia i nom seran de tipus CHARACTER amb longitud 80 i 20

caràcters, respectivament.

• Les sentències anteriors s’inclouen en el programa després de la

sentencia program.

• La declaració explicita del tipus de les variables no és obligatori. Si no

s‘especifica res, el compilador considera el cas per defecte comentat

anteriorment. Això, de fet, implica que les variables de tipus CHARACTER

o LOGICAL s’hagin de declarar sempre

• Amb les sentències de declaració no s’assigna cap valor a les variables,

només es dona un nom determinat a una posició física de la memòria on

s’emmagatzemarà el valor de la variable.

En els exemples següents assumirem que les variables són del tipus determinat per

l’opció per defecte.

Page 8: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

11

Input/output standard

Les comandes input/output standard en FORTRAN són

• read(*,*) llista de variables entre comes

• write(*,*) llista de variables o cadenes de caràcters entre comes

(Una cadena de caràcters és un conjunt de caràcters entre cometes o apòstrofs. )

Per exemple:

Sentència Resultat

read(*,*) x llegeix del teclat un nombres real

read(*,*) i, j llegeix del teclat dos nombres sencers

write(*,*) x, i escriu per pantalla un nombre real seguit

d’un nombre sencer

write(*,*) ‘El producte x*y = ‘,x*y

escriu per pantalla literalment

El producte x*y = , seguit del resultat del

producte

Quan el programa arriba a una sentència d’input/output es transfereix el control als

dispositius d’input/output. Per exemple, quan s’arriba a un sentència com

read(*,*) x

el programa espera que l’usuari introdueixi mitjançant el teclat (dispositiu d’input

standard) una dada (real, en aquest cas). Les dades s’introdueixen simplement escrivint

el número seguit de INTRO. Quan la sentència read inclou més d’una variable entre

comes, els valors es poden introduir durant l’execució del programa bé entre comes o

bé un a un prement INTRO cada cop.

Per altra banda, quan s’ arriba a una sentència com

write(*,*) x

el programa escriu per pantalla (dispositiu d’output standard) el valor que tingui

assignat en aquell precís moment la variable x

Més endavant veurem com es pot controlar el format de input/output dels nombres i

caràcters alfanumèrics mitjançant les sentències de format (format). També veurem

com definir altres dispositius d’input/output diferents als standard, i en concret, com

escriure i llegir de fitxers als discs locals.

Page 9: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

12

Assignació

De fet, el procés d’assignació en FORTRAN ja ho hem anat veient. Bàsicament, hi ha

dues maneres d’assignar un valor a una variable

• Externament, mitjançant la comanda read : Per exemple, amb la sentència

read(*,*) x

aconseguim assignar-li a la variable x un valor mitjançant el teclat

• Per assignació directa. Per exemple, amb la sentència

y = 3.0d0*x +4.0d0

li assignem a la variable y el resultat de multiplicar el valor de la variable x

per tres i sumar-li quatre.

En aquest cas d’assignació directa cal tenir en compte alguns punts:

• Si fem servir una variable a la que no se li ha assignat cap valor, el resultat

por ser qualsevol. Per exemple, si fem

y = 3.0d0*x +4.0d0

sense haver donat cap valor a x, el resultat que es guardarà a y pot ser

qualsevol (tot i això molts compiladors assignen per defecte el valor 0 a totes

les variables).

• Expressions del tipus

y = 3.0d0

y = 3.0d0*y +4.0d0

son perfectament vàlides. De fet estem dient que y inicialment conté el valor

3 i, posteriorment, s’hi emmagatzema el resultat de multiplicar el valor

anterior de y per 3.0 i sumar-li 4.0. Recordeu que son sentencies

d’assignació! No implica igualtat.

Exemple: Escriu un programa que intercanviï el valor de dues variables. És a dir,

que si inicialment i=3 i j =2, al final tinguem i=2 i j = 3.

• El valor que quedi emmagatzemat a la variable depèn del tipus de variable.

Per exemple si fem

i = 4.0d0/3.2d0

Page 10: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

13

a la variable INTEGER i s’hi emmagatzemarà el valor 1

x= 1/2

a la variable REAL x i s’hi emmagatzemarà el valor 0.0

Operacions aritmètiques

Els operadors aritmètics típics són els següents

+ suma

- resta

* multiplicació

/ divisió

** potència

Els operands poden ser números, constants o variables, sempre i quan siguin del tipus

escaient. Cal tenir en compte que:

• El resultat de les operacions on intervenen nombres sencers (INTEGER) és un

nombre sencer. Així, per exemple, 10/3 = 3, mentre que 10.0d0/3 = 3.33333...

• La barreja de variables o nombres de diferents tipus en una mateixa operació es

potencialment perillosa. Per exemple1

Expressió Resultat

a = 10/3 a = 3.000000

b = 10.0d0/3 b = 3.3333332

c = 10.0d0/3.0d0 c = 3.33333333

i = 10/3 i = 3

j = 10.0d0/3.0d0 j = 3

Comparant els valors a b i c es pot veure com es pot perdre precisió. Si escrivim 10.0d0

estem indicant que el número és de doble precisió (a diferència de 10.0 o 10.0e0).

Podem veure també que si la variable on s’assigna el resultat es de tipus INTEGER el

valor que emmagatzema serà sempre de tipus enter.

1 D’ara endavant suposarem que s’han definit variables reals de doble precisió.

Page 11: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

14

A les variables de tipus CHARACTER també se’ls pot assignar valors. Per exemple, si

fem

character nom*10, cognom*10, tot*30

nom = ‘Armando’

cognom = ‘Bronca’

assignem a les variables nom i cognom valors alfanumèrics.

L’operació que es pot fer amb aquest tipus de dades es la concatenació. amb l’operador

“//”

tot =nom//cognom//”Segura”

Així, a la variable tot tindrem assignat

Armando___Bronca____Segura____

• Si l’expressió és més llarga que la variable, aquesta es trunca a la mida

necessària

• Si l’expressió és mes curta que la variable s’afegeixen espais en blanc fins

arribar a la mida declarada de la variable

Page 12: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

15

1.3 Instruccions de execució condicional

L’ordinador, a més de realitzar operacions aritmètiques és capaç de fer comparacions i

executar determinades instruccions en funció del resultat. Per realitzar les comparacions

s’utilitzen expressions o sentències lògiques acompanyades dels corresponents

operadors lògics. Veiem primer aquests últims:

Operador lògic Significat

.EQ. igual a

.NE. diferent de

.LT. més petit que

.LE. més petit o igual que

.GT. més gran que

.GE. més gran o igual que

.AND. i lògic

.OR. o lògic

.NOT. negació lògica

És important tenir en compte que els punts formen part de l’operador lògic.

La sentència if , una de les estructures de control clau, es la que permet realitzar les

comparacions. Veiem com funciona:

El cas més senzill seria la sentència

if (expressió_lògica) sentència1

En aquest cas, s’avalua l’expressio_logica i si es vertadera s’executa la sentència1.

Per exemple, amb la sentència

if(x.LT.0.0) x = -x

si el valor de la variable x és negatiu li canviem el signe (obtenim el valor absolut). De

fet, ja hem vist que la funció intrinseca abs( ) faria també aquesta feina.

Page 13: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

16

Si volem incloure més d’una instrucció dins el bloc if llavors hem de fer

if (expressió_lògica) then

sentència1

sentència2

...

end if

Per altra banda, també podem dirigir l’execució del programa en funció del resultat de

l’expressió lògica (i no només realitzar una sèrie d’instruccions només en cas que sigui

vertadera, com fins ara). Veiem-ho:

if (expressió_lògica) then

sentència1

...

else

sentència2

...

end if

En aquest cas, si l’expressió lògica es vertadera s’executa la sentència1 i de més

sentències escrites abans de la paraula else. En cas que hagués estat falsa, l’execució

del programa salta a la sentència immediatament posterior a else i posteriors fins end if.

Per exemple:

if (x.GT.-3.0.AND.x.LE.10.0) then

write(*,*) ‘El nombre esta dins l’interval (–3 , 10]

else

write(*,*) ‘El nombre esta fora de l’interval (–3 , 10]

end if

Page 14: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

17

Per últim, es poden incloure dins la sentència if més d’una opció, mitjançant altres

expressions lògiques:

if (expressió_lògica1) then

sentència/es 1

else if (expressió_lògica2) then

sentència/es 2

...

else if (expressió_lògica n) then

sentència/es n

else

sentència/es que s’executen cas que totes les expr. lògiques

anteriors siguin falses

...

end if

De tal manera que, per exemple, el bloc de sentències 2 només s’executarà si

l’expressió lògica 1 es FALSA i l’expressió lògica 2 és VERTADERA. Desprès

d’això el programa continuarà amb la sentència immediatament posterior a end if.

Fixeu-vos també que, tot i que no és cap obligació, les sentències que queden entre les

sentències pròpies de control (if..else...end if), s’indenten per millorar la comprensió

del programa.

Exemple: Fes un programa que trobi les solucions d’una equació de segon grau del tipus ax2 +

bx + c = 0. El programa hauria de distingir entre els possibles casos que es poden donar (no hi

ha solució real, una solució doble, dues solucions) i escriure’n el resultat en funció del cas.

Page 15: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

18

1.4- Instruccions de execució repetitiva (bucles)

Els bucles son una de les tècniques de programació més utilitzades. Bàsicament

consisteixen en repetir un numero determinat (finit) o indeterminat (infinit) de vegades

les sentències que s’executen dins el propi bucle.

En FORTRAN existeixen dos tipus de instruccions per fer bucles, segons el numero de

vegades que es repeteixen sigui determinat o indeterminat (depenent d’una condició).

Res millor que un exemple. Veiem com funciona

do while(expressió_lògica) (1)

sentència 1

....

end do (2)

En aquest cas tenim un bucle on el nombre de vegades que es repeteix és indeterminat i

dependent de la condició lògica. Quan el programa entra en el bucle (1) avalua

l’expressió lògica. Si es vertadera, entra dins el bucle i executa les sentències fins

arribar al punt final del bucle (2). Si fos falsa no entraria en el bucle i el control del

programa tornaria a la sentència immediatament posterior al punt final del bucle (2).

Cas d’haver estat vertadera, el programa tornaria al començament del bucle (1) i

tornaria a avaluar l’expressió lògica. Si fos vertadera, entraria al bucle, etc...

Per exemple, el següent és un programa que suma els N primers nombres.

read(*,*) N

i=1

isuma=0

do while (i.LE.N)

isuma=isuma + i

i= i+1

end do

write(*,*) ‘La suma dels ‘,N, ‘ primers nombres enters es: ‘,isuma

Analitzem-ho. Primer es llegeix el nombre final N, de tipus INTEGER. Tot seguit

Page 16: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

19

inicialitzen dues variables INTEGER (i, isuma). La variable i ens servirà de

comptador, mentre que a isuma n’acumularem el resultat final. Quan el control del

programa arriba a l’entrada del bucle, comprova si i és menor o igual que N. En cas

afirmatiu entra al bucle. A dins, el que fem es sumar el valor de i al total (isuma) i,

posteriorment, incrementar en una unitat el valor del comptador i. Quan s’arriba al final

del bucle (end do) el programa torna al principi a comprovar que i encara es menor o

igual que N.

És important incrementar la variable i dins el bucle perquè sinó tindríem un bucle

infinit i bàsicament podríem “penjar” l’ordinador.

Si, per exemple, haguéssim donat a N un valor de 7, el programa entraria fins a 7

vegades el bucle i aniria sumant a isuma els valors 1, 2,3 ..., fins a 7.

Valor de i Valor de isuma

1 1

2 3

3 6

4 10

5 15

6 21

7 28

Però, de fet, també podríem haver fet el programa utilitzant una estructura de bucle

determinat, ja que si N és 7 cal que el bucle es repeteixi exactament 7 vegades.

En aquest cas seria

read(*,*) N

do i=1,N

isuma=isuma+i

end do

write(*,*) ‘La suma dels ‘,N, ‘ primers nombres enteres es: ‘,isuma

Ara la sentència inicial del bucle té l’estructura

do comptador_INTEGER = valor_inicial, valor_final, (valor_pas)

No hi ha, doncs, expressió lògica. Quan el programa entra per primer cop al bucle li

Page 17: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

20

assigna a la variable comptador_INTEGER el valor_incial (per tant, no hi ha necessitat

de inicialitzar-la com abans). Tot seguit s’entra dins el bucle i s’executen les sentències.

Quan s’arriba al final del bucle (end do) es torna a la sentència inicial i s’incrementa en

valor_pas2 el valor de la variable comptador _INTEGER. Aquest procés es repeteix fins

que la variable comptador _INTEGER prengui el valor_final o, en tot cas, no el superi.

És important no modificar el valor de la variable comptador_INTEGER dins

l’estructura del bucle. De fet, molts compiladors no ho permeten i donen error.

Els bucles també es poden aniuar. Per exemple, si volem generar els 99 primers

nombres inclòs el 0, podem fer

do i = 0,99

write(*,*) i

end do

o bé

do i=0,9

do j=0,9

write(*,*) 10*i + j

end do

end do

En aquest segon cas, inicialment la variables i prenen els valor 0 i entra en el bucle.

Llavors ens troben un altre bucle, on el valor inicial de j és 0 i va variant fins a 9, per a

cada valor possible de i. Per tant, la instrucció

write(*,*) 10*i + j

s’executarà un total de 9x9 = 81 vegades.

Fixeu-vos també que, de la mateixa manera que amb les sentències de control (if...end

if), les sentencies dintre de cada bucle es solen indentar per millorar la comprensió del

programa.

2 De fet, valor_pas és optatiu. Si no s’especifica assumeix que la variable incrementa en una unitat.

Page 18: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

21

Finalment, també es poden simular els bucles mitjançant sentencies de decisió i de salt,

tipus go to. Veiem un exemple

read(*,*) N

isuma=0

i=1

1 if(i.LE.N) then

isuma=isuma+i

i=i+1

go to 1

end if

write(*,*) ‘La suma dels ‘,N, ‘ primers nombres enteres es: ‘,isuma

Aquest programa també realitza la suma dels N primers nombres enters. La repetició de

les sentències s’aconsegueix amb la sentència go to 1. El que fa és transferir el control

de l’execució a la línia etiquetada amb el numero 1.

De tota manera, és molt recomanable no utilitzar mai les sentencies de salt tipus go to.

La raó principal és que dificulten la comprensió del codi font.

Exemple: Un mètode per resoldre equacions no lineals és el de les substitucions successives. Si

tenim una equació del tipus f(x)=x , es dóna un valor inicial a x i es calcula la seva imatge f(x).

Si f(x)=x, vol dir que x és la solució. Cas contrari, s’utilitza el valor de f(x) com a nova

aproximació a la solució i s’itera fins que la diferència entre el valor de x i la seva imatge f(x)

sigui menor que un nombre suficientment petit (precisió). Fes un petit programa que trobi la

solució a l’equació ln(x)=x.

Page 19: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

22

1.5- Altres dispositius Input/Output

Ens podem comunicar amb l’ordinador a traves d’altres dispositius a banda del teclat i

la pantalla. En concret, és molt freqüent fer servir fitxers per emmagatzemar les dades ,

tant d’entrada (input) com de sortida (output).

Això pot ser útil per introduir ràpidament gran quantitat d’informació al programa (una

matriu, per exemple) o per emmagatzemar els resultats directament per posteriors

aplicacions.

En FORTRAN l comanda open ens serveix per obrir un fitxer. La sintaxi bàsica és la

següent

open(nombre_INTEGER, file=cadena_CHARACTER)

on cadena_CHARACTER és el nom del fixer i nombre_INTEGER el número que se li

assignarà internament. Per exemple amb

open(1, file=”dades.dat”)

obrim un fitxer al directori de treball que es diu dades.dat, i internament li assignem el

nombre 1.

El nom del fitxer es pot introduïr també mitjançant una variable de tipus

CHARACTER. Per exemple aquest petit tros de codi

CHARACTER*20 nomfitxer

write(*,*) ‘Escriu el nom del fitxer que vols obrir/crear “

read(*,*) nomfitxer

open(1,file=nomfitxer)

ens demana (per pantalla) el nom del fitxer que volem obrir, el guarda en una variable

de tipus CHARACTER anomenada nomfitxer i finalment obre el fitxer amb el nom que

hem entrat (per teclat) , tot assignant-li la unitat 1.

Podem tenir accés a tants fitxers com vulguem, escrivint cada cop una sentència de tipus

open per cadascun.

Page 20: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

23

Un cop tenim un fitxer obert (accessible) podem llegir dades que haguéssim

introduït anteriorment o bé escriure dades noves.

Per llegir dades existents al fitxer, fem servir al comanda read. Així,

read(1,*) N,x0

llegeix un nombre enter i un nombre real del fitxer que li hem assignat el nombre 1, és a

dir, en aquest cas dades.dat. És clar que al fitxer hauríem d’haver escrit prèviament els

valors de les variables per què els llegeixi el programa de la mateixa manera que ho

hauríem fet mitjançant el teclat.

Per tant, el fitxer dades.dat haurà de contenir, per exemple

10, 0.57d0

o bé

10

0.57d0

Si, per contra, el fitxer no existia prèviament (o el volem sobreescriure) i hi volem

escriure dades, faríem, per exemple

write(1,*)’Aquesta línia sortirà al començament del fitxer’

write(1,*)’Tot seguit escric un nombre sencer i un de real’, N,x0

Si obrim el fitxer dades.dat amb un editor simple com el Bloc de Notes del Windows hi

trobaríem el següent

Aquesta línia sortirà al començament del fitxer

Tot seguit escric un nombre sencer i un de real 10 0.57d0

És molt important tenir en compte que l’accés als fitxers és seqüencial.

És a dir, que per accedir a la línia n-sima d’un fitxer haurem d’haver llegit les n-1 línies

anteriors. Quan obrim un fitxer amb la comanda open, el programa esta preparat per

llegir/escriure de/a la primera línia del fitxer. Conforme anem llegint o escrivint anem

avançant línia a línia.

Un comanda que pot ser útil en algunes circumstàncies és rewind(nombre_fitxer), de

manera que si fem

Page 21: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

24

rewind(1)

tornem al programa a la posició inicial del fitxer (primera línia).

Tot i que no és necessari pel correcte funcionament del programa, és recomanable

tancar el fitxer un cop hàgim escrit/llegit tota la informació amb la comanda

close(nombre_fitxer)

close(1)

Finalment, val a dir que les unitats 5 i 6 estan reservades per defecte i corresponen a

“teclat” i “pantalla”. Es a dir que

write(*,*) és equivalent a write(6,*) i

read(*,*) és equivalent a read(5,*)

Per exemple, per fer que el programa escrigui un llistat dels N primers nombres sencers

amb els corresponents quadrats en un fitxer podríem fer el següent

open(2,file=”llista.out”)

read(*,*) N

do i=1,N

write(2,*) i, i*i

end do

end

Es molt recomanable donar extensió típica diferent als fitxers que han de ser

essencialment d’input i d’ouput. Per exemple, els fitxers d’input es solen anomenar

*.in o *.dat , mentre que pels d’output es solen fer servir extensions del tipus *.out

o *.log.

Page 22: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

25

1.6- Vectors i Matrius

En programació, un array o vector no és més que una manera ordenada

d’emmagatzemar un conjunt d’elements del mateix tipus sota un mateix nom. Aquests

elements, en FORTRAN 77 poden qualsevol dels tipus de variables que hem vist.

Per indicar en un programa que volem fer servir un array, primer de tot l’hem de

declarar amb una sentència DIMENSION. Com totes les sentencies de declaració, les

haurem de introduir sempre abans de les sentències d’execució. Veiem un exemple

DIMENSION a(10)

DIMENSION b(10,10), imat(10,15)

Amb la primera de les sentències anteriors hem declarat una variable array

monodimensional (vector) de dimensió 10 al què hem assignat el nom a. A la segona

hem declarat dos arrays bidimensionals (matrius) b i imat de dimensions 10x10 i 10x15,

respectivament.

A més, els elements del vector a i la matriu b seran variables de tipus REAL mentre que

la de la matriu imat seran de tipus INTEGER (perquè el nom comença per i, i sempre i

quan no hàgim sobreescrit les opcions per defecte).

És important entendre que, de nou, el fet de declarar no implica assignar cap valor als

elements dels vectors o matrius. Només n’informem al ordinador de la seva existència i,

en aquest cas, en fixem el nombre màxim d’elements per dimensió que en poden

emmagatzemar.

Per assignar valors als elements del vectors o matrius ho podem fem de la següent

manera amb sentències d’assignació:

a(1) = 2.0d0

read(*,*) b(2,3)

imat(1,15) = 2

En el primer cas emmagatzemem el valor 2.0d0 al primer element del vector a, al què es

fa referència com a a(1). En el segon accedim a l’element que es troba en la segona fila,

tercera columna i li assignem el valor que l’usuari entra externament mitjnaçat el teclat,

etc...

Page 23: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

26

En FORTRAN 77, per assignar un valor a cada element d’un vector o una matriu s’ha

de fer element per element. Afortunadament, per això tenim els bucles. Per exemple, si

volem inicialitzar els elements del vector a a zero faríem simplement

do i=1,10

a(i) = 0.0d0

end do

Per entrar els elements de la matriu b externament mitjançat el teclat podríem fer

do i=1,10

do j=1,10

read(*,*) a(i,j)

end do

end do

Fixa’t que en aquest cas els elements de la matriu s’introdueixen un per un i per

columnes. Existeix una manera alternativa que permet llegir (i escriure) matrius de

manera semblant a com ho fem sobre el paper, introduint els valors filera per filera. Per

fer això cal escriure el següent.

do i=1,10

read(*,*) (a(i),i =1,10)

end do

i

do i=1,10

read(*,*) (a(i,j),j =1,10)

end do

En el primer cas entraríem els elements del vector un a un i entre comes. En el segon,

entraríem els elements d’una mateixa filera un a un i entre comes, i això per les 10

fileres de la matriu (començant per la primera).

i vectors.

A l’hora d’escriure la matriu per pantalla podem fer, de la mateixa manera

do i=1,10

write(*,*) (a(i,j),j =1,10)

end do

Page 24: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

27

En FORTRAN podem definir hipermatrius de fins a 7 dimensions, tot i que rarament en

necessitarem més de dues i excepcionalment 3 o 4.

És també molt important veure que, de la mateixa manera que els elements de les

matrius s’introdueixen un a un, no es poden fer operacions directament amb les

matrius/vectors. És a dir, si volem sumar dues matrius A i B (que es puguin sumar) no

ho podem fer com

C = A +B

sinó que haurem de calcular els elements de la matriu resultant un per un. De nou, els

bucles faciliten molt la feina. Primer de tot, escrivim l’expressió corresponent a un

element qualsevol de la matriu suma

c(i,j) = a(i,j) + b(i,j)

Ara, assumint que les matrius anteriors A i B han estat declarades de dimensió 10x10, el

codi que ens permetria calcular la suma de les matrius seria simplement

do i=1,10

do j=1,10

c(i,j) = a(i,j) + b(i,j)

end do

end do

És a dir, escrivim l’expressió general i mitjançant els bucles que calguin ho estenem per

tots els valors possibles.

Val a dir, finalment, que la dimensió amb què és declarat un array representa només la

dimensió màxima de l’array. De fet, és pràctica habitual declarar un array de dimensió

suficientment gran per als nostres propòsits, generalment amb una constant

PARAMETER(MAXDIM=100)

DIMENSION A(MAXDIM,MAXDIM), B(MAXDIM,MAXDIM)

i després fer servir en realitat una dimensió més petita pels nostres càlculs

...

READ(*,*) N,M

do i=1,N

read(*,*) (A(i,j),j =1,M)

end do

....

Page 25: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

28

El codi següent

DIMENSION A(N,M), B(N,M)

...

READ(*,*) N,M

do i=1,N

read(*,*) (A(i,j),j =1,M)

end do

....

no es possible en FORTRAN77 i donarà error. La raó és que, en el moment de

declarar les matrius A i B , les variables N i M no tenen assignat cap valor (i de cap

manera es pot escriure la sentència READ abans de les sentencies de declaració!).

Page 26: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

29

1.7 Subprogrames: Funcions i Subrutines

El llenguatge FORTRAN té dos tipus de subprogrames: la subrutina i la funció externa.

L’objectiu és el de definir subprogrames o blocs que realitzin tasques específiques.

Aquests blocs realitzaran part del programa i poden ser utilitzat per a la construcció

d’un programa major o futur. Per tal que es pugui segmentar el programa cal

comunicació entre els diferents subprogrames. Aquesta comunicació es fa mitjançant els

paràmetres dels subprogrames. Les regles per passar la informació del programa

principal als subprogrames són les mateixes tant per les funcions com per les subrutines.

La principal diferencia entre una funció i una subrutina és que la primera torna al

programa principal, un valor emmagatzemat en el seu propi nom, mentre que la

subrutina ho fa a traves dels paràmetres.

Funcions

Una utilitat obvia de les funcions en FORTRAN és precisament la de definir funcions

matemàtiques complexes. De fet, el FORTRAN té una sèrie de funcions matemàtiques

bàsiques per defecte. Son les funcions intrínseques. Algunes d’aquestes son

Funció Resultat

sin(nombre_real); cos(nombre_real); tan(nombre_real)

sinus, cosinus o tangent d’un nombre real en radians

asin(nombre_real); acos(nombre_real); atan(nombre_real)

arcsinus, arcosinus o arctangent en radians

exp(nombre_real) Valor de e elevat a la potència indicada sqrt(nombre_real) Arrel quadrada d’un nombre real log(nombre_real) Logaritme neperià d’un nombre real

log10(nombre_real) Logaritme en base 10 d’un nombre real

abs(nombre_real_o_integer) Valor absolut d‘un nombre real o sencer

mod(sencer1,sencer2) Resta entera de la divisió entre sencer1 i sencer2

real(nombre_sencer) Equivalent real d’un nombre sencer

Quan l’argument de la funció sigui un nombre real de doble precisió (REAL*8,

DOUBLE PRECISION) s’afegeix una “d” al nom de la funció.

sin(0.56) dsin(0.56d0)

Page 27: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

30

sqrt(37.8) dsqrt(4.0d0)

Tot i això alguns compiladors ajusten automàticament la precisió al tipus de dada que

s’utilitza com a argument sense necessitat d’afegir aquesta “d” extra.

Podem fer servir les funcions intrínseques en sentencies d’assignació o mostrar el

resultat directament

x = sin(3.0)

write(*,*) dsqrt(x)

Nosaltres podrem definir funcions (que poden ser matemàtiques o de qualsevol tipus) en

FORTRAN de manera que les puguem fer servir de manera anàloga a com s’utilitzen

les funcions intrinseques.

Per fer-ho hem de crear un subprograma de tipus funció. En aquest cas la nomenclatura

és la següent

function nom_funció (llista d’arguments)

declaració dels arguments

sentencies....

nom_funcio=expressió

end

És important tenir en compte que, com a subprograma, cal escriure la funció de manera

externa al programa principal. És a dir, normalment escriurem les funcions al final de

programa i sempre desprès de la sentencia end. (Fixeu-vos que al final de la

declaració de la funció també cal afegir la sentencia end).

Un cop definida la funció la podem fer servir dins el programa com una funció

intrínseca més. En aquest cas podríem fer

x = nom_funcio(llista d’arguments)

Page 28: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

31

Veiem un exemple: Podríem definir la funció f(x) =2 e- 2x + sin(πx)

function y(x)

IMPLICIT DOUBLE PRECISION (a-h,o-z)

PARAMETER(PI=dacos(-1.0d0))

y = 2.0d0*exp(-2.0d0*x)-sin(PI*x)

end

(Fixa’t en la manera d’introduir el valor de π. Així s’aconsegueix el màxim de precisió)

i dintre del programa podem cridar a la funció amb sentencies del tipus

val = y(2.0)

read(*,*) x0

write(*,*) ‘El valor de la funció a x0 = ‘,x0, ‘es ‘,y(x0)

Exemple: Definirem una funció entera que comprovi si un nombre N1 es divisible per

un altre N2. Cas que si, la funció ha de prendre el valor 1 i 0 en cas contrari. En aquest

cas li hem de passar a la funció dos arguments (N1i N2) que seran dues variables de

tipus INTEGER. Ho podríem fer de la següent manera

FUNCTION idiv(N1,N2) ir = mod(N1,N2) IF(ir.EQ.0) then idiv=0 else idiv=1 end if end

Llavors el programa principal quedaria

PROGRAM check_division WRITE(*,*) ‘Entra dos nombres enters i et dire si son divisibles entre si’ READ(*,*) N1,N2 IF(idiv(N1,N2).EQ.1) then WRITE(*,*) N1,' i’ ,N2, ‘son divisibles’ else WRITE(*,*) N1,' i’ ,N2, ‘no son divisibles’ end if end

Page 29: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

32

De fet, aquest programa no funcionarà en tots els casos. Es un exemple típic de

programa ben escrit però mal pensat.

Fixa’t que si N2 es més gran que N1 el programa dirà que els números son divisibles!

Per tant ens caldria afegir a la funció un filtre previ que comprovi que el divisor sigui

més petit que el dividend.

Per exemple

FUNCTION idiv(N1,N2) if(N1.gt.N2) then ir = mod(N1,N2) else ir = mod(N2,N1) end if IF(ir.EQ.0) then idiv=0 else idiv=1 end if end

En l’argot informàtic diem que ara la funció és més robusta.

De tota manera, ja que la funció en el fons ens ha de dir si o no, el més adient és definir-

la de tipus LOGICAL. La funció, amb una altra petita modificació podria quedar de la

següent manera.

LOGICAL FUNCTION idiv(N1,N2) idiv=.true. if(N1.gt.N2) then ir = mod(N1,N2) else ir = mod(N2,N1) end if IF(ir.EQ.0) idiv=.false. end

Fixeu-vos que la funció idiv és de tipus LOGICAL, de la mateixa manera que la versió

anterior era de tipus INTEGER. Per construir una funció que retorni un nombre

INTEGER només cal que el nom comenci per les lletres i-n.(sempre i quan no hàgim

sobreescrit les opcions per defecte). Si volem una funció de tipus LOGICAL ho hem de

expressar explícitament a l’hora de definir la funció (LOGICAL FUNCTION).

Page 30: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

33

Cal anar en compte ara. Ja que la funció és de tipus lògic, el seu resultat s’ha d’assignar

o ha de aparèixer en un context de tipus LOGICAL també. Per tant, caldria modificar el

programa principal de la manera següent

PROGRAM check_division LOGICAL idiv WRITE(*,*) ‘Entra dos nombres enters i et dire si son divisibles entre si’ READ(*,*) N1,N2 IF(idiv(N1,N2).EQ..true.) then WRITE(*,*) N1,' i’ ,N2, ‘son divisibles’ else WRITE(*,*) N1,' i’ ,N2, ‘no son divisibles’ end if end

Per últim, es important veure que els noms de les variables que es passen com a

argument a la funció i al programa principal no tenen perquè coincidir i, de fet, no ho

solen fer. El que si ha de coincidir és el tipus de variable i l’ordre en que es passen els

arguments. Per tant, escriure la funció anterior com

LOGICAL FUNCTION idiv(K1,K2) idiv=.true. if(K1.gt.K2) then ir = mod(K1,K2) else ir = mod(K2,K1) end if IF(ir.EQ.0) idiv=.false. end

no afecta en absolut el funcionament del programa. Simplement, quan el control del

programa es passa a la funció, aquesta pren els valors emmagatzemats a les variables

N1 i N2, els guarda amb altres variables K1 i K2 per utilitzar-los posteriorment. Tot i

això, en FORTRAN, si a la funció es modifiquen els valors assignats a K1 o K2, aquests

canvis es veuran reflectits també a les variables N1 i N2 quan el control del programa

torni al programa principal.

Page 31: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

34

Subrutines

Sovint, les operacions que cal fer son massa llargues o complexes per poder incloure-les

dins una funció3. Si decidim posar-les dins el programa principal podríem fer més difícil

el seguiment de l’estructura lògica del programa. Per exemple, si al mig d’un programa

haguéssim d’invertir una matriu seria més còmode dir-li al ordinador

Deixa per un moment el que estàs fent, inverteix aquesta matriu, i quan estiguis, torna

amb el que feies

Això precisament és el que fan les subrutines. És un programa independent que és cridat

dins el programa principal, i que realitza una feia concreta. Un cop terminada, es retorna

automàticament el control al programa principal. En aquest cas la sintaxi és la següent

subroutine nom_funció (llista d’arguments)

declaració dels arguments

sentencies....

end

És clar que, com a programa independent, necessita comunicar-se amb el programa

principal per a) disposar de les dades inicials necessàries (input) i b) passar-li al

programa principal les noves dades calculades (output). Aquestes variables d’input,

output i input-output4 s’especifiquen a la llista d’arguments. Noteu que aquestes

variables s’han de declarar, de la mateixa manera que es fa al programa principal. És a

dir que si la variable que passem es de tipus CHARACTER o una matriu, cal incloure

les respectives sentències CHARACTER i DIMENSION a la subrutina. De la mateixa

manera, per evitar sorpreses, si hem afegit al programa principal la sentència

implicit double precision(a-h,o-z)

el mateix hauríem de fer als subprogrames (tant de tipus funció com subrutina)

3 A més, podríem necessitar que el subprograma ens retornés més d’un únic valor (una matriu, per

exemple) i per tant la funció no ens serviria. 4 En aquest cas el valor de la variable d’input inicial es sobreescriu dins la subrutina i el seu valor

modificat es passa al programa principal

Page 32: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

35

Crides a les subrutines

Per poder accedir a una subrutina dins un programa farem servir la sentència CALL. Per

exemple, si hem definit una subrutina determinada

subroutine fes_algo(llista_arguments)

la cridarem des de el programa principal fent

call fes_algo(llista_arguments)

Recordeu que a la subrutina li hem de passar el mateix tipus d’arguments (i en el

mateix ordre), però no tenen perquè tenir el mateix nom. A més, les variables que no

es passen com a arguments dins una subrutina no són visibles pel programa

principal i viceversa. Per tant, podem fer servir variables amb el mateix nom al

programa principal (tipicament i, j, k, etc per als bucles) i als subprogrames sense que

interfereixin.

Cal tenir en compte que l’ús de subrutines respon més a raons estètiques que

computacionals. Res impedeix fer un programa sense subrutines, tot i que sovint es

redueix la complexitat i longitud del codi. Per exemple, suposem que disposem d’una

subrutina que realitza el producte de dues matrius quadrades de dimensió N. La

subrutina es diu multmat i els seus arguments son la dimensió de les matrius (N), les

matrius a multiplicar (A,B) i la matriu on emmagatzemarem el resultat (C).

Les primeres linees de la declaració de la subrutina haurian de ser quelcom com

subroutine multmat(N,A,B,C)

implicit double precision(a-h,o-z)

parameter(maxdim=100)

dimension A(maxdim,maxdim),B(maxdim,maxdim),C(maxdim,maxdim)

Llavors, dins el programa prinicpal, la subrutina s’hauria de cridar de la manera següent

call multmat(N,A,B,C)

Podem veure la utilitat de definir subrutines si ens plantegem determinar la k-essima

potència d’una matriu (Ak). En aquesta cas el programa es podria escriure de la següent

manera

Page 33: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

36

PROGRAM potencia PARAMETER(MAXDIM=100) DIMENSION A(MAXDIM),A2(MAXDIM), AK(MAXDIM) WRITE(*,*) ‘Entra les dimensions de la matriu quadrada :' READ(*,*) N WRITE(*,*) ‘Entra la matriu per files:' do i = 1,N READ(*,*) (A(i,j)=j=1,N) end do WRITE(*,*) Quina potència vols calcular?' READ(*,*) k do i=1,N do j=1,N a2(i,j)=a(i,j) !Copiem la matriu A a una matriu auxiliar end do end do do i=1,k-1 ! hem de realitzar k-1 productes... call multmat(N,A2,A,Ak) !fem Ak=A2xA do i=1,N do j=1,N a2(i,j)=ak(i,j) !Desprès de fer cada producte copiem end do !el resultat en la matriu auxiliar end do end do WRITE(*,*) ‘Resultat:' do i=1,N WRITE(*,*) (Ak(i,j)=j=1,N) end do end

És clar que no és el algorisme més eficient! Per altra banda, fixeu-vos que hi ha part de

codi repetida; el necessària per copiar una matriu en una altra. Per fer el codi més

llegible podríem fer una altra subrutina que fes aquesta feina.

SUBROUTINE copiamatriu(N,A,B) PARAMETER(MAXDIM=200) DIMENSION A(MAXDIM),B(MAXDIM) do i=1,N do j=1,N B(i,j)=A(i,j) !Copiem la matriu A a B end do end do end

Page 34: 1.- Programació en FORTRANiqc.udg.es/~perico/docencia/QTC/prog_fortran.pdf · 1.1- Ordinadors, llenguatges d'alt nivell, ... programació en el llenguatge FORTRAN. Els avantatges

Tècniques Computacionals, Curs 2007-2008. Pedro Salvador

37

i llavors al programa principal es podria fer

PROGRAM potencia PARAMETER(MAXDIM=200) DIMENSION A(MAXDIM),A2(MAXDIM), AK(MAXDIM) WRITE(*,*) ‘Entra les dimensions de la matriu quadrada :' READ(*,*) N WRITE(*,*) ‘Entra la matriu per files:' do i=1,N READ(*,*) (A(i,j)=j=1,N) end do WRITE(*,*) Quina potència vols calcular?' READ(*,*) k call copiamatriu(N,A,A2) do i=1,k-1 call multmat(N,A2,A,Ak) ! hem de realitzar k-1 productes... call copiamatriu(N,Ak,A2) end do WRITE(*,*) ‘Resultat:' do i=1,N WRITE(*,*) (Ak(i,j)=j=1,N) end do end

Totes dues versions fan el mateix però aquesta última queda més compacta i més fàcil

d’entendre.