- Observe the first statement, which is
implicit none
This statement enforces type checking. Otherwise
implicit types are assumed, i.e., undefined variables
whose names begin with i, j, k, l, m, and n are assumed
integers, whereas all the other undefined variables are assumed
real. We don't want that, because it can easily lead
to programming errors.
- The next step is to define a new derived Fortran
type, which we're going to call
node. A data of type
node will be a node in a linked list. In this
case our derived type node has 4 components, of
which 3 are reals and one is a pointer that will point
to the next occurrence, somewhere in the memory of the
computer system, of a data of this type - thus forming
a list of elements linked with pointers.
- Observe that the definition of type
node is
recursive - this is always the case with linked lists
and trees.
- We then define two pointers that will eventually point
to objects of type
node:
type(node), pointer :: list, first
We must always keep the address of the first element
of a linked list stored safely somewhere, because if
we lose that, the whole data set will become dereferenced,
i.e., lost.
- There is nothing new about the remaining definitions, so
we can proceed directly to the first executable statement.
- The program opens a data file, whose name, in this case,
is hardwired.
- Assuming that the file has been successfully
opened for reading (also observe the required
file status
'old': this means that the file must
already exist - it is possible to open a new file
for reading, although it is hard to tell what one can
read from such a file) we allocate the first object
of type node and set its pointer component to
point nowhere with the nullify statement:
allocate(list); nullify(list%next)
- At the same time we make
first point to the
same object:
first => list; count = 0
Observe the new symbol =>, which means that
first has been assigned an address of object
that is now referenced by list.
Once we have allocated list, list
is no longer a pointer. It is now an object, which
may become a target for another
pointer, in this case, first.
- In Fortran pointers once they have been allocated
they cease to be pointers and become normal data items
instead. So they're really polymorphic creatures, which
at various times are different things. Because an allocated
pointer is no longer a pointer, you cannot do a thing such
as:
first = list
Instead you have to do:
first => list
The meaning of this operation is
a pointer points to (
) an object
- Now we enter a loop. This is a non-terminated loop
that loops forever until something special happens
inside that gets us out of there.
- What happens inside is that we read lines of
input. Every line is supposed to have 3 floating point
numbers in it, which we read on
list%x, list%y, list%sigma
the three floating point number slots of the object that
is currently referred to by the name list.
- When the end of file is reached, the
end=100 condition
fires up and the program jumps to label 100. There is
no other portable way to process end of file condition
in Fortran.
- Once the record has been read we increment the counter
and allocate space for the next node of the list.
That object is now placed in
list%next so that
we can locate it by marching along the list.
At the same time we redirect the list pointer
itself so that now it points to list%next,
and within this newly created object we nullify the
pointer slot. We need to do that, so that when the list
ends we have some means of ascertaining that.
- Having read all the data from the file, we close it,
and, since now we finally know how much data we have,
we allocate arrays for it.
allocate(x(count)); allocate(y(count)); allocate(sigma(count));
- Next we redirect
list to point back at the
first object, and march along the list. This time
hitting a pointer that is no associated with
any object terminates the march. That's why we've been
always careful to nullify the pointer in a newly
allocated object.
- As we march through the list, we write the records
on standard output, and, at the same time copy the
data from the list to appropriate slots in the arrays
xi, yi, and
.
- The last loop simply writes the arrays on standard
output.
- Like in C and in C++ there is no garbage collection in Fortran.
If you dereference accidentally or on purpose the beginning
of the list, you'll lose access to the data, but
you will not be able to reclaim that space either.
To reclaim it, you must walk backwards through the list
deallocating every node. For that to work the
nodes should have a pair of pointers, pointing in both
directions of the list, for every node.