Part 4. Composite variables

(c) 2017 by Barton Paul Levenson



Arrays

In addition to single, so-called "scalar" variables, you can declare arrays, which hold several values of the same type. If your program needs to keep track of 100 names, for example, you can declare:


    character(40) :: student(100)


The starting place is 1, not 0 as in C, so this statement creates a variable called student with 100 places, from 1 to 100. If you wanted different boundaries, you could declare them explicitly:


    character(40) :: student(0:99)
    real(d)       :: longitude(-180:180)


You refer to a given element in the array with a number--a "subscript" or "index"--in parentheses:


    user(3) = 'Bill'
    y(1)    = y(2) + y(3)


You can give an array an initializer, just like you can with scalar variables. But in this case it needs to have delimiters on each end: (/ and /). Here's an example:


    character(7) :: planetName(8) = (/            &
    & 'Mercury', 'Venus  ', 'Earth  ', 'Mars   ', &
    & 'Jupiter', 'Saturn ', 'Uranus ', 'Neptune' /)


The ampersand ( & ) lets you continue a long line. You can have up to 29 continuation lines.

Fortran-90 and later versions are optimized to work with arrays. Let's say you have a long array of single-precision real numbers to initialize. In old versions of Fortran--or existing versions of almost any other language--you would have to do something like this:


    integer :: i

    . . .

    do i = 1, arraySize
        array(i) = 0.0
    end do


In modern Fortran, you can forget the i variable, and just write:


    array = 0.0


You can carry out whole operations this way, such as:


    array = array + 1.0


And you can even initialize arrays in parts (technically, "slices"):


    array( 1: 5) = -1.0
    array( 6:10) =  0.0
    array(11:15) =  1.0


Fortran also provides special functions just for working with arrays. Want to add up all the elements? Here's the syntax:


    total = sum(array)
    mean  = sum(array) / N


Types

Let's say you're simulating the evolution of a star. At each one of several points from the core to the surface, you want to know the total mass contained within, the pressure, the radius, the luminosity, and the temperature. You could declare five different arrays:


    real(d) :: starL(N)
    real(d) :: starM(N)
    real(d) :: starP(N)
    real(d) :: starR(N)
    real(d) :: starT(N)


But Fortran lets you declare new types of variables made up of the basic types. Here's how we would do a layer type variable for stars:


    type layerType
        real(d) :: L, M, P, R, T
    end type layerType


Then, further down, you could declare a variable of this type:


    type(layerType) :: layer(N)


To reach individual fields, you append them to the variable name with the percent sign ( % ). If you're used to Visual Basic or C, where the usual "field operator" is a period, this will seem strange for a while.


    layer(i)%M = layer(i - 1)%M + dM


Such structured variables can be passed as subroutine or function arguments. You can write type-valued functions which return typed variables. You can assign all the member values at once in "constructors." An example of that last would be:


    layer(N) = layer(3.842d26, 1.9985d30, 0d0, 6.96d8, 5.777d3)


And the individual fields don't all have to be the same type. Programming language texts will often show a type like this (in Pascal, a "record," in C a "struc," in Visual Basic, a "structure"):


    type employee
        character(40) :: name
        integer       :: age
        real          :: salary
    end type employee


Fortran types may not be as versatile as classes--although the Fortran 2003 and later standards do provide for classes, and all the features of object-oriented programming--but they can still be very useful.





Page created:05/05/2017
Last modified:  05/05/2017
Author:BPL