HP 3000 Manuals

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