Fortran 2003
A Wikibookian suggests that this book or chapter be merged into Fortran. Please discuss whether or not this merge should happen on the discussion page. |
Fortran 2003 is a standard of Fortran. This book will focus on modern Fortran, and it will not cover the obsolescent features of Fortran 77 and earlier standards.
Hello World
editHere is a Hello World program in Fortran.
program hello
implicit none
write (*,*) "Hello, world."
end program hello
The "implicit none" statement forces the programmer to declare all variables, which is considered good style. Fortran has integer, character, real, complex, and logical data types. The following program illustrates their use.
program data_types
implicit none
integer :: i
real :: x
logical :: tf
complex :: z
i = 3
x = 3.0
z = (3.0,3.0)
tf = .true.
write (*,*) "i =",i," x =",x," z =",z," tf = ",tf
end program data_types
output: i = 3 x = 3. z = (3.,3.) tf = T
arithmetic operators
editFortran has the arithmetic operators +, -, /,*, and ** (for exponentiation). The output of
program xx
implicit none
write (*,*) 2+3,2-3,2/3,4*3,2**3
end program xx
is
5 -1 0 12 8
Arrays
editFortran 90 and later versions have powerful functionality for arrays. The following program demonstrates some features of arrays. By default, array elements are numbered from 1, not 0, as in C or C++.
program xarray
! demonstrate array constructor and intrinsic functions
implicit none
integer, parameter :: n = 3
integer :: vec(n)
vec = (/9,4,1/) ! set vec(1) to 9, vec(2) to 4, vec(3) to 1
write (*,*) "vec = ",vec ! print each element of vec
write (*,*) "vec(1) = ",vec(1),", vec(3) =",vec(3) ! print the 1st and 3rd elements
write (*,*) "size(vec), sum(vec), product(vec) = ", &
size(vec), sum(vec), product(vec)
write (*,*) "minval(vec), maxval(vec) = ",minval(vec),maxval(vec)
vec = vec + 2 ! add 2 to each element of vec
write (*,*) "vec = ",vec ! print each element of vec
vec = vec**2 ! square each element of vec
write (*,*) "vec = ",vec ! print each element of vec
end program xarray
output:
vec = 9 4 1 vec(1) = 9 , vec(3) = 1 size(vec), sum(vec), product(vec) = 3 14 36 minval(vec), maxval(vec) = 1 9 vec = 11 6 3 vec = 121 36 9
loops
editFortran uses do loops for iteration. For example, the program
program xloop
implicit none
integer :: i
do i=1,3
write (*,*) i,i**2
end do
write (*,*) "i=",i
do i=1,4,2
write (*,*) i
end do
write (*,*) "i=",i
end program xloop
gives output
1 1 2 4 3 9 i= 4 1 3 i= 5
because within the first loop, variable i takes on values between 1 and 3 with step size of 1, and in the second loop the step size is 2. After completing the loop the value of i is its last value before leaving the loop plus the step size.
comparison operators
editFortran has the comparison operators < <= /= == >= > , where /= means "not equal" and the other operators have the usual meanings. The program
program xcompare
implicit none
write (*,*) 1<0,1<=0,1==0,1/=0,1>=0,1>0
end program xcompare
has output
F F F T T T
do
editOne can have a DO loop without a counter variable, in which case an EXIT statement will be needed to leave the loop, as shown in the following program
program xfibonacci
! print Fibonacci numbers up to max_fib
implicit none
integer, parameter :: max_fib = 10
integer :: i,fib,fib1,fib2
i = 0
fib = 0
fib1 = 0
fib2 = 0
write (*,*) "Fibonacci numbers <= ",max_fib
do
if (fib > max_fib) exit
write (*,*) fib
i = i + 1
if (i > 1) then
fib = fib1 + fib2
else
fib = 1
end if
fib2 = fib1
fib1 = fib
end do
end program xfibonacci
Declaring max_fib a parameter means that its value cannot be changed in the rest of the program.
nested loops
editLoops can be nested, as shown in the following program
program xnest
implicit none
integer :: i,j
do i=1,3
do j=1,2
write (*,*) "i,j=",i,j
end do
end do
end program xnest
which gives output
i,j= 1 1 i,j= 1 2 i,j= 2 1 i,j= 2 2 i,j= 3 1 i,j= 3 2
functions and return values
editA function can be used to return a value depending on zero or more arguments. The code below shows a function that converts from degrees Fahrenheit to degrees Celsius.
module convert_mod
implicit none
contains
function cels_from_fahr(degrees_fahr) result(degrees_cels)
real, intent(in) :: degrees_fahr
real :: degrees_cels
degrees_cels = (degrees_fahr-32)/1.8
end function cels_from_fahr
end module convert_mod
program xtemperature
use convert_mod, only: cels_from_fahr
real :: deg
integer :: i
write (*,"(2a10)") "degrees_F","degrees_C"
do i=12,100,20
deg = real(i)
write (*,"(2f10.1)") deg,cels_from_fahr(deg)
end do
end program xtemperature
Output:
degrees_F degrees_C 12.0 -11.1 32.0 0.0 52.0 11.1 72.0 22.2 92.0 33.3
subroutines
editA subroutine cannot be used in an expression and is invoked with a call statement, as demonstrated in the program below, which gives the same output as the program above.
module convert_mod
implicit none
contains
subroutine cels_from_fahr(degrees_fahr,degrees_cels)
real, intent(in) :: degrees_fahr
real, intent(out) :: degrees_cels
degrees_cels = (degrees_fahr-32)/1.8
end subroutine cels_from_fahr
end module convert_mod
program xtemperature
use convert_mod, only: cels_from_fahr
real :: deg_f,deg_c
integer :: i
write (*,"(2a10)") "degrees_F","degrees_C"
do i=12,100,20
deg_f = real(i)
call cels_from_fahr(deg_f,deg_c)
write (*,"(2f10.1)") deg_f,deg_c
end do
end program xtemperature