Writing Programs That Can Be Easily Modified [ HP FORTRAN 77/iX Programmer's Guide ] MPE/iX 5.0 Documentation
HP FORTRAN 77/iX Programmer's Guide
Writing Programs That Can Be Easily Modified
If a program will be moved from one system to another, it is unlikely
that the program will compile, link, load, and run correctly on the first
attempt. Therefore, an easily portable program should also be able to be
easily changed. This section describes some guidelines for writing
programs that can be easily modified.
One way to write a program that can be easily modified is to space and
indent statements. Without spacing and indenting, the program is hard to
read. For example, the following FORTRAN program segment does not indent
or space between logical blocks:
J1=0
DO I=1,30
J1=J1+1
IF(A(I,J1).EQ.0)THEN
DO J=1,30
IF(J.NE.I)THEN
A(I,J)=1
ELSE
A(I,J)=0
ENDIF
END DO
ELSE IF(A(I,J1).EQ.1)THEN
DO J=1,30
IF(J.NE.I)THEN
A(I,J)=0
ELSE
A(I,J)=1
ENDIF
END DO
ELSE
A(I,J1)=999
ENDIF
END DO
It is not obvious what happens in the section or code, nor is it easy to
see how the statements are nested. In contrast, the same program segment
that indents at each nesting level and double-spaces between each logical
section is shown below:
J1 = 0
DO I=1,30
J1 = J1 + 1
IF (A(I,J1) .EQ. 0) THEN
DO J=1,30
IF (J .NE. I) THEN
A(I,J) = 1
ELSE
A(I,J) = 0
ENDIF
END DO
ELSE IF (A(I,J1) .EQ. 1) THEN
DO J=1,30
IF (J .NE. I) THEN
A(I,J) = 0
ELSE
A(I,J) = 1
ENDIF
END DO
ELSE
A(I,J1) = 999
ENDIF
END DO
The nesting levels are now obvious. The logic of the program is also
easy to follow. Therefore, indenting and spacing makes a significant
contribution to the readability of a program.
However, the purpose of the program segment is not obvious. One way to
make a program's function clear is to use meaningful variable names. The
ANSI standard restricts variable names to six uppercase letters and
numbers per variable name; using this limit, meaningful names can
be constructed. HP FORTRAN 77 names can be any length (with a
system-specific limit on the number of significant characters) and can
contain any combination of upper and lowercase letters, digits, and the
underscore character. The variable must begin with a letter. The
following program segment uses meaningful variable names.
Column_index = 0
DO Row_index=1,30
Column_index = Column_index + 1
IF (Matrix(Row_index,Column_index) .EQ. 0) THEN
DO Col_count=1,30
IF (Col_count .NE. Row_index) THEN
Matrix(Row_index,Col_count) = 1
ELSE
Matrix(Row_index,Col_count) = 0
ENDIF
END DO
ELSE IF (Matrix(Row_index,Column_index) .EQ. 1) THEN
DO Col_count=1,30
IF (Col_count .NE. Row_index) THEN
Matrix(Row_index,Col_count) = 0
ELSE
Matrix(Row_index,Col_count = 1
ENDIF
END DO
ELSE
Matrix(Row_index, Column_index) = 999
ENDIF
END DO
A glance at the segment above shows that the program performs a matrix
transformation. Therefore, using meaningful symbolic names improves the
understanding of a program.
Even though the readability of the example has improved by good
programming practices, it is not obvious what kind of matrix
transformation is taking place. To provide detailed information, use
comments. A comment is identified by a C or * in column one. In
addition, by appending an exclamation point ( ! ) to the end of a
source or directive line, the remainder of the line is treated as a
comment. Adding comments to the example results in the following:
Column_index = 0
C Check each element along the principal diagonal.
DO Row_index=1,30
Column_index = Column_index + 1 !Avoids extra loop, retains clarity
IF (Matrix(Row_index,Column_index) .EQ. 0) THEN
C If the principal diagonal element is 0,
C set all other elements in that row to 1.
DO Col_count=1,30
IF (Col_count .NE. Row_index) THEN
Matrix(Row_index,Col_count) = 1
ELSE
Matrix(Row_index,Col_count) = 0
ENDIF
END DO
ELSE IF (Matrix(Row_index,column_index) .EQ. 1) THEN
C If the principal diagonal element is 1,
C set all other elements in that row to 0.
DO Col_count=1,30
IF (Col_count .NE. Row_index) THEN
Matrix(Row_index,Col_count) = 0
ELSE
Matrix(Row_index,Col_count) = 1
ENDIF
END DO
ELSE
Matrix(Row_index,Column_index) = 999 !Mark inconsistent row.
ENDIF
END DO
Now, with just a quick glance at the example, the program's function is
obvious. However, be careful not to use too many comments and do not
include comments that only repeat the actions of the code; these comments
will obscure a program's function. Therefore, use a few, effective
comments instead of many unhelpful comments.
A final method of making a program readable and easy to change is to use
named constants instead of numeric or string literals. This is done by
using the HP FORTRAN 77 PARAMETER statement; refer to the HP FORTRAN
77/iX Reference for details on the PARAMETER statement. By using named
constants, the literal is documented with a meaningful name. Also, if
the value needs to be changed, only the PARAMETER statement has to be
changed, not every occurrence of the literal.
Adding PARAMETER statements and named constants to the example results in
the following:
PARAMETER (Lower_bound = 1, Upper_bound = 30)
PARAMETER (Invalid_row = 999)
PARAMETER (Repl_val_a = 0, Repl_val_b = 1)
PARAMETER (Column_start = Lower_bound - 1)
.
.
.
Column_index = Column_start
C Check each element along the principal diagonal.
DO Row_index=Lower_bound,Upper_bound
Column_index = Column_index + 1 !Avoids extra loop, retains clarity
IF (Matrix(Row_index,Column_index) .EQ. Repl_val_a) THEN
C If the principal diagonal element is Repl_val_a,
C set all other elements in that row to Repl_val_b.
DO Col_count=Lower_bound,Upper_bound
IF (Col_count .NE. Row_index) THEN
Matrix(Row_index,Col_count) = Repl_val_b
ELSE
Matrix(Row_index,Col_count) = Repl_val_a
ENDIF
END DO
ELSE IF (Matrix(Row_index,Column_index) .EQ. Repl_val_b) THEN
C If the principal diagonal element is Repl_val_b,
C set all other elements in that row to Repl_val_a.
DO Col_count=Lower_bound,Upper_bound
IF (Col_count .NE. Row_index) THEN
Matrix(Row_index,Col_count) = Repl_val_a
ELSE
Matrix(Row_index,Col_count) = rep1_val_b
ENDIF
END DO
ELSE
Matrix(Row_index,Column_index) = Invalid_row !Mark inconsistent row
ENDIF
END DO
In summary, spacing and indenting statements make the program structure
clearly visible. Adding meaningful variable names give general details
about a program's function. When comments are effectively used,
important details become apparent. Using named constants improves
documentation in the code and provides an easy way of changing values.
If you apply the guidelines given above, your programs will be readable,
easier to modify, and will be portable.
MPE/iX 5.0 Documentation