Quote of the day

Java-based CS1 is the single greatest mistake in the history of computing curricula. Students should learn to love their own possibilities before they learn to loathe other people’s restrictions.

Ronald P. Loui
in “In Praise of Scripting: Real Programming Pragmatism”

Advertisements

Pointers in Fortran (Part 2) – arrays

Now what about pointers and arrays in Fortran? Well they can be dealt with in a similar fashion. Consider the following code:

integer, target :: r(10)
integer, pointer :: pr(:)
pr => r

This implies that any reference to pr is identical to a reference to r. But it is also possible to do this:

pr => r(3:8)

Here pr is an array with 6 elements with pr(1) the same as r(3). There is also a second way of allocating arrays, through use of the allocateallocation combination. Single dimension dynamic arrays can be specified in Fortran in the following manner:

integer, dimension(:), allocatable :: d

The colon specifies one-dimension, but not the size of the dimension, this is allocated later in the following manner:

integer :: dLen, i
write (*,*) "Number of elements in the array: "
read (*,*) dLen
allocate(d(dLen))

Now elements can be input directly into the array:

write (*,*) "Enter the elements: "
do i = 1,dLen
    read (*,*) d(i)
end do

Note that allocatable arrays are automatically deallocated when they go out of scope.

 

Pointers in Fortran (Part 1) – the basics

So you’re learning Fortran and wonder where the pointers are? (Really??)

Fortran doesn’t rely on the use of pointers as much as C-family languages do. Although explicit pointers are lacking in earlier versions of Fortran, Fortran 90 does allow them, however they are restricted to point only to variables declared with the target attribute. C needs pointer variables to pass arguments to functions. Fortran passes a function the address of a variable, C passes the value of the variable. In order to pass information back to the variable, C needs a pointer.

Extensions to F77 allowed most Fortran compilers to deal with pointers, however it was F90 that standardized their use. There are two concepts for variables in Fortran: the static variable and the dynamic pointer. Unlike other languages, Fortran requires that the variables to associate pointers to be explicitly defined. That requires the use of the target attribute. For example:

integer, target :: a, b

This specifies the variables a and b as being targets for pointers. Fail to do this and the compiler will baulk. It’s not possible to associate a pointer to any variable with the same type as it is in C – maybe to forestall the potential problems that come with it. Now pointers can be defined using the pointer attribute. For example:

integer, pointer :: pa, pb

The variables pa and pb are now designated pointers. Now a pointer can be associated with a target (using the operator =>) in the following manner:

a = 6
pa => a

This means that the pointer pa points to variable a, and has the value 6. Modifying pa will also change the value stored in a. Pointers can be associated with a new variable at any time, i.e. pa => b is valid. They can also be disassociated from a variable using the nullify() function. To see the effect of nullify(), consider the following code:

program pointers

    integer, target :: a, b
    integer, pointer :: pa, pb

    a = 6
    write(*,*) a
    pa => a
    nullify(pa)
    b = pa * 4
    write(*,*) b

end

Compiling and running this code causes the following output:

./a.out
6
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x1009d589e
#1 0x1009d5fd4
#2 0x7fff8a731949
#3 0x1009cae36
#4 0x1009caeda
Segmentation fault: 11

Which clearly indicates something went askew (like pa was null, and b = NULL * 4 didn’t work!). A better message than C would give anyways. Fortran also provides a function called associated(), which allows an inquiry to be made on a pointer – does it have a target (in general) or a specific target associated with it?