Arguments to Subprograms [ HP FORTRAN 77/iX Programmer's Guide ] MPE/iX 5.0 Documentation
HP FORTRAN 77/iX Programmer's Guide
Arguments to Subprograms
Communication between the calling program and the referenced subprogam is
accomplished by passing values through an argument list. An argument
list consists of one or more items separated by commas and enclosed in
parentheses. In addition, values can be passed through common blocks to
and from subprograms.
The calling program unit passes actual arguments to a subprogram. Dummy
arguments "refer" to the same locations as actual arguments; therefore,
arguments are passed by reference.
Actual arguments can be variables, array names, array elements, character
substrings, subprogram names, record names, record field names,
constants, expressions, and alternate return specifiers. Dummy arguments
can be variables, array names, and record names.
Whenever a function or subroutine is called, an association occurs
between each actual argument and its corresponding dummy argument. The
first actual argument is associated with the first dummy argument, the
second actual argument with the second dummy argument, and so on. The
number of actual arguments must be the same as the number of dummy
arguments (although certain intrinsic functions allow a variable number
of arguments). Also, actual arguments in a subroutine call or function
reference should agree in order and data type with the corresponding
dummy arguments.
To see how the dummy and actual arguments correspond, look at the
following example:
PROGRAM main
DIMENSION q(20), r(20)
EXTERNAL fcn ! Required for fcn to be an actual argument;
C otherwise will be treated as a variable.
.
.
.
CALL sub1(q, x, i, r(1), fcn)
.
.
.
END
SUBROUTINE sub1(arry, z, in1, tmp, f)
DIMENSION arry(20)
.
.
.
r = f(in1, tmp)
END
The arguments correspond to each other as follows: q is an array name,
so the dummy parameter arry must be dimensioned in the subprogram. x is
a real variable; the dummy parameter (z) in the second position of the
subroutine argument list must also be a real variable. i corresponds to
in1. r(1) is an element of array r and can correspond to a single
variable name (tmp) (not dimensioned) or an array (dimensioned) in the
dummy argument list. fcn is a function name; therefore, f must be used
in the context of a function in the subprogram.
A subprogram uses the actual arguments passed from the calling program to
replace the dummy arguments and perform the computation. For example,
consider this program:
PROGRAM example
INTEGER a, b
READ (5,*) a, b
WRITE(6,*) a, b
CALL switch(a,b)
WRITE(6,*) a, b
END
SUBROUTINE switch(x,y)
INTEGER x, y, temp
temp = x
x = y
y = temp
END
The calling program unit passes actual arguments a and b to the
subroutine switch. The subroutine uses variables x and y as dummy
arguments. Because the actual arguments are passed by reference, the
variables x and y refer to the storage locations of variables a and b.
The variables will then assume the current value of the actual arguments.
Changing the values of the dummy arguments passed by reference changes
the values of the actual arguments in the calling program unit.
Some examples of how statement functions define their arguments are shown
below.
The statement:
func(q, r, s) = q * r / s
is a statement function with simple variables.
The function description:
FUNCTION next(z, i, j)
DOUBLE PRECISION i
DIMENSION j(10)
defines these arguments: z is a REAL variable; i is a REAL*8 variable; j
is a 10-element INTEGER array.
The subroutine description:
SUBROUTINE add(q, f, get)
q = get(f)
defines these arguments: q and f are real variables and get is a
function name. In the context in which get is used, get could either be
an array or a function. But, because get was not declared as an array,
get is a function name.
All variable names are local to the program unit that defines them. In a
statement function, all actual variable names are local to that
statement. Similarly, dummy arguments are local to the subprogam unit or
statement function containing them. Therefore, the dummy arguments can
be the same as names appearing elsewhere in another program unit. No
element of a dummy argument list can occur in a common (except as a
common block name), EQUIVALENCE, or DATA statement.
If the actual argument is a constant, symbolic name of a constant,
function reference, expression involving operators, or expression
enclosed in parentheses, the associated dummy argument must not be
redefined within the subprogram.
Passing Constants
FORTRAN accepts a constant value as an argument. For example, a call to
a subroutine can look like this:
CALL sublib(books, num, 4.0)
.
.
.
SUBROUTINE sublib(titles, number, value)
The call to the subroutine sublib causes the subroutine to associate the
constant 4.0 with the third dummy argument, value.
Because a constant cannot be changed in value, the dummy argument in the
subprogram that corresponds to the actual constant should not be
redefined in the subprogram.
Passing Expressions
You can use expressions as actual arguments; an actual argument can be
any legal expression whose result is a value of the same data type as the
dummy arguments.
For example, consider these statements:
CALL baseball(team + 5.0, player1, player2,
* SQRT(3.0 - num), win, loss)
SUBROUTINE baseball(home, member1, member2,
* value, wscore, lscore)
When the call to the subroutine baseball occurs, FORTRAN evaluates each
expression and associates the result with the corresponding entry in the
dummy argument list, as follows:
-------------------------------------------------------
| | |
| Dummy Argument | Corresponding Actual Argument |
| | |
-------------------------------------------------------
| | |
| home | result of (team + 5.0) |
| | |
-------------------------------------------------------
| | |
| member1 | player1 |
| | |
-------------------------------------------------------
| | |
| member2 | player2 |
| | |
-------------------------------------------------------
| | |
| value | result of SQRT(3.0 - num) |
| | |
-------------------------------------------------------
| | |
| wscore | win |
| | |
-------------------------------------------------------
| | |
| lscore | loss |
| | |
-------------------------------------------------------
You can pass character expressions and character expressions involving
concatentation of operands whose lengths are (*), indicating undefined
length. For example, the following program shows how to pass character
expressions:
PROGRAM main
CHARACTER*10 string1, string2, string3, string4
string1 = 'one'
string2 = 'two'
string3 = 'three'
string4 = 'four'
CALL sub(string1, string2, string3, string4)
END
SUBROUTINE sub(a, b, c, f)
CHARACTER*(*) a, b, d, e, f
CHARACTER*20 c
PARAMETER (d = 'string1', e = 'string2')
c = a // b
* Legal character expressions as actual arguments:
CALL check(c)
CALL check(d)
CALL check(d // e)
CALL check(f)
CALL check(a // b)
CALL check(a // d)
END
SUBROUTINE check(z)
CHARACTER *(*) z
print *, z
END
The output from this program is as follows:
one two
string1
string1string2
four
one two
one string1
When an actual argument is an expression, the dummy argument in the
subprogram unit that corresponds to the actual expression should not be
reassigned in the subprogram.
Passing Character Data
When character data is passed to a subprogram, both the dummy and actual
arguments must be a character data type. The length of the dummy
argument must be less than or equal to that of the actual argument. If
the length of the dummy argument is less than the length of the
corresponding actual argument, only the leftmost characters of the actual
argument, up to the length of the dummy argument, are associated with the
dummy argument. For example, if an actual character argument is a
variable assigned the value abcdefgh and the length of the dummy argument
is four, only the characters abcd are associated with the dummy argument.
Here is an example of a character argument:
FUNCTION size(string)
CHARACTER*10 string
If a dummy argument of type character is an array name, the length
restriction applies to the entire array and not to each array element.
The length of an individual dummy array element can be different from the
length of an actual array element or array element substring. For
example, a main program can have the statements:
FUNCTION main
CHARACTER a(10)*20 ! Length of 20 declared
CALL sub(a)
.
.
.
END
and the subroutine sub can have the following statements:
SUBROUTINE sub(b)
CHARACTER b(10)*10 ! Length of 10 declared
.
.
.
END
The length of the dummy array element b differs from that of the
corresponding actual array element a.
The dummy argument array must not extend beyond the end of the associated
actual argument array. For example, the program:
PROGRAM main
CHARACTER a(10)*10 ! 10 elements of length 10 declared
CALL sub(a)
.
.
.
END
SUBROUTINE sub(b)
CHARACTER b(20)*20 ! 20 elements of length 20 declared
.
.
.
END
could have unexpected results.
If an actual argument is a character substring, the length of the actual
argument is the length of the substring. If an actual argument is the
concatenation of two or more operands, the sum of the lengths of the
operands is the length of the actual argument.
The length of a dummy argument can be declared by an asterisk, as shown
below:
SUBROUTINE sub(char_dummy)
CHARACTER*(*) char_dummy
In this example, the dummy argument char_dummy assumes the length of the
associated actual argument for each reference of the subroutine. If the
actual argument is an array or array element name, the length assumed by
the dummy argument is that length.
Passing Arrays
Functions and subroutines can process entire arrays. Association between
an actual array argument and the corresponding dummy array argument
follows the same rules described for single-valued arguments. The array
name in a dummy argument list is defined as an array in a type or
DIMENSION statement within the subprogram, and a similar declaration
appears in the invoking program for the actual array name.
You should make sure that the declared array type is the same for both
array names. For instance, if a main program has the statements:
PROGRAM main
INTEGER*2 a(24)
.
.
.
CALL mysub(a)
.
.
.
END
the subroutine mysub must include a similar declaration, like this:
SUBROUTINE mysub(b)
INTEGER*2 b(24)
.
.
.
END
If the subroutine processes an array of character strings, the declared
lengths must also match.
Because each element of an array can be uniquely identified and used just
like a single-valued variable, an array element can be used as an
argument to a subprogram. For example, the statement:
CALL suba(int1, int2, 5.0, 9, array(3), array(5))
is a valid call to a subroutine subprogram.
Because only the name of an array appears in the dummy argument list of a
subprogram, an array must be declared in a type or DIMENSION statement.
The number and size of an actual argument array can differ from the
number and size in the corresponding dummy argument array. The size of
the dummy argument array cannot exceed the size of the actual argument
array. Because array bounds across separate compilation units are not
checked at run time, no warning is issued if the dummy array size exceeds
the actual array size. Altering these unreserved locations could yield
unpredictable results or run-time errors.
Adjustable Dimensions.
Normally, array bounds are specified by integer constants and are fixed
by the values of these constants. However, you can use adjustable arrays
in subprograms. Adjustable dimensions allow you to create a subprogram
that can accept varying sizes of actual array arguments. For adjustable
declarations, one or more of the array bounds is specified by an
expression involving integer variables or expressions, rather than by
integer constants.
For example, here is a subroutine with a fixed array declared:
SUBROUTINE sub1(array)
DIMENSION array(25)
The exact number of elements that array contains is 25 elements. An
array that can contain a variable number of elements is declared like
this:
SUBROUTINE sub2(array, n)
DIMENSION array(n)
The value of n must be passed as an actual argument or must be in a
common block.
An example of an adjustable array declaration in a program is shown
below. The example declares an array iarr in the main program. The
array iarr has two dimensions of 10 elements each. A subroutine sb is
called to fill iarr with values. The variables i and j are set equal to
the array bounds and these variables are used as actual arguments to be
passed to the subroutine. The subroutine dummy arguments k and m assume
the values passed to them through i and j. These variables are used in
an INTEGER statement to establish the bounds for array ivar.
PROGRAM ardim
INTEGER iarr(10, 10)
i = 10
j = 10
CALL sb(iarr, i, j)
WRITE (6, '(1X, 10I3)') iarr
END
SUBROUTINE sb(ivar, k, m)
INTEGER ivar(k, m)
DO nr = 1, k
DO nc = 1, m
ivar(nr, nc) = nr * nc
END DO
END DO
RETURN
END
The following output is produced by the program:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90100
Assumed-Size Arrays.
The assumed-size array is another form of adjustable dimensions in
subprograms. For assumed-size arrays, the subscript of the last
dimension of the array is specified by an asterisk. Because the last
bound of the dimension is not passed as an argument, the bound can take
any value. The results are unpredictable when the dummy array is
referenced and the last dimension index expression exceeds the size of
the actual argument.
The following example demonstrates the use of assumed-size arrays. The
last subscript of the array arry can take any value from 0 to 6.
PROGRAM main
DIMENSION a(10, 10)
CALL sub1(a)
.
.
.
END
SUBROUTINE sub1(z)
DIMENSION z(10, *)
INTEGER num(5, 10, 0:6)
j = 5
i = func1(num, j)
.
.
.
END
FUNCTION func1(arry, k)
INTEGER arry(k, 10, 0:*)
.
.
.
END
A variable that dimensions a dummy argument in a bounds expression within
a type or DIMENSION statement in a subprogram can appear either in a
common block or as a dummy argument, but not both.
Adjustable and assumed-sized array declarations cannot be used in COMMON
statements, in main programs, or in BLOCK DATA subprograms.
You can pass the names of functions and subroutines as arguments to other
subprograms. All subprogram names used as actual arguments must be
listed in an EXTERNAL statement in the calling program.
Any intrinsic function name that is an actual argument must appear in an
INTRINSIC statement in the calling program. For example, the statement:
INTRINSIC sqrt, cos
specifies that the program intends to invoke one or more subprograms for
which sqrt and cos are to be actual arguments used in functions. If the
INTRINSIC statement is not included, sqrt and cos are assumed to be
variables.
An intrinsic function name can appear in an EXTERNAL statement to allow
the function name to be used as an actual argument. For example, the
statement:
EXTERNAL sin, tan
specifies that the user-written subprograms sin and tan will be used as
arguments. As a result, the intrinsic functions SIN and TAN cannot be
used in that program or subprogram.
If the subprogram name is not listed in an EXTERNAL or INTRINSIC
statement, the FORTRAN compiler treats the subprogram name as a simple
variable.
MPE/iX 5.0 Documentation