Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP Fortran 90 Programmer's Reference: HP Fortran 90 Programmer's Reference > Chapter 5 Expressions and assignment

Assignment

» 

Technical documentation

Complete book in PDF
» Feedback
Content starts here

 » Table of Contents

 » Glossary

An assignment operation defines a variable by giving it a value. In HP Fortran 90, there are four types of assignment:

  • Intrinsic assignment (also known as the assignment statement)

  • Pointer assignment

  • Masked-array assignment (also known as the WHERE construct)

  • Defined assignment

The following sections describe the first three assignment types. The last—defined assignment—is defined by the programmer, using the INTERFACE statement. For information about defined assignment, see “Defined assignment”.

Assignment statement

An assignment statement gives the value of an expression to a variable. It has the following syntax:

variable = expression

variable may be any nonpointer variable or a pointer variable that is associated with a target. (If variable is a pointer, expression is assigned to the target.) The valid combinations of types for variable and expression are given in Table 5-5 “Conversion of variable=expression. The intrinsic functions that document the conversions are described in Chapter 11.

Table 5-5 Conversion of variable=expression

Variable type

Expression type

Conversion

Integer

Integer, real, or complex

INT(expression, KIND(variable))

Real

Integer, real, or complex

REAL(expression, KIND(variable))

Character

Character (same kind parameters)

CMPLX(expression, KIND(variable))

Logical

Logical

Truncate expression if its length is greater than that of variable; otherwise, pad value assigned to variable, with blanks.

Logical

Logical

LOGICAL(expression, KIND(variable))

Derived type

Same derived type

None

 

As described in “Bitwise operators”, HP Fortran 90 allows integer and logical operands to be used interchangeably. HP Fortran 90 also allows logical expressions to be assigned to integer variables and integer expressions to logical variables. As shown in Table 5-5 “Conversion of variable=expression, a logical expression may also be assigned to real or complex variables, and similarly, a real or complex expression may be assigned to a logical variable.

If variable is a scalar, expression must be scalar. If variable is an array or an array section, expression must be either an array-valued expression of the same shape or a scalar. If variable is an array or an array section, and expression is a scalar, the value of expression is assigned to all elements of variable. If variable and expression are both arrays, the assignment is carried out element by element with no implied ordering.

The expression is evaluated completely before the assignment is started. For example, the following code segment:

CHARACTER (LEN=4):: c
c(1:4) = "abcd"
c(2:4) = c(1:3)

sets c(2:4) to "abc", not to "aaa", which might result from a left-to-right character-by-character assignment.

The following examples illustrate assignments of different data types:

! declarations of the variables used in the assignment statements
! to follow
integer icnt
type circle
real radius
real xreal y
end type
type (circle) circle1, circle2
real area, pi
logical boolx, booly, pixel(10,10)
integer a(10,5)
integer, dimension (10,10):: matrix1, matrix2
character*3 initials
character*10 surname
character*20 name

icnt = icnt + 1 ! integer assignment

circle1 = circle2 ! derived-type assignment

area = pi * circle%radius**2 ! real assignment

pixel(x,y) = boolx .AND. booly ! assigns a logical expression to
! an element of the logical
! array pixel

a(:,1:2) = 0 ! first two columns of a are set to zero

maxtrix1 = maxtrix2 ! each element of maxtrix2 is assigned to
! the corresponding element of maxtrix1

name = initials // surname ! character assignment using the
! concatenation operator

Pointer assignment

Pointer assignment establishes an association between a pointer and a target. Once the association is established, if the pointer is referenced on the left-hand side of an assignment statement, it is the target to which the assignment is made. And if the pointer is referenced in an expression, the target is taken as the operand in the expression.

The syntax of a pointer assignment is:

pointer-object =>
target-expression
pointer-object

is a variable with the POINTER attribute.

target-expression

is one of the following:

  • A variable with the TARGET or POINTER attribute

  • A function reference or defined operation that returns a pointer result

The type, kind, and rank of pointer-object and target-expression must be the same. If target-expression is an array, it cannot be an assumed-size array or an array section with a vector subscript. For information about assumed-size arrays, see “Assumed-size arrays”. For information about array sections with vector subscripts, see “Vector subscripts”.

If target-expression is a pointer already associated with a target, then pointer-object becomes associated with the target of target-expression. If target-expression is a pointer that is disassociated or undefined, then pointer-object inherits the disassociated or undefined status of target-expression. For information about pointer status, see “Pointer association status”.

The following example, ptr_assign.f90, illustrates association of scalar and array pointers with scalar and array targets:

Example 5-1 ptr_assign.f90

PROGRAM main
INTEGER, POINTER :: p1, p2, p3(:) ! declare three pointers, p3
! is a deferred-shape array
INTEGER, TARGET :: t1 = 99, t2(5) = (/ 1, 2, 3, 4, 5 /)

! p1, p2 and p3 are currently undefined.
p1 => t1 ! p1 is associated with t1.
PRINT *, "contents of t1 referenced through p1:", p1

p2 => p1 ! p2 is associated with t1.
! p1 remains associated with t1.
PRINT *, "contents of t1 referenced through p1 through p2:", p2

p1 => t2(1) ! p1 is associated with t2(1).
! p2 remains associated with t1. PRINT *, "contents of t2(1) referenced through p1:", p1

p3 => t2 ! p3 is associated with t2.
PRINT *, &
"contents of t2 referenced through the array pointer p3:", p3

p1 => p3(2) ! p1 is associated with t2(2).
PRINT *, &
"contents of t2(2) referenced through p3 through p1:", p1

NULLIFY(p1) ! p1 is disassociated.
IF (.NOT. ASSOCIATED(p1)) PRINT *, "p1 is disassociated."

