Vous êtes sur la page 1sur 15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

Fortran/Fortranexamples
PartoftheFortranWikiBook
ThefollowingFortrancodeexamplesorsampleprogramsshowdifferentsituationsdependingonthe
compiler.ThefirstsetofexamplesarefortheFortranII,IV,and77compilers.Theremainingexamples
canbecompiledandrunwithanynewerstandardFortrancompiler(seetheendofthemainFortran
articleforlistsofcompilers).MostmodernFortrancompilersexpectafilewitha.for.forextension
(forFORTRAN66orFORTRAN77source,althoughtheFORTRAN66dialectmayhavetobe
selectedspecificallywithacommandlineoption)or.f90/.f95extension(forFortran90/95source,
respectively).

Contents
1FORTRANII,IV,and77compilers
1.1AreaOfaTriangleprogram
1.1.1SimpleFortranIIprogram
1.1.2SimpleFortranIVprogram
1.1.3SimpleFortran77program
2"Retro"FORTRANIV
2.1Hello,Worldprogram
2.1.1FORTRAN66(alsoFORTRANIV)
2.1.2FORTRAN77
2.1.3Fortran90
3Fortran77examples
3.1Greatestcommondivisor
3.2Complexnumbers
4Fortran90/95examples
4.1SummationswithaDOloop
4.2Calculatingcylinderarea
4.3Dynamicmemoryallocationandarrays
4.4Writingfunctions
4.5Writingsubroutines
4.6InternalandElementalProcedures
4.7Pointersandtargetsmethods
4.8Moduleprogramming

