# Introduction to Arrays

### New Fortran:

Array Declaration, DIMENSION, FORMAT

An array is simply a way of associating a string of adjacent words (for now a word is 4 bytes) in memory with a single variable name to ease computation. Why bother? Arrays are natural places to store lists of things, like names and grades (Yes, I need more than 4 bytes for names, but we'll get to that later, with CHARACTER data types). In science and engineering arrays take on an even more important role. We are in the business of using computers to predict the behavior of various pieces of the real world. However, we can't represent the full detail of the real world within a computer model. Just as a television image is composed of an "array" of colored points (pixels) on the screen, the image of a physical system within the computer must be broken into arrays of data points. Each of these points represents the average behavior of the world over some small but finite volume of space and/or duration of time.

If I want to predict how a diving board will vibrate after someone jumps off, I might divide it into one centimeter long sections, and store the height (above ground level) of each section as an element of an array called "z". Since the diving board doesn't have a uniform width, I'll need another array "amass" to store the mass of each of the elements of volume. Based on my knowledge of material properties and physics, I can generate an array of vertical forces "f", acting on my finite lumps of the board. The elements of "f" combined which the laws motion, give me a way to approximate the new values of "z" some small time interval into the future. I recalculate forces, redo motion equations, and update "z" until I've followed the vibrations long enough to get bored. The arrays in this problem are one-dimensional. We will stick with this simple form for the time being.

Most interesting problems give rise to 2-Dimensional and 3-Dimensional arrays. One such example is the use of computers to predict weather, and climatic trends. I can divide the surface of the Earth, or just part of the Earth, like Pennsylvania, with a 2-Dimensional grid of lines. A 2-Dimensional array "temp" might be used to represent the average surface temperature within each of the grid boxes. This is like putting temperature values into an array of cells on a spreadsheet. The atmosphere would be divided into a 3-D grid, and 3-D arrays used to represent things like average temperature, pressure, relative humidity, and velocity components for all cells in the grid. A fairly complicated set of fluid flow equations can then be applied to predict how some initial set of atmospheric and surface conditions will evolve with the passage of time.

### Declaration of Arrays

How do I set up an array data structure within Fortran? It's just an extension to the data type statements. I follow my variable with an integer constant, or parameter contained in parentheses. For example to set up arrays "a", "b", and "c" with ten elements each I include a REAL statement

```      real a(10), b(10), c(10)
```
or I could use a parameter as follows:

```      integer isize
parameter (isize=10)
real a(isize), b(isize), c(isize)
```
The advantage of this use of parameter, is that if I later need 20 elements in all of my arrays, all I have to do is change one number in the program. I can do similar things to define INTEGER type arrays.

```      integer ia(10), ib(10), ic(10)
```
What we have done with the above array declarations is to make it possible to refer to array elements such as a(1), a(2), ... a(10). We could also refer to an element of the array by using an INTEGER type variable to represent the index between the parentheses. For example I could use "a(i)" within a Fortran expression as long as "i" has a value from 1 through 10 (or whatever number I set as the dimension of the array). If you don't want to be restricted to "1" as the smallest allowed value of the array index, you can be more explicit in the permitted index values by using an integer range expression. For example,

```      real  a(0:10), b(-3:10), c(5:12), d
```
says: array "a" has eleven elements running from "a(0)" through "a(10)"; array "b" has fourteen elements running from "b(-3)" through "b(10)"; and array "c" has eight elements running from "c(5)" through "c(12)". The variable "d" is, of course just a standard "scalar" variable, containing one value. With arrays defined we can use specific elements of the arrays just as other variables would be used Fortran expressions:

```      d = 3.3
a(1)=2.0+d*3.0
b(-1)= d**2+3.
c(7)=a(1)-b(-1)
```
etc. It is also possible to do more powerful operations within DO loops

```      do i=5,12
a(i-3)= a(1)+2.0
b(i-5)=b(i-6)+5.
c(i)=a(i-3)-b(i-3)
end do
```
Two major dangers exist in the use of arrays. If I had programed the above DO loop, but neglected to declare "a" as an array. The compiler would assume that "a" is a function and give a syntax error for the line beginning "a(i-3)". In other related instances where the array "a" is only used to the right of an equals sign, the compiler would not detect a syntax error. However, when all the program units are tacked together to make the final executable program, the linker would go looking for a function named "a" and, failing to do so, return a message about an unsatisfied external reference. Failure to declare the dimension of an array occurs most frequently when arrays are passed as arguments to subprograms.

It is worth noting that the language C does not suffer from this dual use of parentheses in functions and arrays. The index of an array element in C (or C++) is surrounded by square brackets "[", and "]".

The second danger in programming with arrays occurs in the use of variables for array indices. It is possible to assign values of the index that are out of bounds of the space allocated by the array declaration. The result is that values of other Fortran variables, or in extreme instances machine instructions, are overwritten with unpredictable results. Compile and execute the simple example clobber.f, to see such troubles in action. Look at the basic program to see the intent in assigning values to elements in three arrays, then look at the output to see the result of a bad choice of upper bound for the DO loop index.

Two other forms of array declarations are worth mentioning now. Fortran 90 introduces a variation of the type statement to declare arrays. The older simple form

```      real a(0:20), b(0:20), c(0:20)
```
can be written in Fortran 90 as

```      real, dimension (0:20):: a, b, c
```
This is not much use in this simple example, but saves space if I want to declare a large number of variables to be arrays with the same dimension.

An older array declaration is still used by some long time Fortran programmers who are in the habit of using default Fortran variable typing (no REAL or INTEGER statements). The DIMENSION statement has the form.

```      dimension a(0:20), b(0:20), c(0:20)
```
It has the advantage that you can declare both integer and real arrays in the same line:

```      dimension a(0:20), ii(30), jj(5:10)
```
I will introduce other ways of declaring arrays, in later discussions of COMMON statements and new Fortran 90 data structures.

You should remember that any of these forms for array declaration, like standard type statements, are non-executable. They must precede any executable statement within any program unit (main program, subroutine, or function). Learn to distinguish executable statements.

### FORMAT statement.

If you are going to print the contents of arrays, your life will be easier with some knowledge of the FORMAT statement as used in array1.f. We will learn more about these later, but for now I want to introduce 5 key features.

1. The "*" in your WRITE, or PRINT statement is replaced with an integer constant, label number, and the FORMAT statement is given that label number (all FORMATs have labels).
2. Within the parentheses of the FORMAT the layout of the printed line is specified by a mix of quoted strings for headings, data edit descriptors for the variables to be printed, and control edit descriptors to give special control of the line structure.
3. The three most common data (variable) edit descriptors begin with the letters "i" for integer, "f" for simple floating point decimal number, and "e" for exponential (or engineering) notation. These letters are immediately followed by numbers telling how many columns are devoted to display of the data (contents of the Fortran variable) in the print-out. For "f" and "e" descriptors, the column count is followed by a decimal point and then a number telling how many decimal digits to print to the right of the decimal. Study statements and resulting output in array1.f and array2.f, to help understand this concept.
4. One FORMAT can cause multiple lines of print by including a "/" control edit descriptor. Each time the forward slash occurs in a FORMAT (except within quoted strings), a new line is started on the printout.
5. If the original WRITE (or PRINT) statement wants to print more values (contains more Fortran variables in its list of things to print) than the number of data edit descriptors in the FORMAT statement, a new line is started when the end of the FORMAT description is reached. To control the format of remaining variables listed in the WRITE, the FORMAT wraps around to the last left parenthesis in the FORMAT(unless that parenthesis is preceded immediately by an integer repeat descriptor, telling how many times to repeat the use of the format information within the parentheses), and all contents of the FORMAT beyond that parenthesis are reused until all variables are printed, or another FORMAT wrap around is needed. If the last left parenthesis is preceded by a repeat descriptor, Fortran looks to see if this repeated segment is nested within another pair of parentheses (other than those required by the FORMAT statment). If such bounding bounding parentheses exist, the wrap-around goes to the left parenthesis of this pair.
6. When all requested variables are written, any remaining items in the FORMAT are ignored.
.

Always remember that it is the job of the WRITE or PRINT to decide what Fortran variables to print. It is the job of the FORMAT statement to descide how the output of these variables should look. You do not include the names of Fortran variables that you want output within the FORMAT.