Fortran 2003

Fortran 2003 is the latest 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 WorldEdit

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

Fortran 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

arraysEdit

Fortran 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

loopsEdit

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

Fortran 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

doEdit

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

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

A 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

subroutinesEdit

A 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

See AlsoEdit

Last modified on 6 March 2011, at 03:15