Category: Fortran

  • Dynamic Arrays

    dynamic array is an array, the size of which is not known at compile time, but will be known at execution time.

    Dynamic arrays are declared with the attribute allocatable.

    For example,

    real, dimension (:,:), allocatable :: darray    

    The rank of the array, i.e., the dimensions has to be mentioned however, to allocate memory to such an array, you use the allocate function.

    allocate ( darray(s1,s2) )      

    After the array is used, in the program, the memory created should be freed using the deallocate function

    deallocate (darray)  

    Example

    The following example demonstrates the concepts discussed above.

    program dynamic_array 
    implicit none 
    
       !rank is 2, but size not known   
       real, dimension (:,:), allocatable :: darray    
       integer :: s1, s2     
       integer :: i, j     
       
       print*, "Enter the size of the array:"     
       read*, s1, s2      
       
       ! allocate memory      
       allocate ( darray(s1,s2) )      
       
       do i = 1, s1           
    
      do j = 1, s2                
         darray(i,j) = i*j               
         print*, "darray(",i,",",j,") = ", darray(i,j)           
      end do      
    end do deallocate (darray) end program dynamic_array

    When the above code is compiled and executed, it produces the following result −

    Enter the size of the array: 3,4
    darray( 1 , 1 ) = 1.00000000    
    darray( 1 , 2 ) = 2.00000000    
    darray( 1 , 3 ) = 3.00000000    
    darray( 1 , 4 ) = 4.00000000    
    darray( 2 , 1 ) = 2.00000000    
    darray( 2 , 2 ) = 4.00000000    
    darray( 2 , 3 ) = 6.00000000    
    darray( 2 , 4 ) = 8.00000000    
    darray( 3 , 1 ) = 3.00000000    
    darray( 3 , 2 ) = 6.00000000    
    darray( 3 , 3 ) = 9.00000000    
    darray( 3 , 4 ) = 12.0000000   
    

    Use of Data Statement

    The data statement can be used for initialising more than one array, or for array section initialisation.

    The syntax of data statement is −

    data variable / list / ...
    

    Example

    The following example demonstrates the concept −

    program dataStatement
    implicit none
    
       integer :: a(5), b(3,3), c(10),i, j
       data a /7,8,9,10,11/ 
       
       data b(1,:) /1,1,1/ 
       data b(2,:)/2,2,2/ 
       data b(3,:)/3,3,3/ 
       data (c(i),i = 1,10,2) /4,5,6,7,8/ 
       data (c(i),i = 2,10,2)/5*2/
       
       Print *, 'The A array:'
       do j = 1, 5                
    
      print*, a(j)           
    end do Print *, 'The B array:' do i = lbound(b,1), ubound(b,1)
      write(*,*) (b(i,j), j = lbound(b,2), ubound(b,2))
    end do Print *, 'The C array:' do j = 1, 10
      print*, c(j)           
    end do end program dataStatement

    When the above code is compiled and executed, it produces the following result −

     The A array:
    
           7
           8
           9
          10
          11
    The B array:
           1           1           1
           2           2           2
           3           3           3
    The C array:
           4
           2
           5
           2
           6
           2
           7
           2
           8
           2

    Use of Where Statement

    The where statement allows you to use some elements of an array in an expression, depending on the outcome of some logical condition. It allows the execution of the expression, on an element, if the given condition is true.

    Example

    The following example demonstrates the concept −

    program whereStatement
    implicit none
    
       integer :: a(3,5), i , j
       
       do i = 1,3
    
      do j = 1, 5                
         a(i,j) = j-i          
      end do 
    end do Print *, 'The A array:' do i = lbound(a,1), ubound(a,1)
      write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
    end do where( a<0 )
      a = 1 
    elsewhere
      a = 5
    end where Print *, 'The A array:' do i = lbound(a,1), ubound(a,1)
      write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
    end do end program whereStatement

    When the above code is compiled and executed, it produces the following result −

     The A array:
    
           0           1           2           3           4
          -1           0           1           2           3
          -2          -1           0           1           2
    The A array:
           5           5           5           5           5
           1           5           5           5           5
           1           1           5           5           5
  • Arrays

    Arrays can store a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type.

    All arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element.

    Numbers(1)Numbers(2)Numbers(3)Numbers(4)

    Arrays can be one- dimensional (like vectors), two-dimensional (like matrices) and Fortran allows you to create up to 7-dimensional arrays.

    Declaring Arrays

    Arrays are declared with the dimension attribute.

    For example, to declare a one-dimensional array named number, of real numbers containing 5 elements, you write,

    real, dimension(5) :: numbers

    The individual elements of arrays are referenced by specifying their subscripts. The first element of an array has a subscript of one. The array numbers contains five real variables –numbers(1), numbers(2), numbers(3), numbers(4), and numbers(5).

    To create a 5 x 5 two-dimensional array of integers named matrix, you write −

    integer, dimension (5,5) :: matrix  

    You can also declare an array with some explicit lower bound, for example −

    real, dimension(2:6) :: numbers
    integer, dimension (-3:2,0:4) :: matrix  

    Assigning Values

    You can either assign values to individual members, like,

    numbers(1) = 2.0
    or, you can use a loop,
    do i  =1,5
       numbers(i) = i * 2.0
    end do

    One-dimensional array elements can be directly assigned values using a short hand symbol, called array constructor, like,

    numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
    

    please note that there are no spaces allowed between the brackets ‘( ‘and the back slash ‘/’

    Example

    The following example demonstrates the concepts discussed above.

    Live Demo

    program arrayProg
    
       real :: numbers(5) !one dimensional integer array
       integer :: matrix(3,3), i , j !two dimensional real array
       
       !assigning some values to the array numbers
       do i=1,5
    
      numbers(i) = i * 2.0
    end do !display the values do i = 1, 5
      Print *, numbers(i)
    end do !assigning some values to the array matrix do i=1,3
      do j = 1, 3
         matrix(i, j) = i+j
      end do
    end do !display the values do i=1,3
      do j = 1, 3
         Print *, matrix(i,j)
      end do
    end do !short hand assignment numbers = (/1.5, 3.2,4.5,0.9,7.2 /) !display the values do i = 1, 5
      Print *, numbers(i)
    end do end program arrayProg

    When the above code is compiled and executed, it produces the following result −

     2.00000000    
     4.00000000    
     6.00000000    
     8.00000000    
     10.0000000    
    
         2
         3
         4
         3
         4
         5
         4
         5
         6
    1.50000000 3.20000005 4.50000000 0.899999976 7.19999981

    Some Array Related Terms

    The following table gives some array related terms −

    TermMeaning
    RankIt is the number of dimensions an array has. For example, for the array named matrix, rank is 2, and for the array named numbers, rank is 1.
    ExtentIt is the number of elements along a dimension. For example, the array numbers has extent 5 and the array named matrix has extent 3 in both dimensions.
    ShapeThe shape of an array is a one-dimensional integer array, containing the number of elements (the extent) in each dimension. For example, for the array matrix, shape is (3, 3) and the array numbers it is (5).
    SizeIt is the number of elements an array contains. For the array matrix, it is 9, and for the array numbers, it is 5.

    Passing Arrays to Procedures

    You can pass an array to a procedure as an argument. The following example demonstrates the concept −

    program arrayToProcedure      
    implicit none      
    
       integer, dimension (5) :: myArray  
       integer :: i
       
       call fillArray (myArray)      
       call printArray(myArray)
       
    end program arrayToProcedure
    
    
    subroutine fillArray (a)      
    implicit none      
    
       integer, dimension (5), intent (out) :: a
       
       ! local variables     
       integer :: i     
       do i = 1, 5         
    
      a(i) = i      
    end do end subroutine fillArray subroutine printArray(a) integer, dimension (5) :: a integer::i do i = 1, 5
      Print *, a(i)
    end do end subroutine printArray

    When the above code is compiled and executed, it produces the following result −

    1
    2
    3
    4
    5
    

    In the above example, the subroutine fillArray and printArray can only be called with arrays with dimension 5. However, to write subroutines that can be used for arrays of any size, you can rewrite it using the following technique −

    Live Demo

    program arrayToProcedure      
    implicit  none    
    
       integer, dimension (10) :: myArray  
       integer :: i
       
       interface 
    
      subroutine fillArray (a)
         integer, dimension(:), intent (out) :: a 
         integer :: i         
      end subroutine fillArray      
      subroutine printArray (a)
         integer, dimension(:) :: a 
         integer :: i         
      end subroutine printArray   
    end interface call fillArray (myArray) call printArray(myArray) end program arrayToProcedure subroutine fillArray (a) implicit none integer,dimension (:), intent (out) :: a ! local variables integer :: i, arraySize arraySize = size(a) do i = 1, arraySize
      a(i) = i      
    end do end subroutine fillArray subroutine printArray(a) implicit none integer,dimension (:) :: a integer::i, arraySize arraySize = size(a) do i = 1, arraySize
     Print *, a(i)
    end do end subroutine printArray

    Please note that the program is using the size function to get the size of the array.

    When the above code is compiled and executed, it produces the following result −

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    

    Array Sections

    So far we have referred to the whole array, Fortran provides an easy way to refer several elements, or a section of an array, using a single statement.

    To access an array section, you need to provide the lower and the upper bound of the section, as well as a stride (increment), for all the dimensions. This notation is called a subscript triplet:

    array ([lower]:[upper][:stride], ...)

    When no lower and upper bounds are mentioned, it defaults to the extents you declared, and stride value defaults to 1.

    The following example demonstrates the concept −

    Live Demo

    program arraySubsection
    
       real, dimension(10) :: a, b
       integer:: i, asize, bsize
       
       a(1:7) = 5.0 ! a(1) to a(7) assigned 5.0
       a(8:) = 0.0  ! rest are 0.0 
       b(2:10:2) = 3.9
       b(1:9:2) = 2.5
       
       !display
       asize = size(a)
       bsize = size(b)
       
       do i = 1, asize
    
      Print *, a(i)
    end do do i = 1, bsize
      Print *, b(i)
    end do end program arraySubsection

    When the above code is compiled and executed, it produces the following result −

    5.00000000    
    5.00000000    
    5.00000000    
    5.00000000    
    5.00000000    
    5.00000000    
    5.00000000    
    0.00000000E+00
    0.00000000E+00
    0.00000000E+00
    2.50000000    
    3.90000010    
    2.50000000    
    3.90000010    
    2.50000000    
    3.90000010    
    2.50000000    
    3.90000010    
    2.50000000    
    3.90000010 
    

    Array Intrinsic Functions

    Fortran 90/95 provides several intrinsic procedures. They can be divided into 7 categories.

  • Strings

    The Fortran language can treat characters as single character or contiguous strings.

    A character string may be only one character in length, or it could even be of zero length. In Fortran, character constants are given between a pair of double or single quotes.

    The intrinsic data type character stores characters and strings. The length of the string can be specified by len specifier. If no length is specified, it is 1. You can refer individual characters within a string referring by position; the left most character is at position 1.

    String Declaration

    Declaring a string is same as other variables −

    type-specifier :: variable_name
    

    For example,

    Character(len = 20) :: firstname, surname
    you can assign a value like,
    character (len = 40) :: name  
    name = “Zara Ali”

    The following example demonstrates declaration and use of character data type −

    program hello
    implicit none
    
       character(len = 15) :: surname, firstname 
       character(len = 6) :: title 
       character(len = 25)::greetings
       
       title = 'Mr.' 
       firstname = 'Rowan' 
       surname = 'Atkinson'
       greetings = 'A big hello from Mr. Beans'
       
       print *, 'Here is', title, firstname, surname
       print *, greetings
       
    end program hello

    When you compile and execute the above program it produces the following result −

    Here isMr.   Rowan          Atkinson       
    A big hello from Mr. Bean
    

    String Concatenation

    The concatenation operator //, concatenates strings.

    The following example demonstrates this −

    program hello
    implicit none
    
       character(len = 15) :: surname, firstname 
       character(len = 6) :: title 
       character(len = 40):: name
       character(len = 25)::greetings
       
       title = 'Mr.' 
       firstname = 'Rowan' 
       surname = 'Atkinson'
       
       name = title//firstname//surname
       greetings = 'A big hello from Mr. Beans'
       
       print *, 'Here is', name
       print *, greetings
       
    end program hello

    When you compile and execute the above program it produces the following result −

    Here is Mr. Rowan Atkinson       
    A big hello from Mr. Bean
    

    Extracting Substrings

    In Fortran, you can extract a substring from a string by indexing the string, giving the start and the end index of the substring in a pair of brackets. This is called extent specifier.

    The following example shows how to extract the substring ‘world’ from the string ‘hello world’ −

    Live Demo

    program subString
    
       character(len = 11)::hello
       hello = "Hello World"
       print*, hello(7:11)
       
    end program subString 

    When you compile and execute the above program it produces the following result −

    World
    

    Example

    The following example uses the date_and_time function to give the date and time string. We use extent specifiers to extract the year, date, month, hour, minutes and second information separately.

    Live Demo

    program  datetime
    implicit none
    
       character(len = 8) :: dateinfo ! ccyymmdd
       character(len = 4) :: year, month*2, day*2
    
       character(len = 10) :: timeinfo ! hhmmss.sss
       character(len = 2)  :: hour, minute, second*6
    
       call  date_and_time(dateinfo, timeinfo)
    
       !  let’s break dateinfo into year, month and day.
       !  dateinfo has a form of ccyymmdd, where cc = century, yy = year
       !  mm = month and dd = day
    
       year  = dateinfo(1:4)
       month = dateinfo(5:6)
       day   = dateinfo(7:8)
    
       print*, 'Date String:', dateinfo
       print*, 'Year:', year
       print *,'Month:', month
       print *,'Day:', day
    
       !  let’s break timeinfo into hour, minute and second.
       !  timeinfo has a form of hhmmss.sss, where h = hour, m = minute
       !  and s = second
    
       hour   = timeinfo(1:2)
       minute = timeinfo(3:4)
       second = timeinfo(5:10)
    
       print*, 'Time String:', timeinfo
       print*, 'Hour:', hour
       print*, 'Minute:', minute
       print*, 'Second:', second   
       
    end program  datetime

    When you compile and execute the above program, it gives the detailed date and time information −

    Date String: 20140803
    Year: 2014
    Month: 08
    Day: 03
    Time String: 075835.466
    Hour: 07
    Minute: 58
    Second: 35.466
    

    Trimming Strings

    The trim function takes a string, and returns the input string after removing all trailing blanks.

    Example

    Live Demo

    program trimString
    implicit none
    
       character (len = *), parameter :: fname="Susanne", sname="Rizwan"
       character (len = 20) :: fullname 
       
       fullname = fname//" "//sname !concatenating the strings
       
       print*,fullname,", the beautiful dancer from the east!"
       print*,trim(fullname),", the beautiful dancer from the east!"
       
    end program trimString

    When you compile and execute the above program it produces the following result −

    Susanne Rizwan      , the beautiful dancer from the east!
     Susanne Rizwan, the beautiful dancer from the east!
    

    Left and Right Adjustment of Strings

    The function adjustl takes a string and returns it by removing the leading blanks and appending them as trailing blanks.

    The function adjustr takes a string and returns it by removing the trailing blanks and appending them as leading blanks.

    Example

    Live Demo

    program hello
    implicit none
    
       character(len = 15) :: surname, firstname 
       character(len = 6) :: title 
       character(len = 40):: name
       character(len = 25):: greetings
       
       title = 'Mr. ' 
       firstname = 'Rowan' 
       surname = 'Atkinson'
       greetings = 'A big hello from Mr. Beans'
       
       name = adjustl(title)//adjustl(firstname)//adjustl(surname)
       print *, 'Here is', name
       print *, greetings
       
       name = adjustr(title)//adjustr(firstname)//adjustr(surname)
       print *, 'Here is', name
       print *, greetings
       
       name = trim(title)//trim(firstname)//trim(surname)
       print *, 'Here is', name
       print *, greetings
       
    end program hello

    When you compile and execute the above program it produces the following result −

    Here is Mr. Rowan  Atkinson           
    A big hello from Mr. Bean
    Here is Mr. Rowan Atkinson    
    A big hello from Mr. Bean
    Here is Mr.RowanAtkinson                        
    A big hello from Mr. Bean
    

    Searching for a Substring in a String

    The index function takes two strings and checks if the second string is a substring of the first string. If the second argument is a substring of the first argument, then it returns an integer which is the starting index of the second string in the first string, else it returns zero.

    Example

    Live Demo

    program hello
    implicit none
    
       character(len=30) :: myString
       character(len=10) :: testString
       
       myString = 'This is a test'
       testString = 'test'
       
       if(index(myString, testString) == 0)then
    
      print *, 'test is not found'
    else
      print *, 'test is found at index: ', index(myString, testString)
    end if end program hello

    When you compile and execute the above program it produces the following result −

    test is found at index: 11
    
  • Numbers

    Numbers in Fortran are represented by three intrinsic data types −

    • Integer type
    • Real type
    • Complex type

    Integer Type

    The integer types can hold only integer values. The following example extracts the largest value that could be hold in a usual four byte integer −

    program testingInt
    implicit none
    
       integer :: largeval
       print *, huge(largeval)
       
    end program testingInt

    When you compile and execute the above program it produces the following result −

    2147483647
    

    Please note that the huge() function gives the largest number that can be held by the specific integer data type. You can also specify the number of bytes using the kind specifier. The following example demonstrates this −

    program testingInt
    implicit none
    
       !two byte integer
       integer(kind = 2) :: shortval
       
       !four byte integer
       integer(kind = 4) :: longval
       
       !eight byte integer
       integer(kind = 8) :: verylongval
       
       !sixteen byte integer
       integer(kind = 16) :: veryverylongval
       
       !default integer 
       integer :: defval
    
        
    print *, huge(shortval) print *, huge(longval) print *, huge(verylongval) print *, huge(veryverylongval) print *, huge(defval) end program testingInt

    When you compile and execute the above program it produces the following result −

    32767
    2147483647
    9223372036854775807
    170141183460469231731687303715884105727
    2147483647
    

    Real Type

    It stores the floating point numbers, such as 2.0, 3.1415, -100.876, etc.

    Traditionally there were two different real types : the default real type and double precision type.

    However, Fortran 90/95 provides more control over the precision of real and integer data types through the kind specifier, which we will study shortly.

    The following example shows the use of real data type −

    program division   
    implicit none
    
       ! Define real variables   
       real :: p, q, realRes 
       
       ! Define integer variables  
       integer :: i, j, intRes  
       
       ! Assigning  values   
       p = 2.0 
       q = 3.0    
       i = 2 
       j = 3  
       
       ! floating point division
       realRes = p/q  
       intRes = i/j
       
       print *, realRes
       print *, intRes
       
    end program division  

    When you compile and execute the above program it produces the following result −

    0.666666687    
    0
    

    Complex Type

    This is used for storing complex numbers. A complex number has two parts : the real part and the imaginary part. Two consecutive numeric storage units store these two parts.

    For example, the complex number (3.0, -5.0) is equal to 3.0 – 5.0i

    The generic function cmplx() creates a complex number. It produces a result who’s real and imaginary parts are single precision, irrespective of the type of the input arguments.

    program createComplex
    implicit none
    
       integer :: i = 10
       real :: x = 5.17
       print *, cmplx(i, x)
       
    end program createComplex

    When you compile and execute the above program it produces the following result −

    (10.0000000, 5.17000008)
    

    The following program demonstrates complex number arithmetic −

    program ComplexArithmatic
    implicit none
    
       complex, parameter :: i = (0, 1)   ! sqrt(-1)   
       complex :: x, y, z 
       
       x = (7, 8); 
       y = (5, -7)   
       write(*,*) i * x * y
       
       z = x + y
       print *, "z = x + y = ", z
       
       z = x - y
       print *, "z = x - y = ", z 
       
       z = x * y
       print *, "z = x * y = ", z 
       
       z = x / y
       print *, "z = x / y = ", z 
       
    end program ComplexArithmatic

    When you compile and execute the above program it produces the following result −

    (9.00000000, 91.0000000)
    z = x + y = (12.0000000, 1.00000000)
    z = x - y = (2.00000000, 15.0000000)
    z = x * y = (91.0000000, -9.00000000)
    z = x / y = (-0.283783793, 1.20270276)
    

    The Range, Precision and Size of Numbers

    The range on integer numbers, the precision and the size of floating point numbers depends on the number of bits allocated to the specific data type.

    The following table displays the number of bits and range for integers −

    Number of bitsMaximum valueReason
    649,223,372,036,854,774,807(2**63)–1
    322,147,483,647(2**31)–1

    The following table displays the number of bits, smallest and largest value, and the precision for real numbers.

    Number of bitsLargest valueSmallest valuePrecision
    640.8E+3080.5E–30815–18
    321.7E+380.3E–386-9

    The following examples demonstrate this −

    program rangePrecision
    implicit none
    
       real:: x, y, z
       x = 1.5e+40
       y = 3.73e+40
       z = x * y 
       print *, z
       
    end program rangePrecision

    When you compile and execute the above program it produces the following result −

    x = 1.5e+40
    
          1
    Error : Real constant overflows its kind at (1) main.f95:5.12: y = 3.73e+40
           1
    Error : Real constant overflows its kind at (1)

    Now let us use a smaller number −

    program rangePrecision
    implicit none
    
       real:: x, y, z
       x = 1.5e+20
       y = 3.73e+20
       z = x * y 
       print *, z
       
       z = x/y
       print *, z
       
    end program rangePrecision

    When you compile and execute the above program it produces the following result −

    Infinity
    0.402144760   
    

    Now let’s watch underflow −

    Live Demo

    program rangePrecision
    implicit none
    
       real:: x, y, z
       x = 1.5e-30
       y = 3.73e-60
       z = x * y 
       print *, z
       
       z = x/y
       print *, z
    
    end program rangePrecision

    When you compile and execute the above program it produces the following result −

    y = 3.73e-60
    
           1
    Warning : Real constant underflows its kind at (1) Executing the program.... $demo  0.00000000E+00 Infinity

    The Kind Specifier

    In scientific programming, one often needs to know the range and precision of data of the hardware platform on which the work is being done.

    The intrinsic function kind() allows you to query the details of the hardware’s data representations before running a program.

    program kindCheck
    implicit none
       
       integer :: i 
       real :: r 
       complex :: cp 
       print *,' Integer ', kind(i) 
       print *,' Real ', kind(r) 
       print *,' Complex ', kind(cp) 
       
    end program kindCheck

    When you compile and execute the above program it produces the following result −

    Integer 4
    Real 4
    Complex 4
    

    You can also check the kind of all data types −

    Live Demo

    program checkKind
    implicit none
    
       integer :: i 
       real :: r 
       character :: c 
       logical :: lg 
       complex :: cp 
       
       print *,' Integer ', kind(i) 
       print *,' Real ', kind(r) 
       print *,' Complex ', kind(cp)
       print *,' Character ', kind(c) 
       print *,' Logical ', kind(lg)
       
    end program checkKind

    When you compile and execute the above program it produces the following result −

    Integer 4
    Real 4
    Complex 4
    Character 1
    Logical 4
    
  • Loops

    There may be a situation, when you need to execute a block of code several number of times. In general, statements are executed sequentially : The first statement in a function is executed first, followed by the second, and so on.

    Programming languages provide various control structures that allow for more complicated execution paths.

    A loop statement allows us to execute a statement or group of statements multiple times and following is the general form of a loop statement in most of the programming languages −

    If Conditional

    Fortran provides the following types of loop constructs to handle looping requirements. Click the following links to check their detail.

    Sr.NoLoop Type & Description
    1do loopThis construct enables a statement, or a series of statements, to be carried out iteratively, while a given condition is true.
    2do while loopRepeats a statement or group of statements while a given condition is true. It tests the condition before executing the loop body.
    3nested loopsYou can use one or more loop construct inside any other loop construct.

    Loop Control Statements

    Loop control statements change execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed.

    Fortran supports the following control statements. Click the following links to check their detail.

    Sr.NoControl Statement & Description
    1exitIf the exit statement is executed, the loop is exited, and the execution of the program continues at the first executable statement after the end do statement.
    2cycleIf a cycle statement is executed, the program continues at the start of the next iteration.
    3stopIf you wish execution of your program to stop, you can insert a stop statement
  • Decisions

    Decision making structures require that the programmer specify one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed, if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.

    Following is the general form of a typical decision making structure found in most of the programming languages −

    Decision Making

    Fortran provides the following types of decision making constructs.

    Sr.NoStatement & Description
    1If… then constructAn if… then… end if statement consists of a logical expression followed by one or more statements.
    2If… then…else constructAn if… then statement can be followed by an optional else statement, which executes when the logical expression is false.
    3if…else if…else StatementAn if statement construct can have one or more optional else-if constructs. When the if condition fails, the immediately followed else-if is executed. When the else-if also fails, its successor else-if statement (if any) is executed, and so on.
    4nested if constructYou can use one if or else if statement inside another if or else if statement(s).
    5select case constructselect case statement allows a variable to be tested for equality against a list of values.
    6nested select case constructYou can use one select case statement inside another select case statement(s).
  • Constants

    The constants refer to the fixed values that the program cannot alter during its execution. These fixed values are also called literals.

    Constants can be of any of the basic data types like an integer constant, a floating constant, a character constant, a complex constant, or a string literal. There are only two logical constants : .true. and .false.

    The constants are treated just like regular variables, except that their values cannot be modified after their definition.

    Named Constants and Literals

    There are two types of constants −

    • Literal constants
    • Named constants

    A literal constant have a value, but no name.

    For example, following are the literal constants −

    TypeExample
    Integer constants0 1 -1 300 123456789
    Real constants0.0 1.0 -1.0 123.456 7.1E+10 -52.715E-30
    Complex constants(0.0, 0.0) (-123.456E+30, 987.654E-29)
    Logical constants.true. .false.
    Character constants“PQR” “a” “123’abc$%#@!”” a quote “” “‘PQR’ ‘a’ ‘123″abc$%#@!” an apostrophe ” ‘

    A named constant has a value as well as a name.

    Named constants should be declared at the beginning of a program or procedure, just like a variable type declaration, indicating its name and type. Named constants are declared with the parameter attribute. For example,

    real, parameter :: pi = 3.1415927
    

    Example

    The following program calculates the displacement due to vertical motion under gravity.

    program gravitationalDisp
    
    ! this program calculates vertical motion under gravity 
    implicit none  
    
       ! gravitational acceleration
       real, parameter :: g = 9.81   
       
       ! variable declaration
       real :: s ! displacement   
       real :: t ! time  
       real :: u ! initial speed  
       
       ! assigning values 
       t = 5.0   
       u = 50  
       
       ! displacement   
       s = u * t - g * (t**2) / 2  
       
       ! output 
       print *, "Time = ", t
       print *, 'Displacement = ',s  
       
    end program gravitationalDisp

    When the above code is compiled and executed, it produces the following result −

    Time = 5.00000000    
    Displacement = 127.374992    
    
  • Variables

    A variable is nothing but a name given to a storage area that our programs can manipulate. Each variable should have a specific type, which determines the size and layout of the variable’s memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.

    The name of a variable can be composed of letters, digits, and the underscore character. A name in Fortran must follow the following rules −

    • It cannot be longer than 31 characters.
    • It must be composed of alphanumeric characters (all the letters of the alphabet, and the digits 0 to 9) and underscores (_).
    • First character of a name must be a letter.
    • Names are case-insensitive.

    Based on the basic types explained in previous chapter, following are the variable types −

    Sr.NoType & Description
    1IntegerIt can hold only integer values.
    2RealIt stores the floating point numbers.
    3ComplexIt is used for storing complex numbers.
    4LogicalIt stores logical Boolean values.
    5CharacterIt stores characters or strings.

    Variable Declaration

    Variables are declared at the beginning of a program (or subprogram) in a type declaration statement.

    Syntax for variable declaration is as follows −

    type-specifier :: variable_name
    

    For example

    integer :: total  	
    real :: average 
    complex :: cx  
    logical :: done 
    character(len = 80) :: message ! a string of 80 characters

    Later you can assign values to these variables, like,

    total = 20000  
    average = 1666.67   
    done = .true.   
    message = “A big Hello from Tutorials Point” 
    cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
    

    You can also use the intrinsic function cmplx, to assign values to a complex variable −

    cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i 
    cx = cmplx (x, y) ! cx = x + yi
    

    Example

    The following example demonstrates variable declaration, assignment and display on screen −

    Live Demo

    program variableTesting
    implicit none
    
       ! declaring variables
       integer :: total      
       real :: average 
       complex :: cx  
       logical :: done 
       character(len=80) :: message ! a string of 80 characters
       
       !assigning values
       total = 20000  
       average = 1666.67   
       done = .true.   
       message = "A big Hello from Tutorials Point" 
       cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
    
       Print *, total
       Print *, average
       Print *, cx
       Print *, done
       Print *, message
       
    end program variableTesting

    When the above code is compiled and executed, it produces the following result −

    20000
    1666.67004    
    (3.00000000, 5.00000000 )
    T
    A big Hello from Tutorials Point         
    
  • Data Types

    Fortran provides five intrinsic data types, however, you can derive your own data types as well. The five intrinsic types are −

    • Integer type
    • Real type
    • Complex type
    • Logical type
    • Character type

    Integer Type

    The integer types can hold only integer values. The following example extracts the largest value that can be held in a usual four byte integer −

    program testingInt
    implicit none
    
       integer :: largeval
       print *, huge(largeval)
       
    end program testingInt

    When you compile and execute the above program it produces the following result −

    2147483647
    

    Note that the huge() function gives the largest number that can be held by the specific integer data type. You can also specify the number of bytes using the kind specifier. The following example demonstrates this −

    Live Demo

    program testingInt
    implicit none
    
       !two byte integer
       integer(kind = 2) :: shortval
       
       !four byte integer
       integer(kind = 4) :: longval
       
       !eight byte integer
       integer(kind = 8) :: verylongval
       
       !sixteen byte integer
       integer(kind = 16) :: veryverylongval
       
       !default integer 
       integer :: defval
    
        
    print *, huge(shortval) print *, huge(longval) print *, huge(verylongval) print *, huge(veryverylongval) print *, huge(defval) end program testingInt

    When you compile and execute the above program, it produces the following result −

    32767
    2147483647
    9223372036854775807
    170141183460469231731687303715884105727
    2147483647
    

    Real Type

    It stores the floating point numbers, such as 2.0, 3.1415, -100.876, etc.

    Traditionally there are two different real types, the default real type and double precision type.

    However, Fortran 90/95 provides more control over the precision of real and integer data types through the kind specifier, which we will study in the chapter on Numbers.

    The following example shows the use of real data type −

    Live Demo

    program division   
    implicit none  
    
       ! Define real variables   
       real :: p, q, realRes 
       
       ! Define integer variables  
       integer :: i, j, intRes  
       
       ! Assigning  values   
       p = 2.0 
       q = 3.0    
       i = 2 
       j = 3  
       
       ! floating point division
       realRes = p/q  
       intRes = i/j
       
       print *, realRes
       print *, intRes
       
    end program division  

    When you compile and execute the above program it produces the following result −

    0.666666687    
    0
    

    Complex Type

    This is used for storing complex numbers. A complex number has two parts, the real part and the imaginary part. Two consecutive numeric storage units store these two parts.

    For example, the complex number (3.0, -5.0) is equal to 3.0 – 5.0i

    We will discuss Complex types in more detail, in the Numbers chapter.

    Logical Type

    There are only two logical values: .true. and .false.

    Character Type

    The character type stores characters and strings. The length of the string can be specified by len specifier. If no length is specified, it is 1.

    For example,

    character (len = 40) :: name  
    name = “Zara Ali”

    The expression, name(1:4) would give the substring “Zara”.

    Implicit Typing

    Older versions of Fortran allowed a feature called implicit typing, i.e., you do not have to declare the variables before use. If a variable is not declared, then the first letter of its name will determine its type.

    Variable names starting with i, j, k, l, m, or n, are considered to be for integer variable and others are real variables. However, you must declare all the variables as it is good programming practice. For that you start your program with the statement −

    implicit none
    

    This statement turns off implicit typing.

  • Basic Syntax

    A Fortran program is made of a collection of program units like a main program, modules, and external subprograms or procedures.

    Each program contains one main program and may or may not contain other program units. The syntax of the main program is as follows −

    program program_name
    implicit none      
    
    ! type declaration statements      
    ! executable statements  
    
    end program program_name

    A Simple Program in Fortran

    Let’s write a program that adds two numbers and prints the result −

    program addNumbers
    
    ! This simple program adds two numbers
       implicit none
    
    ! Type declarations
       real :: a, b, result
    
    ! Executable statements
       a = 12.0
       b = 15.0
       result = a + b
       print *, 'The total is ', result
    
    end program addNumbers

    When you compile and execute the above program, it produces the following result −

    The total is 27.0000000    
    

    Please note that −

    • All Fortran programs start with the keyword program and end with the keyword end program, followed by the name of the program.
    • The implicit none statement allows the compiler to check that all your variable types are declared properly. You must always use implicit none at the start of every program.
    • Comments in Fortran are started with the exclamation mark (!), as all characters after this (except in a character string) are ignored by the compiler.
    • The print * command displays data on the screen.
    • Indentation of code lines is a good practice for keeping a program readable.
    • Fortran allows both uppercase and lowercase letters. Fortran is case-insensitive, except for string literals.

    Basics

    The basic character set of Fortran contains −

    • the letters A … Z and a … z
    • the digits 0 … 9
    • the underscore (_) character
    • the special characters = : + blank – * / ( ) [ ] , . $ ‘ ! ” % & ; < > ?

    Tokens are made of characters in the basic character set. A token could be a keyword, an identifier, a constant, a string literal, or a symbol.

    Program statements are made of tokens.

    Identifier

    An identifier is a name used to identify a variable, procedure, or any other user-defined item. A name in Fortran must follow the following rules −

    • It cannot be longer than 31 characters.
    • It must be composed of alphanumeric characters (all the letters of the alphabet, and the digits 0 to 9) and underscores (_).
    • First character of a name must be a letter.
    • Names are case-insensitive

    Keywords

    Keywords are special words, reserved for the language. These reserved words cannot be used as identifiers or names.

    The following table, lists the Fortran keywords −

    The non-I/O keywords
    allocatableallocateassignassignmentblock data
    callcasecharactercommoncomplex
    containscontinuecycledatadeallocate
    defaultdodouble precisionelseelse if
    elsewhereend block dataend doend functionend if
    end interfaceend moduleend programend selectend subroutine
    end typeend whereentryequivalenceexit
    externalfunctiongo toifimplicit
    ininoutintegerintentinterface
    intrinsickindlenlogicalmodule
    namelistnullifyonlyoperatoroptional
    outparameterpausepointerprivate
    programpublicrealrecursiveresult
    returnsaveselect casestopsubroutine
    targetthentypetype()use
    WhereWhile
    The I/O related keywords
    backspacecloseendfileformatinquire
    openprintreadrewindWrite