FORTRANII,IV,and77compilers
NOTE:BeforeFORTRAN90,mostFORTRANcompilersenforcedfixedformatsourcecode,a
carryoverfromIBMpunchcards(http://en.wikipedia.org/wiki/Punch_card)
commentsmustbeginwitha*orCor!incolumn1
statementlabelsmustoccurincolumns15
continuationlinesmusthaveanonblankcharacterincolumn6
statementsmuststartincolumn7
thelinelengthmaybelimitedto72characters(derivedfromthe80bytewidthofapunchcard,
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

1/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

withlast8charactersreservedfor(optional)sequencenumbers)
IferrorsareproducedwhenyoucompileyourFORTRANcode,firstcheckthecolumnalignment.Some
compilersalsoofferfreeformsourcebyusingacompilerflag

AreaOfaTriangleprogram
SimpleFortranIIprogram
Onedatacardinput
Ifoneoftheinputvaluesiszero,thentheprogramwillendwithanerrorcodeof"1"inthejobcontrol
cardlistingfollowingtheexecutionoftheprogram.NormaloutputwillbeonelineprintedwithA,B,C,
andAREA.Nospecificunitsarestated.

CAREAOFATRIANGLEHERON'SFORMULA
CINPUTCARDREADERUNIT5,INTEGERINPUT
COUTPUTLINEPRINTERUNIT6,REALOUTPUT
CINPUTERRORDISPAYERROROUTPUTCODE1INJOBCONTROLLISTING
INTEGERA,B,C
READ(5,501)A,B,C
501FORMAT(3I5)
IF(A.EQ.0.OR.B.EQ.0.OR.C.EQ.0)STOP1
S=(A+B+C)/2.0
AREA=SQRT(S*(SA)*(SB)*(SC))
WRITE(6,601)A,B,C,AREA
601FORMAT(4HA=,I5,5HB=,I5,5HC=,I5,8HAREA=,F10.2,12HSQUAREUNITS)
STOP
END

SimpleFortranIVprogram
Multipledatacardinput
Thisprogramhastwoinputchecks:oneforablankcardtoindicateendofdata,andtheotherforazero
valuewithintheinputdata.Eitherconditioncausesamessagetobeprinted.

CAREAOFATRIANGLEHERON'SFORMULA
CINPUTCARDREADERUNIT5,INTEGERINPUT,ONEBLANKCARDFORENDOFDATA
COUTPUTLINEPRINTERUNIT6,REALOUTPUT
CINPUTERRORDISPAYERRORMESSAGEONOUTPUT
501FORMAT(3I5)
601FORMAT(4HA=,I5,5HB=,I5,5HC=,I5,8HAREA=,F10.2,12HSQUAREUNITS)
602FORMAT(10HNORMALEND)
603FORMAT(23HINPUTERROR,ZEROVALUE)
INTEGERA,B,C
10READ(5,501)A,B,C
IF(A.EQ.0.AND.B.EQ.0.AND.C.EQ.0)GOTO50
IF(A.EQ.0.OR.B.EQ.0.OR.C.EQ.0)GOTO90
S=(A+B+C)/2.0
AREA=SQRT(S*(SA)*(SB)*(SC))
WRITE(6,601)A,B,C,AREA
GOTO10
50WRITE(6,602)
STOP
90WRITE(6,603)
STOP
END

http://en.wikibooks.org/wiki/Fortran/Fortran_examples

2/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

SimpleFortran77program
Multipledatacardinput
ThisprogramhastwoinputchecksintheREADstatementwiththeENDandERRparameters,onefora
blankcardtoindicateendofdataandtheotherforzerovaluealongwithvaliddata.Ineithercondition,
amessagewillbeprinted.

CAREAOFATRIANGLEHERON'SFORMULA
CINPUTCARDREADERUNIT5,INTEGERINPUT,NOBLANKCARDFORENDOFDATA
COUTPUTLINEPRINTERUNIT6,REALOUTPUT
CINPUTERRORDISPAYSERRORMESSAGEONOUTPUT
501FORMAT(3I5)
601FORMAT("A=",I5,"B=",I5,"C=",I5,"AREA=",F10.2,"SQUAREUNITS")
602FORMAT("NORMALEND")
603FORMAT("INPUTERRORORZEROVALUEERROR")
INTEGERA,B,C
10READ(5,501,END=50,ERR=90)A,B,C
IF(A=0.OR.B=0.OR.C=0)GOTO90
S=(A+B+C)/2.0
AREA=SQRT(S*(SA)*(SB)*(SC))
WRITE(6,601)A,B,C,AREA
GOTO10
50WRITE(6,602)
STOP
90WRITE(6,603)
STOP
END

"Retro"FORTRANIV
AretroexampleofaFORTRANIV(laterevolvedintoFORTRAN66)programdeckisavailableonthe
IBM1130page,includingtheIBM1130DM2JCLrequiredforcompilationandexecution.AnIBM
1130emulatorisavailableatIBM1130.org(http://ibm1130.org/)thatwillallowtheFORTRANIV
programtobecompiledandrunonaPC.

Hello,Worldprogram
Inkeepingwithcomputingtradition,thefirstexamplepresentedisasimpleprogramtodisplaythe
words"Hello,world"onthescreen(orprinter).
FORTRAN66(alsoFORTRANIV)

CFORTRANIVWASONEOFTHEFIRSTPROGRAMMING
CLANGUAGESTOSUPPORTSOURCECOMMENTS
WRITE(6,7)
7FORMAT(13HHELLO,WORLD)
STOP
END

Thisprogramprints"HELLO,WORLD"toFortranunitnumber6,whichonmostmachineswastheline
printerorterminal.(Thecardreaderorkeyboardwasusuallyconnectedasunit5).Thenumber7inthe
WRITEstatementreferstothestatementnumberofthecorrespondingFORMATstatement.FORMATstatements
maybeplacedanywhereinthesameprogramorfunction/subroutineblockastheWRITEstatements
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

3/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

whichreferencethem.TypicallyaFORMATstatementisplacedimmediatelyfollowingtheWRITEstatement
whichinvokesitalternatively,FORMATstatementsaregroupedtogetherattheendoftheprogramor
subprogramblock.IfexecutionflowsintoaFORMATstatement,itisanoopthus,theexampleabovehas
onlytwoexecutablestatements,WRITEandSTOP.
Theinitial13HintheFORMATstatementintheaboveexampledefinesaHollerithconstant,heremeaning
thatthe13charactersimmediatelyfollowingaretobetakenasacharacterconstant(notethatthe
Hollerithconstantisnotsurroundedbydelimiters).(Somecompilersalsosupportedcharacterliterals
enclosedinsinglequotes,apracticethatcametobestandardwithFORTRAN77.)
Thespaceimmediatelyfollowingthe13Hisacarriagecontrolcharacter,tellingtheI/Osystemto
advancetoanewlineontheoutput.Azerointhispositionadvancestwolines(doublespace),a1
advancestothetopofanewpageand+characterwillnotadvancetoanewline,allowingoverprinting.
FORTRAN77
AsofFORTRAN77,singlequotesareusedtodelimitcharacterliterals,andinlinecharacterstringsmay
beusedinsteadofreferencestoFORMATstatements.CommentlinesmaybeindicatedwitheitheraCoran
asterisk(*)incolumn1.

PROGRAMHELLO
*ThePRINTstatementislikeWRITE,
*butprintstothestandardoutputunit
PRINT'(A)','Hello,world'
STOP
END

Fortran90
AsofFortran90,doublequotesareallowedinadditiontosinglequotes.Anupdatedversionofthe
Hello,worldexample(whichheremakesuseoflistdirectedI/O,supportedasofFORTRAN77)could
bewritteninFortran90asfollows:

programHelloWorld
write(*,*)'Hello,world!'!Thisisaninlinecomment
endprogramHelloWorld

Fortran77examples
Greatestcommondivisor
ThefollowingintroductoryexampleinFORTRAN77findsthegreatestcommondivisorfortwo
numbers and usingaverbatimimplementationofEuclid'salgorithm.

*euclid.f(FORTRAN77)
*FindgreatestcommondivisorusingtheEuclideanalgorithm

http://en.wikibooks.org/wiki/Fortran/Fortran_examples

4/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

PROGRAMEUCLID
PRINT*,'A?'
READ*,NA
IF(NA.LE.0)THEN
PRINT*,'Amustbeapositiveinteger.'
STOP
ENDIF
PRINT*,'B?'
READ*,NB
IF(NB.LE.0)THEN
PRINT*,'Bmustbeapositiveinteger.'
STOP
ENDIF
PRINT*,'TheGCDof',NA,'and',NB,'is',NGCD(NA,NB),'.'
STOP
END

FUNCTIONNGCD(NA,NB)
IA=NA
IB=NB
1IF(IB.NE.0)THEN
ITEMP=IA
IA=IB
IB=MOD(ITEMP,IB)
GOTO1
ENDIF
NGCD=IA
RETURN
END

Theaboveexampleisintendedtoillustratethefollowing:
ThePRINTandREADstatementsintheaboveuse'*'asaformat,specifyinglistdirectedformatting.
Listdirectedformattinginstructsthecompilertomakeaneducatedguessabouttherequiredinput
oroutputformatbasedonthefollowingarguments.
AstheearliestmachinesrunningFortranhadrestrictedcharactersets,FORTRAN77uses
abbreviationssuchas.EQ.,.NE.,.LT.,.GT.,.LE.,and.GE.torepresenttherelationaloperators=,
,<,>,,and,respectively.
ThisexamplereliesontheimplicittypingmechanismtospecifytheINTEGERtypesofNA,NB,IA,
IB,andITEMP.
InthefunctionNGCD(NA,NB),thevaluesofthefunctionargumentsNAandNBarecopiedintothe
localvariablesIAandIBrespectively.ThisisnecessaryasthevaluesofIAandIBarealtered
withinthefunction.BecauseargumentpassinginFortranfunctionsandsubroutinesutilizecallby
referencebydefault(ratherthancallbyvalue,asisthedefaultinlanguagessuchasC),modifying
NAandNBfromwithinthefunctionwouldeffectivelyhavemodifiedthecorrespondingactual
argumentsinthemainPROGRAMunitwhichcalledthefunction.
Thefollowingshowstheresultsofcompilingandrunningtheprogram.

$g77oeuclideuclid.f
$euclid
A?
24
B?
36
TheGCDof24and36is12.

Complexnumbers
ThefollowingFORTRAN77exampleprintsoutthevaluesof
.
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

(where

)forvaluesof

5/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

*cmplxd.f(FORTRAN77)
*DemonstrationofCOMPLEXnumbers
*
*Printsthevaluesofe**(j*i*pi/4)fori=0,1,2,...,7
*wherejistheimaginarynumbersqrt(1)

PROGRAMCMPLXD
IMPLICITCOMPLEX(X)
PARAMETER(PI=3.141592653589793,XJ=(0,1))
DO1,I=0,7
X=EXP(XJ*I*PI/4)
IF(AIMAG(X).LT.0)THEN
PRINT2,'e**(j*',I,'*pi/4)=',REAL(X),'j',AIMAG(X)
ELSE
PRINT2,'e**(j*',I,'*pi/4)=',REAL(X),'+j',AIMAG(X)
ENDIF
2FORMAT(A,I1,A,F10.7,A,F9.7)
1CONTINUE
STOP
END

Theaboveexampleisintendedtoillustratethefollowing:
TheIMPLICITstatementcanbeusedtospecifytheimplicittypeofvariablesbasedontheirinitial
letterifdifferentfromthedefaultimplicittypingschemedescribedabove.Inthisexample,this
statementspecifiesthattheimplicittypeofvariablesbeginningwiththeletterXshallbeCOMPLEX.
ThePARAMETERstatementmaybeusedtospecifyconstants.Thesecondconstantinthisexample
(XJ)isgiventhecomplexvaluedvalue
,where istheimaginaryunit
.
ThefirstnumberintheDOstatementspecifiesthenumberofthelaststatementconsideredtobe
withinthebodyoftheDOloop.Inthisexample,asneithertheENDIFnortheFORMATisasingle
executablestatement,theCONTINUEstatement(whichdoesnothing)isusedsimplyinorderfor
theretobesomestatementtodenoteasthefinalstatementoftheloop.
EXP()correspondstotheexponentialfunction .InFORTRAN77,thisisagenericfunction,
meaningthatitacceptsargumentsofmultipletypes(suchasREALand,inthisexample,COMPLEX).
InFORTRAN66,aspecificfunctionwouldhavetobecalledbynamedependingonthetypeof
thefunctionarguments(forthisexample,CEXP()foraCOMPLEXvaluedargument).
WhenappliedtoaCOMPLEXvaluedargument,REAL()andAIMAG()returnthevaluesofthe
argument'srealandimaginarycomponents,respectively.
Incidentally,theoutputoftheaboveprogramisasfollows(seethearticleonEuler'sformulaforthe
geometricinterpretationofthesevaluesaseightpointsspacedevenlyaboutaunitcircleinthecomplex
plane).

$cmplxd
e**(j*0*pi/4)=1.0000000+j0.0000000
e**(j*1*pi/4)=0.7071068+j0.7071068
e**(j*2*pi/4)=0.0000000+j1.0000000
e**(j*3*pi/4)=0.7071068+j0.7071068
e**(j*4*pi/4)=1.0000000j0.0000001
e**(j*5*pi/4)=0.7071066j0.7071069
e**(j*6*pi/4)=0.0000000j1.0000000
e**(j*7*pi/4)=0.7071070j0.7071065

Errorcanbeseenoccurringinthelastdecimalplaceinsomeofthenumbersabove,aresultofthe
COMPLEXdatatyperepresentingitsrealandimaginarycomponentsinsingleprecision.Incidentally,
Fortran90alsomadestandardadoubleprecisioncomplexnumberdatatype(althoughseveral
compilersprovidedsuchatypeevenearlier).
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

6/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

Fortran90/95examples
SummationswithaDOloop
InthisexampleofFortran90code,theprogrammerhaswrittenthebulkofthecodeinsideofaDOloop.
Uponexecution,instructionsareprintedtothescreenandaSUMvariableisinitializedtozerooutside
theloop.Oncetheloopbegins,itaskstheusertoinputanynumber.Thisnumberisaddedtothe
variableSUMeverytimethelooprepeats.Iftheuserinputs0,theEXITstatementterminatestheloop,
andthevalueofSUMisdisplayedonscreen.
Alsoapparentinthisprogramisadatafile.Beforetheloopbegins,theprogramcreates(oropens,ifit
hasalreadybeenrunbefore)atextfilecalled"SumData.DAT".Duringtheloop,theWRITEstatement
storesanyuserinputtednumberinthisfile,anduponterminationoftheloop,alsosavestheanswer.

!sum.f90
!PerformssummationsusinginaloopusingEXITstatement
!Savesinputinformationandthesummationinadatafile

programsummation
implicitnone
integer::sum,a

print*,"Thisprogramperformssummations.Enter0tostop."
open(unit=10,file="SumData.DAT")

sum=0

do
print*,"Add:"
read*,a
if(a==0)then
exit
else
sum=sum+a
endif
write(10,*)a
enddo

print*,"Summation=",sum
write(10,*)"Summation=",sum
close(10)

end

Whenexecuted,theconsolewoulddisplaythefollowing:

Thisprogramperformssummations.Enter0tostop.
Add:
1
Add:
2
Add:
3
Add:
0
Summation=6

AndthefileSumData.DATwouldcontain:

http://en.wikibooks.org/wiki/Fortran/Fortran_examples

7/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

1
2
3
Summation=6

Calculatingcylinderarea
Thefollowingprogram,whichcalculatesthesurfaceareaofacylinder,illustratesfreeformsourceinput
andotherfeaturesintroducedbyFortran90.

programcylinder

!Calculatethesurfaceareaofacylinder.
!
!Declarevariablesandconstants.
!constants=pi
!variables=radiussquaredandheight

implicitnone!Requireallvariablestobeexplicitlydeclared

integer::ierr
character(1)::yn
real::radius,height,area
real,parameter::pi=3.141592653589793

interactive_loop:do

!Prompttheuserforradiusandheight
!andreadthem.

write(*,*)'Enterradiusandheight.'
read(*,*,iostat=ierr)radius,height

!Ifradiusandheightcouldnotbereadfrominput,
!thencyclethroughtheloop.

if(ierr/=0)then
write(*,*)'Error,invalidinput.'
cycleinteractive_loop
endif

!Computearea.The**means"raisetoapower."

area=2*pi*(radius**2+radius*height)

!Writetheinputvariables(radius,height)
!andoutput(area)tothescreen.

write(*,'(1x,a7,f6.2,5x,a7,f6.2,5x,a5,f6.2)')&
'radius=',radius,'height=',height,'area=',area

yn=''
yn_loop:do
write(*,*)'Performanothercalculation?y[n]'
read(*,'(a1)')yn
if(yn=='y'.or.yn=='Y')exityn_loop
if(yn=='n'.or.yn=='N'.or.yn=='')exitinteractive_loop
enddoyn_loop

enddointeractive_loop

endprogramcylinder

Dynamicmemoryallocationandarrays
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

8/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

Thefollowingprogramillustratesdynamicmemoryallocationandarraybasedoperations,twofeatures
introducedwithFortran90.ParticularlynoteworthyistheabsenceofDOloopsandIF/THENstatementsin
manipulatingthearraymathematicaloperationsareappliedtothearrayasawhole.Alsoapparentisthe
useofdescriptivevariablenamesandgeneralcodeformattingthatcomportwithcontemporary
programmingstyle.Thisexamplecomputesanaverageoverdataenteredinteractively.

programaverage

!Readinsomenumbersandtaketheaverage
!Aswritten,iftherearenodatapoints,anaverageofzeroisreturned
!Whilethismaynotbedesiredbehavior,itkeepsthisexamplesimple

implicitnone
integer::number_of_points
real,dimension(:),allocatable::points
real::average_points=0.,positive_average=0.,negative_average=0.

write(*,*)"Inputnumberofpointstoaverage:"
read(*,*)number_of_points

allocate(points(number_of_points))

write(*,*)"Enterthepointstoaverage:"
read(*,*)points

!Taketheaveragebysummingpointsanddividingbynumber_of_points
if(number_of_points>0)average_points=sum(points)/number_of_points

!Nowformaverageoverpositiveandnegativepointsonly
if(count(points>0.)>0)positive_average=sum(points,points>0.)&
/count(points>0.)
if(count(points<0.)>0)negative_average=sum(points,points<0.)&
/count(points<0.)

deallocate(points)

!Printresulttoterminal
write(*,'(''Average='',1g12.4)')average_points
write(*,'(''Averageofpositivepoints='',1g12.4)')positive_average
write(*,'(''Averageofnegativepoints='',1g12.4)')negative_average

endprogramaverage

Writingfunctions
ModernFortranfeaturesavailableforusewithprocedures,includingdeferredshape,protected,and
optionalarguments,areillustratedinthefollowingexample,afunctiontosolveasystemoflinear
equations.

functiongauss_sparse(num_iter,tol,b,A,x,actual_iter)result(tol_max)

!Thisfunctionsolvesasystemofequations(Ax=b)byusingtheGaussSeidelMethod

implicitnone

real::tol_max

!Input:itsvaluecannotbemodifiedfromwithinthefunction
integer,intent(in)::num_iter
real,intent(in)::tol
real,intent(in),dimension(:)::b,A(:,:)

!Input/Output:itsinputvalueisusedwithinthefunction,andcanbemodified
real,intent(inout)::x(:)

!Output:itsvalueismodifiedfromwithinthefunction,onlyiftheargumentisrequired
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

9/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

integer,optional,intent(out)::actual_iter

!Locals
integer::i,n,iter
real::xk

!Initializevalues
n=size(b)!Sizeofarray,obtainedusingsizeintrinsicfunction
tol_max=2.*tol
iter=0

!Computesolutionuntilconvergence
convergence_loop:dowhile(tol_max>=tol.and.iter<num_iter);iter=iter+1

tol_max=1.!Resetthetolerancevalue

!Computesolutionforthekthiteration
iteration_loop:doi=1,n

!Computethecurrentxvalue
xk=(b(i)dot_product(A(i,:i1),x(:i1))dot_product(A(i,i+1:n),x(i+1:n)))/A(i,i)

!Computetheerrorofthesolution
!dot_product(a,v)=a'b
tol_max=max((abs(x(i)xk)/(1.+abs(xk)))**2,abs(A(i,i)*(x(i)xk)),tol_max)
x(i)=xk
enddoiteration_loop
enddoconvergence_loop

if(present(actual_iter))actual_iter=iter

endfunctiongauss_sparse

Notethatanexplicitinterfacetothisroutinemustbeavailabletoitscallersothatthetypesignatureis
known.ThisispreferablydonebyplacingthefunctioninaMODULEandthenUSEingthemoduleinthe
callingroutine.AnalternativeistouseanINTERFACEblock,asshownbythefollowingexample:

programtest_gauss_sparse
implicitnone

!explicitinterfacetothegauss_sparsefunction
interface
functiongauss_sparse(num_iter,tol,b,A,x,actual_iter)result(tol_max)
real::tol_max
integer,intent(in)::num_iter
real,intent(in)::tol
real,intent(in),dimension(:)::b,A(:,:)
real,intent(inout)::x(:)
integer,optional,intent(out)::actual_iter
endfunction
endinterface

!declarevariables
integer::i,N=3,actual_iter
real::residue
real,allocatable::A(:,:),x(:),b(:)

!allocatearrays
allocate(A(N,N),b(N),x(N))

!Initializematrix
A=reshape([(real(i),i=1,size(A))],shape(A))

!Makematrixdiagonallydominant
doi=1,size(A,1)
A(i,i)=sum(A(i,:))+1
enddo

!Initializeb
b=[(i,i=1,size(b))]

!Initial(guess)solution
x=b

http://en.wikibooks.org/wiki/Fortran/Fortran_examples

10/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

!invokethegauss_sparsefunction
residue=gauss_sparse(num_iter=100,&
tol=1E5,&
b=b,&
A=a,&
x=x,&
actual_iter=actual_iter)

!Output
print'(/"A=")'
doi=1,size(A,1)
print'(100f6.1)',A(i,:)
enddo

print'(/"b="/(f6.1))',b

print'(/"residue=",g10.3/"iterations=",i0/"solution="/(11x,g10.3))',&
residue,actual_iter,x

endprogramtest_gauss_sparse

Writingsubroutines
Inthosecaseswhereitisdesiredtoreturnvaluesviaaprocedure'sarguments,asubroutineispreferred
overafunctionthisisillustratedbythefollowingsubroutinetoswapthecontentsoftwoarrays:

subroutineswap_real(a1,a2)

implicitnone

!Input/Output
real,intent(inout)::a1(:),a2(:)

!Locals
integer::i
real::a

!Swap
doi=1,min(size(a1),size(a2))
a=a1(i)
a1(i)=a2(i)
a2(i)=a
enddo

endsubroutineswap_real

Asinthepreviousexample,anexplicitinterfacetothisroutinemustbeavailabletoitscallersothatthe
typesignatureisknown.Asbefore,thisispreferablydonebyplacingthefunctioninaMODULEandthen
USEingthemoduleinthecallingroutine.AnalternativeistouseaINTERFACEblock.

InternalandElementalProcedures
Analternativewaytowritetheswap_realsubroutinefromthepreviousexample,is:

subroutineswap_real(a1,a2)

implicitnone

!Input/Output
real,intent(inout)::a1(:),a2(:)

!Locals
integer::N
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

11/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

!Swap,usingtheinternalsubroutine
N=min(size(a1),size(a2))
callswap_e(a1(:N),a2(:N))

contains
elementalsubroutineswap_e(a1,a2)
real,intent(inout)::a1,a2
real::a
a=a1
a1=a2
a2=a
endsubroutineswap_e
endsubroutineswap_real

Intheexample,theswap_esubroutineiselemental,i.e.,itactsuponitsarrayarguments,onanelement
byelementbasis.Elementalproceduresmustbepure(i.e.,theymusthavenosideeffectsandcaninvoke
onlypureprocedures),andalltheargumentsmustbescalar.Sinceswap_eisinternaltotheswap_real
subroutine,nootherprogramunitcaninvokeit.
Thefollowingprogramservesasatestforanyofthetwoswap_realsubroutinespresented:

programtest_swap_real
implicitnone

!explicitinterfacetotheswap_realsubroutine
interface
subroutineswap_real(a1,a2)
real,intent(inout)::a1(:),a2(:)
endsubroutineswap_real
endinterface

!Declarevariables
integer::i
real::a(10),b(10)

!Initializea,b
a=[(real(i),i=1,20,2)]
b=a+1

!Outputbeforeswap
print'(/"beforeswap:")'
print'("a=[",10f6.1,"]")',a
print'("b=[",10f6.1,"]")',b

!Calltheswap_realsubroutine
callswap_real(a,b)

!Outputafterswap
print'(//"afterswap:")'
print'("a=[",10f6.1,"]")',a
print'("b=[",10f6.1,"]")',b

endprogramtest_swap_real

Pointersandtargetsmethods
InFortran,theconceptofpointersdiffersfromthatinClikelanguages.AFortran90pointerdoesnot
merelystorethememoryaddressofatargetvariableitalsocontainsadditionaldescriptiveinformation
suchasthetarget'srank,theupperandlowerboundsofeachdimension,andevenstridesthrough
memory.ThisallowsaFortran90pointertopointatsubmatrices.

http://en.wikibooks.org/wiki/Fortran/Fortran_examples

12/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

Fortran90pointersare"associated"withwelldefined"target"variables,viaeitherthepointer
assignmentoperator(=>)oranALLOCATEstatement.Whenappearinginexpressions,pointersarealways
dereferencedno"pointerarithmetic"ispossible.
Thefollowingexampleillustratestheconcept:

moduleSomeModule
implicitnone
contains
elementalfunctionA(x)result(res)
integer::res
integer,intent(IN)::x
res=x+1
endfunction
endmoduleSomeModule

programTest
useSomeModule,DoSomething=>A
implicitnone

!Declarevariables
integer,parameter::m=3,n=3
integer,pointer::p(:)=>null(),q(:,:)=>null()
integer,allocatable,target::A(:,:)
integer::istat=0,i,j
character(80)::fmt

!Writeformatstringformatrices
!(/A/A,"=[",3("[",3(i2,1x),"]"/5x),"]")
write(fmt,'("(/A/A,""=["",",i0,"(""["",",i0,"(i2,1x),""]""/5x),""]"")")')m,n

allocate(A(m,n),q(m,n),stat=istat)
if(istat/=0)stop'ErrorduringallocationofAandq'

!MatrixAis:
!A=[[147]
![258]
![369]
!]
A=reshape([(i,i=1,size(A))],shape(A))
q=A

write(*,fmt)"MatrixAis:","A",((A(i,j),j=1,size(A,2)),i=1,size(A,1))

!pwillbeassociatedwiththefirstcolumnofA
p=>A(:,1)

!ThisoperationonphasadirecteffectonmatrixA
p=p**2

!ThiswillendtheassociationbetweenpandthefirstcolumnofA
nullify(p)

!MatrixAbecomes:
!A=[[147]
![458]
![969]
!]
write(*,fmt)"MatrixAbecomes:","A",((A(i,j),j=1,size(A,2)),i=1,size(A,1))

!Performsomearrayoperation
q=q+A

!Matrixqbecomes:
!q=[[2814]
![61016]
![121218]
!]
write(*,fmt)"Matrixqbecomes:","q",((q(i,j),j=1,size(A,2)),i=1,size(A,1))

!Usepasanordinaryarray
allocate(p(1:m*n),stat=istat)
if(istat/=0)stop'Errorduringallocationofp'

!Performsomearrayoperation
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

13/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

p=reshape(DoSomething(A+A**2),shape(p))

!Arrayoperation:
!p(1)=3
!p(2)=21
!p(3)=91
!p(4)=21
!p(5)=31
!p(6)=43
!p(7)=57
!p(8)=73
!p(9)=91
write(*,'("Arrayoperation:"/(4x,"p(",i0,")=",i0))')(i,p(i),i=1,size(p))

deallocate(A,p,q,stat=istat)
if(istat/=0)stop'Errorduringdeallocation'

endprogramTest

Moduleprogramming
Amoduleisaprogramunitwhichcontainsdatadefinitions,globaldata,andCONTAINedprocedures.
UnlikeasimpleINCLUDEfile,amoduleisanindependentprogramunitthatcanbecompiledseparately
andlinkedinitsbinaryform.Oncecompiled,amodule'spubliccontentscanbemadevisibletoacalling
routineviatheUSEstatement.
Themodulemechanismmakestheexplicitinterfaceofprocedureseasilyavailabletocallingroutines.In
fact,modernFortranencourageseverySUBROUTINEandFUNCTIONtobeCONTAINedinaMODULE.Thisallows
theprogrammertousethenewerargumentpassingoptionsandallowsthecompilertoperformfulltype
checkingontheinterface.
Thefollowingexamplealsoillustratesderivedtypes,overloadingofoperatorsandgenericprocedures.

moduleGlobalModule

!Referencetoapairofproceduresincludedinapreviouslycompiled
!modulenamedPortabilityLibrary
usePortabilityLibrary,only:GetLastError,&!Genericprocedure
Date!Specificprocedure
!Constants
integer,parameter::dp_k=kind(1.0d0)!Doubleprecisionkind
real,parameter::zero=(0.)
real(dp_k),parameter::pi=3.141592653589793_dp_k

!Variables
integer::n,m,retint
logical::status,retlog
character(50)::AppName

!Arrays
real,allocatable,dimension(:,:,:)::a,b,c,d
complex(dp_k),allocatable,dimension(:)::z

!Derivedtypedefinitions
typeijk
integer::i
integer::j
integer::k
endtypeijk

typematrix
integerm,n
real,allocatable::a(:,:)!Fortran2003feature.ForFortran95,usethepointerattributeinstead
endtypematrix

!Allthevariablesandproceduresfromthismodulecanbeaccessed
!byotherprogramunits,exceptforAppName
public
http://en.wikibooks.org/wiki/Fortran/Fortran_examples

14/15

3/23/2015

Fortran/FortranexamplesWikibooks,openbooksforanopenworld

private::AppName

!Genericprocedureswap
interfaceswap
moduleprocedureswap_integer,swap_real
endinterfaceswap

interfaceGetLastError!Thisaddsanew,additionalproceduretothe
!genericprocedureGetLastError
moduleprocedureGetLastError_GlobalModule
endinterfaceGetLastError

!Operatoroverloading
interfaceoperator(+)
moduleprocedureadd_ijk
endinterface

!Prototypeforexternalprocedure
interface
functiongauss_sparse(num_iter,tol,b,A,x,actual_iter)result(tol_max)
real::tol_max
integer,intent(in)::num_iter
real,intent(in)::tol
real,intent(in),dimension(:)::b,A(:,:)
real,intent(inout)::x(:)
integer,optional,intent(out)::actual_iter
endfunctiongauss_sparse
endinterface

!Proceduresincludedinthemodule
contains

!Internalfunction
functionadd_ijk(ijk_1,ijk_2)
type(ijk)add_ijk,ijk_1,ijk_2
intent(in)::ijk_1,ijk_2
add_ijk=ijk(ijk_1%i+ijk_2%i,ijk_1%j+ijk_2%j,ijk_1%k+ijk_2%k)
endfunctionadd_ijk

!Includeexternalfiles
include'swap_integer.f90'!CommentsSHOULDN'Tbeaddedonincludelines
include'swap_real.f90'
endmoduleGlobalModule

Retrievedfrom"http://en.wikibooks.org/w/index.php?title=Fortran/Fortran_examples&oldid=2585181"

Thispagewaslastmodifiedon26November2013,at19:18.
TextisavailableundertheCreativeCommonsAttributionShareAlikeLicense.additionalterms
mayapply.Byusingthissite,youagreetotheTermsofUseandPrivacyPolicy.

http://en.wikibooks.org/wiki/Fortran/Fortran_examples

15/15

Vous aimerez peut-être aussi