p2 => p1 ! Now p2 is also disassociated.
IF (.NOT. ASSOCIATED(p2)) PRINT *, &
"p2 is disassociated by pointer assignment."
END PROGRAM main

Here are the command lines to compile and execute the program, along with the output from a sample run:

$ f90 ptr_assign.f90
$ a.out
contents of t1 referenced through p1: 99
contents of t1 referenced through p1 through p2: 99
contents of t2(1) referenced through p1: 1
contents of t2 referenced through the array pointer p3: 1 2 3
4 5
contents of t2(2) referenced through p3 through p1: 2
p1 is disassociated.
p2 is disassociated by pointer assignment.

Masked array assignment

In a masked array assignment, a logical expression—called a mask— controls the selection of array elements for assignment. Masked array assignment is implemented by the WHERE statement and the WHERE construct. The syntax of the WHERE statement is:

WHERE (array-logical-expression)
array = array-expression

where array-logical-expression, array, and array-expression must all be conformable. The array-logical-expression (the mask) is evaluated for each element and the outcome (.TRUE. or .FALSE.) determines whether an assignment is made to the corresponding element of array.

The syntax of the WHERE construct is:

WHERE ( array-logical-expression )
array = array-expression
[array = array-expression] ...
[ELSEWHERE

array = array-expression
[array = expression] ... ]
END WHERE

The WHERE construct is similar to the WHERE statement, but more general in that several array = array-expression statements can be controlled by one array-logical-expression. In addition, an optional ELSEWHERE part of the construct assigns array elements whose corresponding array-logical-expression elements evaluate to .FALSE..

When a WHERE construct is executed, array-logical-expression is evaluated just once and therefore any subsequent assignment in a WHERE block (the block following the WHERE statement) or ELSEWHERE block to an entity of array-logical-expression has no effect on the masking. Thereafter, successive assignments in the WHERE block are evaluated in sequence as if they were specified in a WHERE statement, as follows:

WHERE (array-logical-expression)
array = array-expression

Each assignment in the ELSEWHERE is executed as if it were:

WHERE (.NOT.array-logical-expression)
array = array-expression

For example, the following WHERE construct:

WHERE (a > b)
a = b
b = 0
ELSEWHERE
b = a
a = 0
END WHERE

is evaluated as if it was specified as:

mask = a > b
WHERE (mask) a = b
WHERE (mask) b = 0
WHERE (.NOT.mask) b = a
WHERE (.NOT.mask) a = 0

Only assignment statements may appear in a WHERE block or an ELSEWHERE block. Within a WHERE construct, only the WHERE statement may be the target of a branch.

The form of a WHERE construct is similar to that of an IF construct, but with this important difference: no more than one block of an IF construct may be executed, but in a WHERE construct at least one (and possibly both) of the WHERE and ELSEWHERE blocks will be executed. In a WHERE construct, this difference has the effect that results in a WHERE block may feed into, and hence affect, variables in the ELSEWHERE block. Notice, however, that results generated in an ELSEWHERE block cannot feed back into variables in the WHERE block.

The following example score2grade.f90 illustrates the use of a masked assignment to find the letter-grade equivalent for each test score in the array test_score. To do the same operation without the benefit of masked array assignment would require a DO loop iterating over the array either in an IF-ELSE-IF construct or in a CASE construct, testing and assigning to each element at a time.

Example 5-2 score2grade.f90

PROGRAM main
! illustrates the use of the WHERE statement in masked array
! assignment
!
! use an array constructor to initialize the array that holds
! the numerical scores
INTEGER, DIMENSION(10) :: test_score = &
(/75,87,99,63,75,51,79,85,93,80/)
! array to hold the equivalent letter grades (A, B, C, etc.)
CHARACTER, DIMENSION(10) :: letter_grade
! because the array arguments are declared in the procedure
! as assumed-shape arrays, the procedure's interface must
! be explicit
!
INTERFACE
SUBROUTINE convert(num, letter)
INTEGER :: num(:)
CHARACTER :: letter(:)
END SUBROUTINE convert
END INTERFACE

PRINT *, "Numerical score:", test_score
CALL convert(test_score, letter_grade)
PRINT "(A,10A3)", " Letter grade: ", letter_grade
END PROGRAM main

SUBROUTINE convert(num, letter)
! declare the dummy arguments as assumed-shape arrays
INTEGER :: num(:)
CHARACTER :: letter(:)

! use the WHERE statements to figure the letter grade
! equivalents
WHERE (num >= 90) letter = "A"
WHERE (num >= 80 .AND. num < 90) letter = "B"
WHERE (num >= 70 .AND. num < 80) letter = "C"
WHERE (num >= 60 .AND. num < 70) letter = "D"
WHERE (num < 60) letter = "F"
END SUBROUTINE convert

Here are the command lines to compile and execute the program, along with the output from a sample run:

$ f90 score2grade.f90
$ a.out
Numerical score: 75 87 99 63 75 51 79 85 93 80
Letter grade: C B A D C F C B A B

The next example is a subroutine that uses the WHERE construct to replace each positive element of array a by its square root. The remaining elements calculate the complex square roots of their values, which are then stored in the corresponding elements of the complex array ca. In the ELSEWHERE part of the construct, the assignment to array a should not appear before the assignment to array ca; otherwise, all of ca will be set to zero.

SUBROUTINE find_sqrt(a, ca)
REAL :: a(:)
COMPLEX :: ca(:)

WHERE (a > 0.0)
ca = CMPLX(0.0)
a = SQRT(a)
ELSEWHERE
ca = SQRT(CMPLX(a))
a = 0.0
END WHERE
END SUBROUTINE find_sqrt
Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© Hewlett-Packard Development Company, L.P.