A structure can be referred to as a whole, and its components can also be referenced, using the % sign (rather than the dot . of other languages). A structure may be read or written, and the effect is the same as if its components were listed in order in the data list.
For example, a city can be described by its name, population, latitude, longitude and elevation:
TYPE :: City character(20) :: Name integer :: Population real :: Latitude, Longitude !! degrees north & west integer :: Elevation !! in meters END TYPE CityNow variables of the new type may be declared, and assigned values using a structure constructor:
TYPE(City) :: Lennox, & Hatley = City("Hatley Village",674, 45.2, 72.9, 300)Individual components of a structure can be referenced using a %
Lennox%Name = "Lennoxville" print *, Hatley%Population, " inhabitants"
Pointer variables are initially disassociated, and may become associated with values through pointer assignment => or an ALLOCATE statement. Pointers can be reassigned, breaking any previous association, or disassociated by NULLIFY. For example:
REAL, TARGET :: Pi = 3.14159 REAL, POINTER:: Cake, Ice_Cream Cake => Pi !! Cake is associated with target Pi ALLOCATE (Ice_Cream) !! Associate with unnamed storage Ice_Cream = Pi !! Copy value of Pi to the unnamed storage Cake = -98.6 !! Watch out! Pi changes also PRINT *, Pi, Ice_Cream !! prints -98.6 3.14159
A pointer's association status may also become "undefined." This is also known as the dangling pointer problem.
Cake => Ice_Cream !! Cake now associated with unnamed storage DEALLOCATE (Cake) !! Cake now disassociated, and storage released !! Ice_Cream is left UNDEFINED
Structures and pointers can be combined nicely to form dynamic, linked data structures such as linked lists and binary trees. One needs a structure including some data, and a pointer to another such structure, the next set of data in a list. In this list of animal chasing order, head is an extra pointer to the first item in the list, each node has a pointer Next. The Next pointer of the last node in a list is generally disassociated, here shown as a red box.
The structure is defined as follows:
TYPE :: Node Character(6) :: Animal TYPE(Node), POINTER :: Next END TYPE Node TYPE(Node), POINTER :: Head, TemP !! Initially empty listand the list can be created by ALLOCATE space, and filling it in, assigning links with pointer assignment, from right to left:
ALLOCATE (Head) Head%Animal = "Mouse" NULLIFY (Head%Next) !! no next item ALLOCATE (TemP) TemP%Animal = "Cat" TemP%Next => Head !! Link Cat to Mouse Head => TemP !! Make Cat the new head ALLOCATE (TemP) !! Can now reuse TemP TemP%Animal = "Dog" TemP%Next => Head Head => TemP !! Dog is now at Head NULLIFY (TemP) !! No longer need service of TemPWe can traverse the list, printing the entries, as follows:
TemP => Head DO WHILE (ASSOCIATED(TemP)) PRINT *, TemP%Animal TemP => TemP%Next END DOIt would also be possible, and perhaps more intuitive, to build the list from left to right:
print *,"Enter animals, one per line, blank line when done" ALLOCATE (Head) TemP => Head READ '(A)', TemP%Animal DO WHILE (TemP%Animal /= ' ') !!until blank line entered ALLOCATE (TemP%Next) !!create new node and link to it TemP => TemP%Next !! work with new node READ '(A)', TemP%Animal END DO NULLIFY (Temp%Next) !! Final node points nowhereNow the animals are linked in the order they were entered. There is also a final node with blank for animal, and Next disassociated. This can be used as a sentinal value. It is awkward to remove it.
In the preceeding example, the only data in each node was a single word. It could just as well be any type or types of data, including another structure or array(s).
To top of this document
Back to Fortran page
Back to Lin Jensen's home page