ICS101: COMPUTER PROGRAMMING USING FORTRAN

 

1.       INTRODUCTION (Overview of Computer Hardware & Software)

 

1.1     GOAL OF THE COURSE:

          The goal of this course is to teach students the use of computers as tools for solving engineering and scientific problems.  In this modern world of ours, computer has become a general-purpose tool used in all most all aspects of human endeavor.  Computers are used in offices to manage records, in banks to manage and control financial transactions.  In homes for playing games, etc. This course however, is particularly concern with teaching the use of computer as a tool to scientist and engineers in solving their scientific and engineering problems. 

 

1.2     COMPONENTS OF A COMPUTER

          Computers vary in size and computational capacity.  Various names have been used to classify the different types of computers.  You hear categories like mainframes, minicomputers, microcomputers, notebook, etc.    

These variations are mainly in terms of size, memory capacity, and speed.  However, the main structure of all computers is basically the same.  They all consist of hardware and software components.  Also, they all perform three basic functions, namely: receiving input, processing the input and producing output.

 

Hardware component:  The hardware component of a computer consists of those components that we can see and touch.  Such components are normally grouped into four as shown by the following diagram which also shows how the four parts are interrelated:

 

 

 

 

 

 

 

 


Input devices:  These are those devices that are used to send data to the computer, e.g: Keyboard, Mouse, etc.

Output Devices:  These are the devices that are used to receive input from the computer, e.g: screen, printer, etc.

Memory:  This is the device that is used to store data and programs that manipulate the data.

CPU:  This is the brain of the computer where processing and control takes place.

 

Software Components:  Even though the hardware components described above would seen to describe everything about computer as far as a lay man is concerned, they are in fact useless without the software components.  These consist of the programs (series of instructions) that instruct the hardware on how to operate to solve a given problem.  Software is usually categorized into two:  System software and Application Software.

 

The System software includes those programs that are designed to directly manage and control the hardware.  Examples of System software are the various operating systems such as Windows 98, Windows NT, UNIX, MSDOS, etc.  Application Software consists of programs that are designed to solve user-related problems.  Examples of these are, Microsoft Word, Excel, Computer Games and all the Fortran Programs that we are going to write in this course.  

 

To use a tool, one must first understand how to use it.  This explain why we need to know how to program.

 

1.3     PROGRAMMING LANGUAGES

          To communicate between any two people, they must either both understand a common language or their must be a third person who understand the languages of the two people involved.  This is exactly the situation that exists between computer and a user.

 

All digital computers are designed to understand only one language called  machine language.  This language consists of only two symbols, namely 0 and 1.  Thus, words and sentences are constructed to consist of only these two symbols.  i.e. both data and program instructions must consist of only these symbols.

 

This therefore made the computer language very difficult to understand and use by users, as it is very easy to make mistakes when dealing with a sequence of zeros and ones.  It is also very difficult to interpret what a program written in this language is intended to do by anybody other than perhaps the original programmer.

 

Human beings (users) on the other hand, understand what are called Natural languages. E.g. Arabic, English, Urdu, etc.  These languages also do have their problems in that understanding them depends a lot on the intelligence of human beings.  For example, consider the English sentence, ‘I am coming’.  This could mean different things depending on the situation.  This is called the problem of ambiguity.  Computers being what they are (stupid) could not be able to cope with such languages.

 

To achieve a compromise, programming languages known as high-level languages are developed.  These are developed to be as close as possible to natural languages (English), but at the same time very specific to suit the nature of computers.

 

The first attempt to develop high-level language was Assembly language.  This consists of symbolic words called mnemonics (e.g.  MOVE, ADD, etc.).  However, Assembly language was still at a very low level as it was designed to program in the manner the computer actually operates at register level.   At a letter stage, other more higher programming languages were developed to allow programs to be written in terms of mathematical expressions, with little or no concern on how the computer will actually evaluate such expressions.  Some of these languages are: FORTRAN, Pascal, C, C++, JAVA, etc.  In this course we shall learn one of the simplest of them, FORTRAN.

 

We had earlier said that computers understand only the machine language.  So how would it understand a program written in a high-level language?  The answer is through a Compiler (in the case of assembly language this is called an Assembler).  A FORTRAN compiler for example, understands both the machine language and the FORTRAN language.  Thus, when we write our programs in FORTRAN (source program), we submit it to the compiler to produce a machine language version (object code).  This process is called compilation.  It is this object code that we then run on the computer.

1.4              PROGRAM CONSTRUCTION

Program construction is very much like any engineering construction.  Just like we have to design a building before we begin the actual construction, we have to plan and design our programs before we actually implement them on the computer.  The process involves four main steps, namely: Analysis, Design, Implementation and Testing.  The analysis involves a thorough understanding of the problem we are trying to solve.  The next step is designing a solution.  This could involve breaking down the problem into smaller sub-problems, a process called top-down design or step-wise refinement.  After we are satisfied with the designed solution, we then implement it by writing program(s) in a programming language such as FORTRAN.  Finally, we test and debug the problems to ensure that all errors are removed.

 

1.5              PROGRAM CONSTRUCTION TOOLS

To write and debug programs, we need two basic tools, namely an editor and a compiler.   An Editor is a program that allows the user to create and modify text files. This is what we use in typing in and editing our FORTRAN programs.  A Compiler in addition to translating our programs into machine language also helps us debug our programs by pointing out the errors that may exist.  The Compiler that we shall be using for this course is called FORTRAN Visual Workbench.  It has its own editor integrated within it.

 

1.6              FORMAT OF A FORTRAN PROGRAM.     

The Fortran Compiler requires that all program statements or lines have a specific structure.  It requires that program lines be within the first 73 columns of a file.  All characters outside this range are ignored.  The columns are used as follows:

·        Columns 1 to 5 inclusive are for statement label or number used to identify a specific line or statement.

·        Column 6 is used for continuation, which might be needed if the program statement is too long to fit in the 73 columns.  Any character, except zero can be placed in column 6 to indicate continuation of the previous line.

·        Column 7 to73 are used for actual FORTRAN statements.

·        A ‘*’ or the character ‘C’ in column 1 indicates that the line is a comment line.  Comments are used to explain the function of program code.  The Compiler ignores what is typed on a comment line.

 

In addition to this column structure, FORTRAN statements are structured in the following format.      Declarations

Program Statements

END

 

Declarations: involve definition of variables required in the program

Program Statements: are the FORTRAN statements that solves the program being considered

END:  This indicates the physical end of the program.

e.g:

1234567890123456789012345678901234567890123456789012345678901234567890123

     INTEGER K

     DO 10 K=1, 8

        PRINT*, ’HELLO  ’, K

10   CONTINUE

     END

2.         ARITHMETIC OPERATIONS

          The purpose of writing programs is usually to manipulate certain data.  In FORTRAN language, there are four types of data, namely: INTEGER, REAL, CHARACTER and LOGICAL.  These data types can be used in their literal form, in which case they are called constants, (e.g. 2, 5, 7.2, etc), or they can be associated with names, in which case they are called variables, (e.g. X, Y, COUNT, etc.).  First we take a look at constants.

 

2.1              CONSTANTS

Integer Constants:  These are whole numbers (numbers without decimal point).  E.g.  32,  0,  -6201,  1992, etc.

 

Real Constants:  These are numbers that have a decimal point.  E.g.  1.23,         -0.0007,  3257.263,       5.0,    8.,          94000000000000000.0

 

The last example can be written in scientific notation as 0.94 x 1017.  In FORTRAN, this is represented as 0.94E+17, with E representing “times 10 to the power of”.  Other examples are shown below:

Real Number

Decimal Notation

FORTRAN representation

6.3 x 10-5

0.000063

0.63E-04

-5.7 x 10-6

-0.0000057

-0.57E-05

5.7 x 106

5700000.0

0.57E+07

 

Logical Constants:  There are two logical constants, represented in FORTRAN as .TRUE. and .FALSE.

 

Character Constants (character strings):  These consist of a sequence of one or more characters enclosed between single quotes.  E.g.  ’HELLO’,   ’HOW ARE YOU’,

’I ’’VE GOT IT’.

Note that if a single quote needs to be included in the output, it written as two single quotes.

 

2.2              VARIABLES:

These are names introduced by the user (programmer) to represent certain data items.  Variables are introduced by defining (or declaring) them at the beginning of a FORTRAN program.  The definition takes the general form:

                   TYPE         list of variables

Where TYPE is the type of the variables (INTEGER, REAL, CHARACTER OR LOGICAL) and list of variables is a list of one or more names given by the programmer following the guidelines below:

·        A variable should start with alphabetic character (A,B,...,Z)

·        The length of a variable should not exceed 6 characters

·        A variable may contain digits (0, 1, …, 9)

·        A variable should not contain special character (!,#,?,”,etc.)

·        A variable may not contain blanks.

 

          E.g.    Valid Variables            Invalid Variables

                   TRY                               5TEST

                   NAME21                       A+B

                   X                                   MY  PAY

Integer Variables:  These can be defined in two ways, explicitly (recommended) and implicitly. 

 

The explicit definition takes the form:            INTEGER  list of integer variables.

 E.g.   INTEGER BOOKS, NUM, X

          INTEGER X

 

The Implicit definition does not require any special statement; we just use the variables in the FORTRAN statements.  The only requirement is that the name should begin with one of the following letters: I, J, K, L, M, N.

 

Note:  If we forget to explicitly declare our variables and they begin with one of the above letters, they are automatically assumed to be of type integer.

 

Real Variables:  These are also defined either explicitly, or implicitly.  The explicit definition takes the form:                   REAL list of real variables .

E.g.               REAL  RATE, PAY, A, B

 

Implicit definition only requires that the name begin with a letter other than I, J, K, L, M, N.

Any variable that is not explicitly defined and begins with a letter other than one of  I, J, K, L, M, N,  is automatically assumed to be of type real.

 

Logical Variables:  These can only be defined explicitly, in the form:

LOGICAL list of logical variables

E.g.           LOGICAL  TEST, FLAG, Q

 

Character Variables:  These can only be defined explicitly in the form:

                   CHARACTER  list of character variables and their length                   or

                   CHARACTER*n  list of character variables and their length

 

Each variable may be followed by *k, where k represents the length of the string the variable can hold.  If *k is not specified, the length is assumed to be n.  If n is not specified, the length is assumed to be 1.

E.g.             CHARACTER NAME*20               NEME is of length 20

                   CHARACTER*6  M, WS*3, IN2    M and IN2 are of length 6  and WS is 3

                   CHARACTER Z*8, TEST                Z is of length 8, TEST is of length 1

Note: It is generally agreed that implicit declaration is a bad programming habit so we shall avoid it in this course.  You can make the compiler to check for this by typing  $DECLARE at the beginning of your FORTRAN program, starting from the first column.

 

2.3              ARITHMETIC OPERATORS

There are five Arithmetic Operators in FORTRAN, namely:  Addition, Subtraction, Division, Multiplication and Exponentiation  (power) operator.   The table below shows the symbols used to represent these operators as well as the order of evaluation (precedence).

 

Operator

Math. Notation

FORTRAN symbol

FORTRAN Usage

Precedence

Exponentiation

Xy

**

X**Y

1

Multiplication

X x Y

*

X*Y

2

Division

X ¸ Y

/

X/Y

2

Addition

X + Y

+

X+Y

3

Subtraction

X - Y

-

X-Y

3

·        In any Arithmetic expression, parenthesis has the highest priority in evaluation, starting with the most inner parenthesis. 

·        The next in priority is the exponentiation operator.  If there are two or more consecutive exponentiation operators, evaluation is from right to left. E.g.  2**2**3 = 2**8 = 256.

·        Division and Multiplication have the same priority following the exponentiation operator

·        The next in priority are the Addition and Subtraction, which also have the same priority.  Operators with the same priority are evaluated from left to right, except the exponentiation operator as explained above.

 

The result of an arithmetic operation depends on the type of the operands.  Integer operands result in integer result and real operands give real result.

E.g.

50-23 = 27

50.0–23.0 = 27.00000

3**2 = 9

3.0**2.0 = 9.00000

5*7 =35

5.0*7.0 = 35.00000

8/2 = 4

8.0/2.0  = 4.0000

8/3 = 2 

8.0/3.0 = 2.66667

9/10 = 0

9.0/10.0 = 0.90000

 

If an expression contains both integer and Real operands, it is called mixed-mode and its result is real.  E.g.

                             50-23.0 = 27.00000

                             8.0/3 = 2.66667

Example1.  Evaluate the expression: 20-14/5*2**2**3

Solution:    20-14/5*2**2**3          = 20-14/5*2**8

                                                = 20-14/5*256

                                                = 20-2*256

                                                = 20-512

                                                = -492

Example 2:  Convert the expression to FORTRAN

Solution:    (A+B)**0.5/(a**2 – b**2)

 

2.4              ASSIGNMENT STATEMENT

This assigns a value to a variable.  Its general form is:      variable = expression

Where expression must be of the same type as the variable with one exception:  integer values can be assigned to real variables. 

Example1

.         X1=3.25     X1 is assigned the value 3.25

          Y1=7.0       Y1 is assigned the value 7.0

          X1=Y1       X1 is assigned the value of Y1

          X1=X1+1   X1 is incremented by 1

          X1=X1+Y1          X1 is incremented by the value of Y1.

          AVER=SUM/COUNT  AVER is assigned the result of dividing SUM by COUNT

 

Example 2: If the variable NAME is declared as :          CHARACTER NAME*8

What will be the value of name after the assignment:  NAMER=’ICS101 FORTRAN’

 

Solutions: ICS101 F

2.5              SIMPLE INPUT STATEMENTS

Another way of assigning a value to a variable is by reading the value from the terminal when the program is being executed, using the READ statement. There are two types of READ statements: formatted and unformatted.  Here we present the unformatted form. Its general form is:

          READ*, list of variables

On encountering a read statement, the computer will suspend the execution of the program and allow the user to type input values for each of the variables in the list.  The execution will continue on pressing the <Enter> key.

 

e.g.              INTEGER A, B

READ*, A, B

Text Box: 5  10

If the input is: then A is assigned 5 and B is assigned 10.

 

Note:  The following should be noted about READ statement.

·        Each read statement starts from a new line.

·        IF the input data is not enough in the current line, reading continues in the next line.

·        The data values can be separated by blanks or comma.

·        The data values must agree in types with the variable, except that integer values can be assigned to real variables but not the reverse.

·        Extra data on an input line is ignored.

 

2.6              SIMPLE OUTPUT STATEMENTS.

The PRINT statement is used to print the values of variables, expressions, or constants.  It also has formatted and unformatted forms.  Here we present the unformatted.  The unformatted form is:

          PRINT*, list of variables, expressions or constants

 

Exaple1:

          INTEGER K, L

          K=3

          L=20

          PRINT*, K,L                                            

          PRINT*, K+L

This produces the output:          3                 20

                                                23

Note: If a variable that has not been assigned any value is printed, the output appears as: ????

 

Example 2:  The following program reads three real numbers, prints them, computes their average and prints it.

 

C  READS 3 REAL NUMBERS, COMPUES AND PRINTS THEIR AVERAGE

      REAL NUM1,NUM2,NUM3,COUNT,AVER

      COUNT=3.0

      READ*, NUM1,NUM2,NUM3

      PRINT*, ’THE NUMBERS ARE ’,NUM1,NUM2,NUM3

      AVER=(NUM1+NUM2+NUM3)/COUNT

      PRINT*, ’THE AVERAGE IS ’,AVER

      END

Example3: The following program reads the length and breadth of a rectangle and then computes the Area and the Perimeter.

 

C  READS THE LENGTH AND BREADTH OF A RECTANGLE, THEN COMPUTES

C  AND PRINTS THE AREA AND THE PERIMETER

      REAL L,B,AREA,PERI

      READ*, L,B

      AREA=L*B

      PERI=2*(L+B)

      PRINT*, ’THE AREA IS ’,AREA

      PRINT*, ’THE PERIMETER IS ’,PERI

 

Example 4:  The following program reads the coordinates of two points (x1, y1) and (x2, y2) and finds the distance between the points, using the formula:

Solution:

 

*  COMPUTES AND PRINTS THE DISTANCE BETWEEN TWO GIVEN POINTS

      REAL X1, X2, Y1, Y2, D

      PRINT*, ’ENTER THE FIRST POINT’

      READ*, X1, Y1

      PRINT*, ’ENTER THE SECONT POINT’

      READ*, X2, Y2

      D=((X1-X2)**2+(Y1-Y2)**2)**0.5

      PRINT*, ’THE DISTANCE IS’,D


3.       LOGICAL OPERATIONS

In addition to the Arithmetical operators discussed in the last sections, we also have Logical and Relational operators.  This section discusses these two set of operators.  We also discuss how FORTRAN evaluates expressions that involve all the three operators.

 

3.1              LOGICAL OPERATORS

These are operators that operates on logical values to produce logical results.  There are three of them: .AND., .OR., and .NOT.

 

.AND. :  This is a binary operator that produces .TRUE. if and only if both its operands have .TRUE. value.  If any of the operands has a .FALSE. value, the result is .FALSE..

 

.OR. :  This is a binary operator that produces .FALSE. if and only if both it operands have a .FALSE. , otherwise, the result is .TRUE.

 

.NOT. :  This is a unary operator that produces the opposite of its operand.

 

The following table summarizes the result of the three logical operators.

 

P

Q

P .AND. Q

P .OR. Q

.NOT. P

.FALSE.

.FALSE.

.FALSE.

.FALSE.

.TRUE.

.FALSE.

.TRUE.

.FALSE.

.TRUE.

 

.TRUE.

.FALSE.

.FALSE.

.TRUE.

.FALSE.

.TRUE.

.TRUE.

.TRUE.

.TRUE.

 

 

The .NOT. operator has the highest priority of the three, followed by .AND., followed by .OR.

 

Example 1:  Evaluate the following logical expression:

          .FALSE. .OR. .NOT. .TRUE. .AND. .TRUE.

 

Solution:    = .FALSE. .OR. .FALSE. .AND. .TRUE.  (.NOT. has the highest priority)

                   = .FALSE. .OR. .FALSE.                          (followed by .AND.)

                   = .FALSE.                                                  (followed by .OR.)

 

Example 2:  Evaluate the following logical expression:

          .FALSE. .AND. .TRUE. .OR. .NOT. (.FALSE. .AND. .TRUE.)

 

Solution:    = .FALSE. .AND. .TRUE. .OR. .NOT. .FALSE.

                   = .FALSE. .AND. .TRUE. .OR. .TRUE.

                   = .FALSE. .OR. .TRUE.

                   = .TRUE.

 

Example 3:  Evaluate the following logical expression:

          .NOT. (.NOT. .FALSE.) .AND. .TRUE. .OR. .FALSE.

 

Solution:    = .NOT. .TRUE. .AND. .TRUE. .OR. .FALSE.

                   = .FALSE. .AND. .TRUE. .OR. .FALSE.

                   =..FALSE. .OR. .FALSE.       = .FALSE.

Example 4:  Assuming the declaration :  LOGICAL FLAG .  If the expression:

                    .NOT. FLAG .OR. .FALSE.

          is .TRUE., what is the value of FLAG?

 

Solution: Since .NOT. has the higher priority, the last step is:

                   X .OR. .FALSE.

where X = .NOT. FLAG

But we are told that the final result is .FALSE.  So that X .OR. .FALSE. = .TRUE.

Therefore,  X = .TRUE.

Hence,  FLAG = .FALSE

 

 

3.2.            RELATIONAL OPERATORS

These are used to compare values of arithmetic expressions.  There are six relational operators as shown by the table below:

 

Operator

Math. Notation

FORTRAN Notation

EQual to

=

.EQ.

Not Equal to

¹

.NE.

Greater Than

>

.GT.

Greater or Equal to

³

.GE.

Less Than

<

.LT.

Less than or Equal to

£

.LE.

 

All the six relational operators have the same priority.  However, in relation to Arithmetic and Logical operators,  Arithmetic operators come first, followed by Relational operators, followed by Logical operators.

 

Example 1:          Given that:

                   X=3.0

                   Y=5.0

                   Z=10.0

                   FLAG=.FALSE.

Evaluate the expression:

          .NOT. FLAG .AND. X*Y .GT. Z .OR. X+Y .GT. Z

 

Solution:    = .NOT. FLAG .AND. 15.0 .GT. 10.0 .OR. 8.0 .GT. 10

                   = .NOT. FLAG .AND. .TRUE. .OR. .FALSE.

                   = .TRUE. .AND. .TRUE. .OR. .FALSE.

                   = ..TRUE. .OR. .FALSE.

                   = .TRUE.

 

Example 2:  Assuming that K and L are Integer values.  When will the following expressions be true?

          K/L*L .EQ. K

 

Solutions:  When K is divisible by L

 


Example 3:  Given that: X=3.0         Y=5.0         Z=10.0        FLAG= .FALSE.

          Find the value of each of the following expressions:

(i)                  X*Z .EQ. 20.0 .OR. FLAG .AND. .NOT. Z .EQ. 5.0

(ii)                Z*10 .NE.Y*30 .AND. X .LE. Y .AND. FLAG

 

Solutions:

(i)                  = 30.0 .EQ. 20.0 .OR. FLAG .AND. .NOT. 10.0 .EQ. 5.0

= .FALSE. .OR. FLAG .AND. .NOT. .FALSE.

= .FALSE. .OR. FLAG .AND. .TRUE.

= .FALSE. .OR.FALSE.

=.FALSE.

 

(ii)                = 100.0 .NE. 150.0 .AND. 3.0 .LE.5.0 .AND. FLAG

= .TRUE. .AND. .TRUE. .AND. FLAG

= .TRUE. .AND. FLAG

= .FALSE.

 

 

4.0              IF STRUCTURES

Statements in a program are normally executed in sequence, starting from the beginning to the end.  However, there are situations where we would want certain statement or block of statements to be executed or skipped based on some conditions.  There are also situations where we want to execute one from alternative blocks of statements.  These are the purpose of IF statements.

 

There are four types of IF statements in FORTRAN, These, in order of complexity are: Simple IF, IF, IF-ELSE, and IF-ELSEIF.

 

4.1     Simple IF:  This is used when we have  ONE simple statement that we want to either execute or skip based on a certain condition.  Where simple statement is one that can be written on one line (e.g. Assignment, READ, PRINT, GOTO, etc.)

 

The general form of Simple IF statement is:

                   IF (condition) STATEMENT

IF condition evaluates to .TRUE., the statement is executed, otherwise, it is skipped.

 

Example 1: The following program reads an account balance of a customer and the amount of money the customer wishes to withdraw.  The program then computes and prints the new balance.  The program prints a warning message if the new balance is negative.

 

      REAL BAL, WDR

      PRINT*, ’ENTER CURRENT BALANCE’

      READ*, BAL

      PRINT*, ’ENTER AMOUNT TO WITHDRAW’

      READ*,WDR

      BAL=BAL-WDR

      PRINT*, ’NEW BALANCE IS ’,BAL

      IF (BAL .LT. 0) PRINT*, ’SORRY, ACCOUNT WILL BE IN RED!’

      END

4.2     IF:     This is used when we have a block of statements that we want to either execute or skip based on a certain condition.  Block of statements is one or more FORTRAN statements (not necessarily simple).  The general form of this statement is:

 

          IF (condition) THEN

                   Block of statements

          ENDIF

 

If condition evaluates to .TRUE., the block of statements is executed, otherwise, it is skipped.

Note:          We normally indent the statements between IF and ENDIF by two or three blanks for transparency reasons.

 

Example 1:  Suppose that in the last example, we want to print an additional message, ‘Please see the manager’ when the new balance is negative.  Then we can achieve this using IF statement as follows:

 

      REAL BAL, WDR

      PRINT*, ’ENTER CURRENT BLANCE’

      READ*, BAL

      PRINT*, ’ENTER AMOUNT TO WITHDRAW’

      READ*,WDR

      BAL=BAL-WDR

      PRINT*, ’NEW BALANCE IS ’,BAL

      IF (BAL .LT. 0) THEN

PRINT*, ’SORRY, ACCOUNT WILL BE IN RED!’

PRINT*, ’PLEASE SEE THE MANAGER!!’

      ENDIF

      END

 

Example 2:          Write a program that reads a grade.  If the grade is not zero, the program adds 2 to the grade and then prints the new grade.

 

Solution:    REAL GRADE

        PRINT*, ’PLEASE ENTER GRADE’

        READ*, GRADE

        IF (GRADE .GT. 0) THEN

           GRADE=GRADE+2.0

           PRINT*, ’NEW GRADE = ’, GRADE

        ENDIF

        END

 

4.3     IF-ELSE:   This is used when we have two blocks of statements from which we want to execute one or the other. Its general form is:

 

          IF (condition) THEN

                   Block1

          ELSE

                   Block2

          ENDIF

The condition is first evaluated.  If it evaluates to .TRUE., then block1 is executed and block2 is skipped.  If it evaluates to .FALSE., block2 is executed and block1 is skipped.  Thus, in either case, only one block is executed.

 

Example 1:Write a program that reads two integer numbers and prints the maximum of them.

 

Solution:

      INTEGER N1,N2,MAX

      PRINT*, ’ENTER THE TWO NUMBERS’

      READ*, N1,N2

      IF (N1 .GT. N2) THEN

         MAX=N1

      ELSE

         MAX=N2

      ENDIF

      PRINT*, ’THE MAXIMUN OF ’,N1,’ AND ’,N2,’ IS ’,MAX

      END

 

Example 2:          Write a program that reads an integer number and finds out if the number is odd or even.  The program then prints a proper message.

 

Solution:

     INTEGER N

     PRINT*, ’PLEASE TYPE YOUR NUMBER’

     READ*,N

     IF (N/2*2 .EQ. N) THEN

        PRINT*, ’THE NUMBER IS EVEN’

     ELSE

        PRINT*, ’THE NUMBER IS ODD’

     ENDIF

     END

 

Example 3:          Write a program that reads a real number.  If the number is negative, the program prints the message, ‘THE NUMBER IS OUT OF RANGE’, otherwise, prints the square root of the number.

 

Solution:

     REAL X

     PRINT*, ’TYPE YOUR NUMBER’

     READ*,X

     IF (X .LT. 0) THEN

        PRINT*, ’THE NUMBER IS OUT OF RANGE’

     ELSE

        PRINT*, ’THE SQUARE ROOT OF ’,X,’ IS ’,X**0.5

     ENDIF

     END

 

Example 4:          Write a program that reads the coefficient of a quadratic equation, then computes and prints the roots.  The program should check that the equation has real roots, if not it should print an appropriate message.

     REAL A,B,C,DISC,X1,X2

     PRINT*, ’TYPE THE COEFFICIENTS OF THE EQUATION’

     READ*,A,B,C

     DISC=B**2-4*A*C

     IF (DISC .GE. 0) THEN

        X1=(-B+DISC**0.5)/(2*A)

        X2=(-B-DISC**0.5)/(2*A)

        PRINT*, ’THE ROOTS ARE ’,X1, ’AND ’,X2

     ELSE

        PRINT*, ’SORRY, THE EQUATION HAS NO REAL ROOTS’

     ENDIF

     END

 

4.3     IF-ELSEIF:         This is used when we want to execute one block of statements from among more than two blocks, based on a sequence of conditions. Its general form is:

 

IF (condition 1) THEN

          Block 1

ELSEIF (condition 2) THEN

          Block 2

ELSEIF (condition 3) THEN

          Block 3

         

ELSEIF (condition n) THEN

          Block n

ELSE          (optional)

          Block n+1

ENDIF

 

The conditions are evaluated in sequence until one of then evaluates to true or they are exhausted.

If condition i evaluates to .TRUE., block i is executed and the rest are skipped.

The ELSE part is optional.  If there is an ELSE part and non of the conditions evaluates to .TRUE., block n+1 is executed.  If there is no ELSE part, none of the blocks is executed.

 


Example 1:          Write a program that reads a student ID and his GPA and then prints a message according to the following:

 

GPA ≥ 3.5

EXCELLENT

3.5>GPA≥3.0

VERY GOOD

3.0>GPA≥2.5

GOOD

2.5>GPA≥2.0

FAIR

GPA<2.0

POOR

Solution:

     INTEGER ID

     REAL GRADE

     CHARACTER STATE*10

     PRINT*, ’ENTER ID AND GRADE’

 READ*,ID,GRADE

 IF (GRADE .GE. 3.5) THEN

   STATE=’EXCELLENT’

 ELSEIF (GRADE .GE. 3.0) THEN

   STATE=’VERY GOOD’

 ELSEIF (GRADE .GE. 2.5) THEN

   STATE=’GOOD’

 ELSEIF (GRADE .GE. 2.0) THEN

   STATE=’FAIR’

 ELSE

   STATE=’POOR’

 ENDIF

 PRINT* ID, ’ ’, STATE

 END

 

Example 2:          Write a program that reads a month (an integer in the range 1 …12) and prints the number of days in the month (note: ignore leap years).

 

Solution:

     INTEGER MONTH,DAYS

     PRINT*, ’ENTER THE MONTH’

     READ*,MONTH

     IF (MONTH .EQ. 2) THEN

        DAYS=28

     ELSEIF (MONTH .EQ. 4 .OR. MONTH .EQ. 6 .OR. MONTH .EQ.9     C       .OR. MONTH .EQ. 11) THEN

        DAYS=30

     ELSE

        DAYS=31

     ENDIF

     PRINT*, ’THE NUMBER OF DAYS IS ’,DAYS

     END

 

4.4.            NESTED IF STATEMENTS

Except in the case of simple IF, the block of statements in an IF statement can itself be or contain another IF statement.  This is called Nested IF statement.

Example 1:          Modify the last example to make sure that valid input is entered, otherwise, the program should print the message, ‘SORRY, INVALID INPUT’.

 

Solution:

     INTEGER MONTH,DAYS

     PRINT*, ’ENTER THE MONTH’

     READ*,MONTH

     IF (MONTH .GT. 12 .OR. MONTH .LT. 1) THEN

        PRINT*, ’SORRY, INVALID INPUT’

     ELSE

   IF (MONTH .EQ. 2) THEN

           DAYS=28

        ELSEIF (MONTH .EQ. 4 .OR. MONTH .EQ. 6 .OR.

    C           MONTH .EQ. 9. OR. MONTH .EQ. 11) THEN

           DAYS=30

        ELSE

           DAYS=31

        ENDIF

        PRINT*, ’THE NUMBER OF DAYS IS ’,DAYS

     ENDIF

     END

 

 

5.                  Functions

Top-down design, as explained earlier, is one of the most popular method of software design.  It involves breaking down a problem into subtasks and solve these subtasks by smaller and simpler solutions.  FORTRAN supports this design method through the concept of subprograms.  Subprograms are self-contained, independent program codes that are aimed at solving a given subtask.  A good program should normally consists of a main program and a set of subprograms for each of the subtasks the program performes.

 

The following are some of the advantages of dividing a program into subprograms:

·        Subprograms can be independently implemented and tested. This makes the construction of a program much easier.

·        Subprograms can be easily copied and used in another program that requires the same tasks.  This makes it possible for a library of subprograms to be developed, so that programming becomes an assembly process.  It also makes it possible to use subprograms written by others.

·        Subprograms reduce the size of programs since once a subprogram is written for a given task, it is simply invoked at any place it is required within the program rather than repeating the code.

·        It is also easier to identify errors and make corrections and modifications in smaller programs.  Thus, programs that consist of subprograms are easier to maintain.

 

There are two types of subprograms in FORTRAN, namely, FUNCTIONS and SUBROUTINES.  This section discusses functions.

 


5.1              FUNCTIONS:

          This is a subprogram that is aimed at computing a single value given one or more arguments.  It can appear before or after the main program.  Its general form is:

 

Return type FUNCTION fname (list of arguments)

Declaration of dummy & local variables

Executable statements (at least one of which is fname=expression)

RETURN

END

 

The first line is called the header while the rest of the lines form the body.

Return type is the type of value the function is to return (e.g. INTEGER, REAL, ...)

fname is the name of the function to be given by the programmer following the same rules as for naming variables.

List of arguments consist of the argument(s) that are required by the function for it to compute the required value.  These are usually called formal or dummy arguments as they are not given any values until the function is invoked or called. 

Local variables are other variables that may be required for the computation of the value

Executable statements are one or more FORTRAN statements that actually compute the value to be returned by the function.  At least one of these must be an assignment statement that assigns a value to the function name.  Thus a function returns its value through its name.

Every function must include at least one RETURN statement that returns control to the calling program. 

Finally, like main programs, END indicates the physical end of a function.

 

Example 1:  Write a real function that computes the volume SVOL, of a sphere, given its radius.

 

Solution:

      REAL FUNCTION SVOL (R)

      REAL R, PI

      PI=3.14159

      SVOL = 4.0/3.0*PI*R**3

      RETURN

      END

 

Example 2:  Write a logical function ORDER that checks whether three different integer numbers are ordered in increasing or decreasing order.

 

Solution:

     LOGICAL FUNCTION ORDER (NUM1, MUM2,NUM3)

     INTEGER NUM1, NUM2, NUM3

     LOGICAL DEC, INC

     DEC = NUM1 .GT. NUM2 .AND. NUM2 .GT. NUM3

     INC = NUM1 .LT. NUM2 .AND. NUM2 .LT. NUM3

     ORDER = DEC .OR. INC

     RETURN

     END

 


Example 3:  Write a function to evaluate the following:

         

 Solution:

     REAL FUNCTION F(X)

     REAL X

     IF (X .LT. 5) THEN

        F=2*X**2 + 4*X + 2

     ELSEIF (X .EQ. 5) THEN

        F=0

     ELSE

        F=3*X + 1

     ENDIF

     RETURN

     END

 

5.2              FUNCTION CALL

The execution of a program that has functions (and/or subroutines) begins with the main program.  For a function to be executed, it has to be called or invoked by the main program.  A function is called as part of a statement (such as assignment or print statement) in the main program.  When a function is called, a value must be supplied for each of the function’s dummy arguments.  These values are called actual arguments.  The, actual arguments can be constant values, variables that have values assigned to them, or expressions that will result in a value.  The following are examples of valid and invalid function calls, assuming A=5.0 and B=21.0

 

Valid Call

Result

Invalid Call

Error Message

OREER(3,2,4)

.FALSE.

ORDER(3.0,2,4)

Argument 1 referenced as real

ORDER(3,4*3,99)

.TRUE.

 

But defined to be integer

SVOL(B)

38808.0

F(3.2, 3.4)

More than one argument to function

F(A+B)

79

SVOL(5)

Argument 1 referenced as integer

F(3.0+F(2.0))

64.0

 

But defined to be real

 

Example 1:  Write an integer function sum to add three integers.  Write a main program to test the function:

 

Solution:

     INTEGER X,Y,Z, SUM

     READ*, X,Y,Z

     PRINT*, ’THE SUM = ’,SUM(X,Y,Z)

     END

 

     INTEGER FUNCTION SUM(A,B,C)

     INTEGER A,B,C

     SUM = A+B+C

     RETURN

     END

Notice the following rules about function call

·        Actual and dummy arguments must match in type, order and number

·        Actual arguments may be constants, variables or expressions but dummy arguments must be variables.

·        Dummy and Actual arguments can have the same or different names.

·        The type of the function must be the same in both the calling program and the function

·        Function call is part of an expression

·        A FORTRAN function cannot call itself although it can be called not only by the main program but also by other subprograms as well.

 

Example 2:          Write a function RNUM to reverses a two digits number.  The function should return –1 if the number is not two digits.  Write a main program to test the function.

Solution:

     INTEGER FUNCTION RNUM(NUM)

     INTEGER NUM, TENS, UNITS

     IF (NUM .GE. 10 .AND. NUM .LE. 99) THEN

        TENS = NUM/10

        UNITS = NUM – TENS*10

        RNUM = UNITS*10 + TENS

     ELSE

        RNUM = -1

     ENDIF

     RETURN

     END

 

C   MAIN PROGRAM

     INTEGER NUM, RNUM, RESULT

     PRINT*, ’ENTER YOUR NUMBER’

     READ*, NUM

     RESULT = RNUM(NUM)

     IF (RESULT .EQ. –1) THEN

        PRINT*, ’INVALID INPUT ’, NUM

     ELSE

        PRINT*, NUM ’ REVERSED IS ’, RESULT

     ENDIF

     END

 

Example 3: Write a logical function FACTOR that takes two integer arguments and checks if the first argument is a factor of the second.

 

Solution:

     LOGICAL FUNCTION FACTOR (N1, N2)

     INTEGER N1, N2

     FACTOR  = N2/N1 * N1 .EQ. N2

     RETURN

     END

 

C  MAIN PROGRAM

     LOGICAL FACTOR

     INTEGER, NUM1, NUM2

     READ*, NUM1, NUM2

     PRINT*, FACTOR(NUM1, NUM2)

     END


5.3              INTRINSIC FUNCTIONS

These are pre-defined functions that are available from the FORTRAN language.  They are used (called) in the same manner as user-defined functions, the only different is that they do not need subprogram description.  Some of the common intrinsic functions are shown below:

Functions

Function Value

Comments

SQRT(X)

Square Root of X

X is a real argument

ABS(X)

Absolute value of X

 

SIN(X)

Sine of X

Angle in Radians

COS(X)

Cosine of X

TAN(X)

Tangent of X

EXP(X)

e raised to power X

 

LOG(X)

Natural log of X

X real

LOG10(X)

Log to base 10 of X

X real

INT(X)

Integer value of X

Coverts real to integer

REAL(K)

Real value of X

Converts Integer to real

MOD(M,N)

Remainder of M/N

Modulo function

 

5.4              STATEMENT FUNCTIONS

In engineering & scientific applications, we frequently encounter functions that can be written in a single statement.  For example, f(x) = x+2.  In such cases, FORTRAN allows us to write a statement function instead of a function subprogram.  A statement function is defined after declarations but before any executable statement.  The general for is:

fname (list of dummy arguments) = expression

 

Example1:           REAL AREA,SIDE1,SIDE2, ANGLE

                             AREA(SIDE1, SIDE2, ANGLE) = 0.5*SIDE1*SIDE2*SIN(ANGLE)

 

Example 2:          INTEGER TOTSEC, HR, MIN, SEC

                             TOTSEC(HR,MIN,SE) = 3600*HR + 60*MIN + SEC

 

Example 3:          REAL F,X,Y

                             F(X,Y) = 2*X**2 + 5*X*Y

 

Example 4:          Write a program that reads a code and temperature.  If the code is 1, convert from centigrade to Fahrenheit.  If the code is 2, convert from Fahrenheit to centigrade.  The program should make use of statement functions that perform the conversion.

Solution:

  REAL FTEMP, CTEMP, TEMP, VALUE

      INTEGER CODE

      FTEMP(TEMP) = TEMP*9/5 + 32

      CTEMP(TEMP) = (TEMP – 32) * 5/9

      PRINT*, ’ENTER TEMPERATURE CODE AND VALUE’

      READ*, CODE, VALUE

      IF (CODE .EQ. 1) THEN

        PRINT*, VALUE, ’C = ’, FTEMP(VALUE), ’F’

      ELSEIF

        PRINT*, VALUE, ’F = ’, CTEMP(VALUE), ’C’

      ELSE

        PRINT*, ’INPUT ERROR’

      ENDIF

      END

6.                  SUBROUTINES

A function produces a single value.  However, there are many programming situations, where we would like a subprogram to produce more than one value.  There are also situations where a subtask does not involve the evaluation of values at all, but instead, some action such as printing is required.  Subroutines are subprograms designed to solve these types of problems. i.e. they can return zero, one, or more values. Like functions, they can appear either before or after the main program.  The general form is:

 

SUBROUTINE sname (list of dummy arguments)

Declarations

Executable statements

RETURN

END

 

Similar to functions:

·        The Dummy arguments and the Actual arguments must match in type, order and number

·        Dummy and Actual arguments can have the same or different names.

·        Subroutines cannot call themselves, but may be called by the main program as well as other subprograms.

·        At least one RETURN statement is required to return control to the calling program. Also END is use to indicate the physical end of a subroutine.

 

Subroutines differ from functions in the following ways:

·        A subroutine has no return type

·        A subroutine may return a single value, many values or no value at all.

·        A subroutine returns its values (if any) through its dummy arguments. Thus, a subroutine uses its dummy arguments for both receiving input and returning output.

·        A subroutine is called by an executable statement, CALL, which has the form:

                   CALL sname (list of actual arguments)

 

Example 1:  Write a subroutine, SWAP, that exchanges the values of its two real arguments.  Write a main program to test the subroutine.

 

Solutions:

     SUBROUTINE SWAP (NUM1,NUM2)

     REAL NUM1, NUM2, TEMP

     TEMP = NUM1

     NUM1 = NUM2

     NUM2 = TEMP

     RETURN

     END

 

C   MAIN PROGRAM

     INTEGER N1, N2

     PRINT*, ’ENTER VALUES FOR N1, AND N2’

     READ*, N1, N2

     PRINT*, ’THE VALUES BEFORE EXCHANGE ARE ’,N1,N2

     CALL SWAP(N1,N2)

     PRINT*, ’THE VALUES AFTER EXCHANGE ARE ’,N1,N2

     END

Example 2:  Write a subroutine that takes three different integer arguments, X, Y, and Z and returns the maximum and minimum of the numbers.  Write a main program to test the subroutine by calling it with input parameters, A=4, B=6 and C=8 and print the result.  Call the subroutine the second time with input arguments, C+4, -1, and A+B and print the result.

 

Solution:

 SUBROUTINE MAXMIN (X, Y, Z, MAX, MIN)

 INTEGER X, Y, Z, MAX, MIN

 MAX = X

 MIN = X

 IF (Y .GT. MAX) MAX = Y

 IF (Y .LT. MIN) MIN = Y

 IF (Z .GT. MAX) MAX = Z

 IF (Z .LT. MIN) MIN = Z

 RETURN

 END

 

C   MAIN PROGRAM

     INTEGER A, B, C, MAX, MIN

     A = 4

     B = 6

     C = 8

     CALL MAXMIN(A, B, C, MAX, MIN)

     PRINT*,’FOR ’,A,B,C, ’MAXIMUM = ’,MAX, ’ MINIMUM = ’,MIN

     CALL MAXMIN(C+4, -1, A+B, MAX, MIN)

     PRINT*,’FOR ’,C+4,-1,A+B, ’MAXIMUM = ’,MAX,’ MINIMUM = ’,MIN

     END

 

Notice from the above example that

·        The input dummy arguments can be constant values, variables or expressions, but the output dummy arguments must be variables.

·        A subroutine (or function) can be called any number of times within a program.

 

Example 3:          Write a subroutine to sum three integers and compute their average.  Write a main program to test the subroutine.

 

Solution:

C   MAIN PROGRAM

     INTEGER X, Y, Z, SUM

     REAL AVG

     PRINT*, ’ENTER THREE NUMBERS’

     READ*, X,Y,Z

     CALL SUMAVG(X,Y,Z,SUM,AVG)

     PRINT*, ’THE TOTAL = ’, SUM

     PRINT*, ’THE AVERAGE = ’, AVG

     END

 

     SUBROUTINE SUMAVG (A, B, C, T, V)

     INTEGER A,B,C,T

     REAL V

     T = A+B+C

     V = T/3.0

     RETURN

     END

 

Example 4: Write a subroutine that takes a real number and returns the integer part and the real part of the number.  Write a main program to test the subroutine.

 

Solution:

C   MAIN PROGRAM

     REAL NUM, RNUM

     INTEGER INUM

     PRINT*, ’ENTER YOUR REAL NUMBER’

     READ*,NUM

     CALL SEPNUM (NUM, RNUM, INUM)

     PRINT*, ’THE ORIGINAL NUMBER IS ’, NUM

     PRINT*, ’THE INTEGER PART IS ’, INUM

     PRINT*, ’THE REAL PART IS ’, RNUM

    END

 

     SUBROUTINE SEPNUM (X,R,I)

     REAL X,R

     INTEGER, I

     I = INT(X)

     R = X – I

     RETURN

     END

 

The following example shows that a subroutine can be called by another subroutine.

 

Example 5:  Two brothers, Khalid and Walid enter into a business deal, with Khalid contributing two thirds of the capital and Walid contributing the remaining one third.  At the end of the year, the profit generated is to be shared according to the contribution of each, and after removing 2.5% as zakat.  Write a subroutine PROFIT that computes their respective shares given the profit generated.  The subroutine should call a function ZAKAT that computes zakat given an amount, assuming that the nisab for zakat is 20000.  Write a main program to test the subroutine.

 

Solution

    REAL FUNCTION ZAKAT(A)

    REAL A

    IF (A .LT. 20000) THEN

        ZAKAT=0

    ELSE

        ZAKAT=0.025*A

    ENDIF

    RETURN

    END

 

    SUBROUTINE PROFIT(AMOUNT,A,B)

    REAL AMOUNT,A,B,BAL,ZAKAT

    BAL=AMOUNT-ZAKAT(AMOUNT)

    A=2.0/3.0*BAL

    B=1.0/3.0*BAL

    RETURN

    END

 

C   MAIN PROGRAM

    REAL P, X, Y

    PRINT*, 'PLEASE ENTER THE PROFIT'

    READ*, P

    CALL PROFIT(P,X,Y)

    PRINT*, 'AMOUNT FOR KHALID =',X

    PRINT*, 'AMOUNT FOR WALID =',Y

    END

 

7.                  DO LOOPS

While writing a program, it may be necessary to execute a statement or a group of statements repeatedly.   Repetitions can be of two types; deterministic, where the number of times the execution is to be repeated is known, or indeterministic, where the repetition is terminated by a condition.  Accordingly, FORTRAN has two types of repetition constructs to handle each of these cases.  These are, DO loop and WHILE loop.

 

The DO loop is concerned with deterministic repetition and is the subject of this section.  Its general form is:

 

          DO N index = initial, limit, increment

                   Block of statements

N       CONTINUE

 

Where index is a variable, initial, limit and increment are expressions and N is a label for the CONTINUE statement.  The increment is optional.  If it is omitted, an increment of 1 or 1.0 is assumed, depending on whether index is of type integer or real.

 

The block of statement is called the loop body.  Each execution of the loop body is called an iteration.  The number of iterations for a DO loop is given by: 

When the statement is encountered,  the execution goes as follows:

Step1:  index is assigned the value of initial

Step2:  If index is less than or equal to limit, the block of statements is executed and it goes to step3.   If index is greater than the limit, the loop is terminated, and control goes to the statement following CONTINUE.

Step3:  index is incremented by value of increment and it goes back to step2.

 

The following diagram summarizes the action of a DO loop.

 

 

 

 

 

 

 

 

 

 


           

 

 

 

 

 

 

 

 

Example 1: The following are two versions of a program that prompts and reads the grades of 5 students in an exam (one per input line) and computes the average grade. 

 

Solution 1:  (Without using DO-Loop)

 

Solution 2:  (Using DO-Loop

REAL X1,X2,X3,X4,X5,SUM,AVG

PRINT*, ’ENTER NEXT GRADE’

READ*,X1

PRINT*, ’ENTER NEXT GRADE’

READ*,X2

PRINT*, ’ENTER NEXT GRADE’

READ*,X3

PRINT*, ’ENTER NEXT GRADE’

READ*,X4

PRINT*, ’ENTER NEXT GRADE’

READ*,X5

SUM = X1+X2+X3+X4+X5

AVG = SUM/5

PRINT*,’AVERAGE GRADE=’,AVG

 

REAL X,SUM,AVG

INTEGER I

SUM=0

DO 10 I=1,5

    PRINT*, ’ENTER NEXT GRADE’

    READ*, X

    SUM=SUM+X

10   CONTINUE

AVG = SUM/5

PRINT*, ’AVERAGE GRADE =’,AVG

 

 

Notice from the above example that the solution that does not use DO loop is longer.  It will even be much longer if the number of students is increased.  For example if it is increased to 8, then we need 6 more lines in solution1, while we only need to change the limit in solution2 from 5 to 8.

 

The following rules apply to DO loops:

·        The index must be a variable of either integer or real type, but initial, limit, and increments can be constant values, variables or expressions of type integer or real.

·        The value of index cannot be modified inside the loop body.

·        The increment must not be zero otherwise an error occurs.

 

Example 2:  Write a FORTRAN program that reads an integer M and then computes and prints the factorial of M

 

Solution:

    INTEGER M, TERM, FACT

    PRINT*, ’ENTER YOUR NUMBER’

    READ*, M

    IF (M .GT. 0) THEN

        FACT=1

        TERM=M

        DO 10 TERM=M,2,-1

           FACT=FACT*TERM

10      CONTINUE

        PRINT*, ’FACTORIAL OF ’,M, ’ IS ’,FACT

    ELSE

        PRINT*, ’INVALID INPUT’

    ENDIF

    END

 

 

Example 3:          Write a program that reads grades of students in a section and finds the highest grade. Read at the beginning, an integer N which represents the number of students in the section.

 

Solution:

     REAL GRADE, H

     INTEGER, N,I

     PRINT*, ’ENTER NUMBER OF STUDENTS’

     READ*,N

     H=0.0

     DO 10 I=1,N

        PRINT*, ’ENTER NEXT GRADE’

        READ*, GRADE

        IF (GRADE .GT. H) H=GRADE

10  CONTINUE

     PRINT*, ’THE HIGHEST GRADE =’,H

     END

 

Example 4:          A leap year is any year that is a multiple of 400 or that is a multiple of 4 but not a multiple of 100. Write a logical function ISLEAP which determines whether a year is leap or not. Write a main program which uses the logical function to print all leap years in the range 1950 to 1999.

 

Solution

C   MAIN PROGRAM

     INTEGER YEAR

     LOGICAL ISLEAP

     PRINT*, ’LEAP YEARS BETWEEN 1950 TO 1999’

     DO 10, YEAR=1950,1999

        IF (ISLEAP(YEAR)) PRINT*, YEAR

10  CONTINUE

     END

 

 LOGICAL FUNCTION ISLEAP(Y)

 ISLEAP=Y/4*4 .EQ. Y .AND. Y/100*100 .NE. 100 .OR.

C      Y/400*400 .EQ. 400

     RETURN

     END

 

7.1     NESTED DO LOOPS

The Block of statement within a DO loop can itself be (or contain) a DO loop.  This is called nested DO loop.  The following is an example of a program consisting of a nested DO Loop.  Its output is shown on the right.

 

     INTEGER M,N

     DO 111 M=1,2

     DO 122 N=1,6,2

             PRINT*, M, J

122     CONTINUE

111 CONTINUE

END

1        1

1        3

1        5

2        1

2        3

2        5

 

Note:  A nested DO loop can have one CONTINUE statement.  For example, the above program can be written as follows:

 INTEGER M,N

 DO 111 M=1,2

       DO 111 N=1,6,2

                             PRINT*, M, J

111      CONTINUE

  END

 

7.2              INPLIED LOOPS

If a DO loop involves only the READ or the PRINT statement, then it can as well be handle by implied loop.  Implied loop has the general form:

 

READ*, (list of variables, index=initial, limit, increment)  OR

PRINT*, (list of expressions, index=initial, limit, increment)

 

As in the case of explicit DO loops, the index must be either of type integer or real.  All the rules that apply to DO loop parameters also apply to implied loop parameters.

 

Example 1:  The following statement print values from 100 to 87

    PRINT*, (K, K=100, 87, -1)

 

Notice that the statement above is treated as one PRINT statement, hence the output is on one line as shown below:

100    99      98      97      96      95      94      93      92      91      90      89      88      87

 

The equivalent DO loop statement is:

     DO 10 K=100,87,-1

        PRINT*, K

10  CONTINUE

 

In the DO loop above, the PRINT statement is executed 14 times, thus producing 14 lines of output as shown below:

100

99

87

 

Example 2:The following implied loop prints more than one value in each iteration:

    PRINT*, (’%’, ’+’, M=1,3)

 

The output from the above statement is:

          %+%+%+

 

Example 3:  An Implied loop may also be nested either in another implied loop or in an explicit DO loop.  There is restriction on the number of levels of nesting. The following segment shows nested implied loops.

 

    PRINT*, ((K, K=1,5,2), L=1,2)

 

The output of the above statement is as follows:

1        3        5        1        3        5


8.                  WHILE LOOP

WHILE loop is used when the number of iteration required is not known, but it is to be determined by some condition.  Its general form is as follows:

 

DO WHILE (condition)

          Block of statements

END DO

 

The condition, which is a logical expression, is first evaluated.  If it produces a .TRUE. value, the block of statements is executed. The condition is evaluated again and if it produces a .TRUE. value, the block of statements is executed.  This process is repeated continuously until the condition evaluates to a .FALSE. value. At this point the loop is terminated and control goes to the statement following the END DO.

 

The following diagram illustrates the execution of a WHILE loop.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Notice that if the condition evaluates to .FALSE. the first time, the block of statements is not executed at all. i.e., there will be zero iterations.

 

Example 1:  Write a program that reads and classify the weights of boxers according to the following criteria:

Weight £ 65 kg

Light-weight

65 < weight <85kg

Middle-weight

Weight ³ 85

Heavy-weight

 

The program should repeatedly reads the weight and prints an appropriate message until a weight of –1.0 is read.

 

Solution:  Notice hare that the number of boxers is not known, hence DO loop cannot be used.  However, since the termination condition has been given (input value of –1), we can use WHILE loop.  When an input value is used to terminate a WHILE loop, it is called a sentinel or end-marker.

     REAL WEIGHT

     PRINT*, ’ENTER NEXT WEIGHT’

     READ*, WEIGHT

     DO WHILE (WEIGHT .NE. –1)

          IF (WIGHT .LE. 65) THEN

              PRINT*, ’LIGHT WEIGHT’

          ELSEIF (WEIGHT .LT. 85) THEN

              PRINT*, ’MIDDLE WEIGHT’

          ELSE

              PRINT*, ’HEAVY WEIGHT’

          ENDIF

     PRINT*, ’ENTER NEXT WEIGHT’

     READ*, WEIGHT

     END DO

     END

 

Example 2:  Write a program that reads real values from a user (one value per line), until a sentinel of –1 is entered.  The program should print the number of values, their sum and their average.

 

Solution:

     REAL X, SUM, AVG

     INTEGER COUNT

     COUNT=0

     SUM=0.0

     PRINT*, ’ENTER NEXT VALUE’

     READ*,X

     DO WHILE (X .NE. –1)

          SUM = SUM+X

          COUNT=COUNT+1

          PRINT*, ’ENTER NEXT VALUE’

          READ*, X

     END DO

     AVG = SUM/COUNT

     PRINT*, ’NUMBER OF VALUES =’, COUNT

     PRINT*, ’THE SUM =’ SUM

     PRINT*, ’THE AVERAGE =’, AVG

     END

 

Example 3: Write a program that reads a real value S, (1.5 £ S £ 15) and find the smallest integer such that 1 +1/2 + 1/3 + … +1/n > S

 

Solution:

     REAL S, SUM

     INTEGER N

     N = 0

     SUM = 0.0

PRINT*, ’ENTER VALUE FOR S IN THE RANGE 1.5 … 15’

READ*, S

DO WHILE (SUM .LE. S)

     N = N+1

     SUM = SUM + 1.0/N

END DO

PRINT*, ’VALUE OF N =’, PI

PRINT*, ’THE CORRESPONDING SUM =’, SUM

END

 

Example 4:           Write a FORTRAN program that finds an approximate value for p, using the following infinite series.  p2/6 = 1/12 + 1/22 + 1/32 + …..  The program should stop if the difference between two successive approximations is less than 0.000001.

Solution:

Notice here that we need to keep two successive values of p.  The condition for terminating the loop is the difference between the two values being less than 0.000001.

REAL TERM, SUM, PI, OLDPI

OLDPI = SQRT(1*6.0)

TERM=2.0

SUM = 1.0 + 1/4.0

PI = SQRT(SUM*6)

DO WHILE (PI – OLDPI .GE. 0.000001)

     OLDPI = PI

     TERM=TERM+1

     SUM = SUM + 1.0/TERM**2

     PI = SQRT(SUM*6)

END DO

PRINT*, ’THE APPROXIMATE VALUE OF PI =’, PI

END

 

Notice that all DO loops can be converted to WHILE loops but not all WHILE loops are convertible to DO loops.

 

Example 5:  Convert the following DO loop into WHILE loop.

 

DO loop

Equivalent WHILE loop

     REAL X, AVG, SUM

     INTEGER K

     SUM = 0.0

     DO 10 K=1, 100

          READ*, X

          SUM = SUM+X

10   CONTINUE

     AVG = SUM/100

     PRINT*, AVG

     END

     REAL X, AVG, SUM

     INTEGER K

     SUM = 0.0

     K=0

     DO WHILE (K .LT. 100)

          READ*, X

          SUM = SUM+X

          K = K+1

     END DO

     AVG = SUM/100

     PRINT*, AVG

     END

 

Notice that in the WHILE loop, we need to initialize K before the loop and increment it inside the loop.  This is done automatically by the DO loop.

 

8.2  NESTED WHILE LOOPS

A WHILE loop can contain as its body, another WHILE loop.  This is called nested WHILE loop.  The following example illustrates this:

 

Example 6:

Output of the program:

INTEGER M, J

             M = 1

             DO WHILE (M .LE. 2)

                         J=1

                         DO WHILE (J .LE. 6)

                                      PRINT*, M,J

                                      J=J+2

                         END DO

                         M = M+1

             END DO

             END

1        1

1        3

1        5

2        1

2        3

2        5

 

 

 

9.                  I-D ARRAY

It is common in programs to read a large quantity of input data.  Simple variables that we have learnt so far are not suitable for such operations.  For example, consider a problem to compute the grades of 30 students and list the grades of those students below the average.  The grades must be stored in the memory while reading because after the average is computed, they have to be processed again to list those below average.  Thus, 30 simple variables are required.  Clearly, it is not convenient to declare such number of variables.  To solve this problem, we use 1-D array.

 

9.1     DECLARATION OF 1-D ARRAY.

1-D array represents a group of memory locations and is declared as follows:

TYPE aname1(n)

OR

TYPE aname2(n1:n2)

 

Where the TYPE indicates the type of elements the array can store. In the first case, n is an integer representing the number of elements the array can store with subscripts (or index) 1…n.  In the second case, the array can store n2-n1+1 elements with subscripts, n1, n1+1, …, n2.

 

These declarations can be represented diagrammatically as follows.

 

 

 


aname1

 

 

 

 

….

 

 

1

2

3

4

 

n

Subscript

 

 

aname2

 

 

 

 

….

 

 

n1

n1+1

n1+2

n1+3

 

n2

 

Note:  The elements of an array can be of any type, but the subscript must be of type integer.

 

Example1: The following table shows some examples of array declaration.

INTEGER LIST(30)

Integer array LIST of 30 elements

LOGICAL FLAG(20)

Logical array FLAG of 20 elements

CHARACTER NAMES(15)*20

Character array NAMES of 15 elements each of size 20

REAL YEAR(1983:1994)

Real array YEAR of  12 elements with index 1983-1994

 

Array can also be declared using the DIMENSION statement.  This assumes implicit type declaration.  However, it can be combined with explicit type declaration to specify the type.

 

e.g.    DIMENSION ALIST(100), KIT(-3:5), XYZ(15)

          INTEGER XYZ

          REAL BLIST(12), KIT

 

In this example, ALIST, BLIST and KIT are of type real and XYZ is of type integer.

 

9.2     INITIALISING 1-D ARRAY

An element of an array is accessed by appending its index in parenthesis to the array name as shown below:

 

LIST(2)                 second element of array LIST

YEAR(1984)         second element of array YEAR

NAMES(4)           fourth element of array NAMES

A 1-D array can be initialized by using assignment statement to assign a value to each of its elements. This can be easily achieved in a DO-loop as shown below.

 

Example 1:  Declare a real array LIST of 3 elements and initialize each to zero.

 

REAL LIST(3)

DO 5 K=1,3

     LIST(K)=0.0

5    CONTINUE

 

Example2:  Declare an integer array power2 with subscripts 0 to 10 and store the powers of 2 from zero to 10 in the array.

 

INTEGER POWER2(0:10),K

DO 7 K=0,10

     POWER2(K)=2**K

7    CONTINUE

 

An array can also be initialized using READ statement.  We can read into the whole array either using the array name or by using a loop to read values into the individual elements.

 

Example3:  Read all the elements of an integer array X of size 4.  Assuming the four input values are in a single line.

 

Solution1:    INTEGER X(4)       Solution2:    INTEGER X(4),K

              READ*, X                         READ*, (X(K),K=1,4)

 

The two solutions above are equivalent.  The only difference is that, the second can be modified to read into part of the array but the second cannot.

 

Example4:  Read all the elements of an integer array X of size 4.  Assuming that the input data values apper in four input lines.

 

Solution1:    INTEGER X(4), I         Solution2:    INTEGER X(4),I

          DO 11 I=1,4                           I=0

                   READ*,X(I)                       DO WHILE (I .LE. 4)

11   CONTINUE                                   I=I+1

READ*, X(I)

END DO

 

Note: These solutions require four input lines since the READ statement is executed 4 times.  Thus it will not work if the input is on one line.  On the other hand, both solutions (1) and (2) in example3 above can work even if the input data is on 4 lines.  Example4 can also be solved using WHILE loop as shown by solution2.

 

Example5:  Read the first five elements of a logical array PASS of size 20.  Assume the input is one per line.

 

Solution: LOGICAL PASS(20)

          INTEGER K

          READ*, (PASS(K), K=1,5)

 

Example6: Read the grades of N students into an array SCORE.  The value of N is the first data value, followed by N data values in the next input line.

 

Solution: INTEGER SCORE(100), K, N

          READ*,N

          READ*, (SCORE(K), K=1,N)

 

Note that in the above example, the number of elements is not given until run-time.  But array must be declared using a constant integer value in the main program (we shall see letter that an integer variable can be used if the array is declared in a subprogram).  Thus our only option is to declare the array with some large size and hope that elements will not exceed the size

 

9.3         PRINTING 1-D ARRAY

Printing of array is similar to reading.  It can be done without subscript in which case all the elements are printed on one output line.  Individual elements can also be printed by specifying their subscripts.

 

Example 1: Read an integer array X of size 4 and print:

(i)                  The entire array

(ii)                One element per line

(iii)               Those elements greater than one.

 

Solution:

     INTEGER X(4),K

     READ*, X

     PRINT*, ’PRINTING THE ENTIRE ARRAY’

     PRINT*, X

     PRINT*, ’PRINTING ONE ELEMENT PER LINE’

     DO 11 K=1, 4

          PRINT*, X(K)

11   CONTINUE

     PRINT*, ’PRINTING ELEMENTS GREATER THAN ZERO’

     DO 22 K=1, 4

          IF (X(K) .GT. 0) PRINT*, X(K)

22   CONTINUE

     END

 

9.4     PROGRAM EXAMPLES

Example 1:  Write a program that reads an integer N and then reads N data values into an array.  The program should count the number of those elements that are odd.  Assume that the number of elements is not more that 50.

 

Solution:

     INTEGER A(50), COUNT,N,K

     READ*, N, (A(K), K=1,N)

     COUNT =0

     DO 33 K=1,N

          IF (MOD(A(K),2) .EQ. 1) COUNT=COUNT+1

33   CONTINUE

     PRINT*, ’COUNT OF ODD ELEMENTS =’,COUNT

     END

 

Example 2:  Write a program that reads an integer array of size N and then reverses the elements of the array using the same array.  Assume that the number of elements is not more than 100.

 

Solution:

     INTEGER NUM(100),TEMP,I,N

     READ*, N

     READ*, (NUM(I), I=1,N)

     DO 44 I=1, N/2

          TEMP=NUM(I)

          NUM(I)=NUM(N+1-I)

          NUM(N+1-I)=TEMP

44   CONTINUE

     PRINT*, (NUM(I), I=1,N)

END

9.4         Arrays in Subprograms

1-D array can be passed as an argument to a subprogram or be used locally within a subprogram.  The size of such an array can be declared as a constant or a variable.  However, variable-sized declaration in a subprogram is allowed only if both the size and the array are dummy arguments.

 

Example 1:  Write a function ASUM that returns the sum of an integer array of any size.  Write a main program to test the function using an array of size 4 and another array of size 5.

 

Solution:

INTEGER A(4), B(5), ASUM

PRINT*, ’ENTER VALUES FOR FIRST ARRAY’

READ*, A

PRINT*, ’ENTER VALUES FOR SECOND ARRAY’

READ*, B

PRINT*, ’SUM OF FIRST ARRAY=’,ASUM(A,4)

PRINT*, ’SUM OF SECOND ARRAY=’,ASUM(B,5)

END

 

INTEGER FUNCTION ASUM(A,N)

INTEGER N, A(N),I

ASUM=0

DO 55 I=1,N

          ASUM=ASUM+A(I)

55   CONTINUE

RETURN

END

 

Example 2:  Write a function EQUAL that returns true if two given array are equal and false otherwise.  Write a main program to test the function by reading an integer N and two arrays of size N.  Assume that N is not more than 100.

 

Solution:

INTEGER A(100), B(100), N,I

PRINT*, ’ENTER SIZE OF ARRAYS’

READ*, N

PRINT*, ’ENTER VALUES FOR ARRAY A’

READ*, (A(I), I=1, N)

PRINT*, ’ENTER VALUES FOR ARRAY B’

READ*, (B(I), I=1, N)

IF (EQUAL(A,B,N)) THEN

     PRINT*, ’A=B=’,(A(I), I=1,N)

ELSE

          PRINT*, ’A=’,(A(I), I=1,N)

          PRINT*, ’B=’,(B(I), I=1,N)

ENDIF

END

 

LOGICAL FUNCTION EQUAL(A1,A2,SIZE)

INTEGER A1(SIZE), A2(SIZE), I, SIZE

EQUAL = .TRUE.

DO 55 I=1, SIZE

     IF (A1(I) .NE. A2(I)) THEN

          EQUAL = .FALSE.

          RETURN

     ENDIF

55   CONTINUE

     RETURN

     END

Example 3:  Write a subroutine UPDATE that takes a real array A of variable size and replaces every element of A with its absolute value.  Test the subroutine with an array of size 10.

 

     SUBROUTINE UPDATE(A,N)

     INTEGER I,N

     REAL A(N)

     DO 66 I=1,N

          A(I) = ABS(A(I))

66   CONTINUE

     RETURN

     END

 

     INTEGER J,N

     REAL A(10)

     PRINT*, ’ENTER VALUES FOR THE ARRAY’

     READ*, A

     PRINT*, ’ORIGINAL ARRAY =’, (A(J), J=1,N)

     CALL UPDATE (A,10)

     PRINT*, ’UPDATED ARRAY =’, (A(J), J=1,N)

     END

 

Example 4:  Write a subroutine LAZY that takes a real array containing the grades of N students and returns the COUNT of those below average and the list of those grades below average in another array. Test the subroutine with an array of size 10.

 

SUBROUTINE LAZY (A,N,B,COUNT)

INTEGER N,COUNT,I

REAL A(N), B(N),SUM,AVG

SUM=0.0

DO 10 I=1,N

     SUM=SUM+A(I)

10   CONTINUE

     AVG=SUM/N

     COUNT=0

     DO 20 I=1,N

          IF (A(I) .LT. AVG) THEN

COUNT=COUNT+1

B(COUNT)=A(I)

ENDIF

20   CONTINUE

     RETURN

     END

 

     REAL A(10),B(10)

     INTEGER C

     PRINT*, ’ENTER 10 VALUES FOR THE ARRAY’

     READ*, A

     CALL LAZY(A,10,B,C)

     PRINT*, ’NUMBER OF LAZY STUDENTS =’,C

     PRINT*,’THEIR GRADES ARE:’, (B(I),I=1,C)

     END

 

10           10.     2-D ARRAY

          A two dimensional array gives a tabular representation of data consisting of rows and columns.  It is declared in the form:

TYPE aname1(m, n),   OR

TYPE aname2(m1:m2, n1:n2)

where in the first case, m is the number or rows (1...m) and n the number of columns (1..n).  In the second case, the rows have subscripts m1, m1+1, .., m2 and columns have subscripts n1, n1+1, …, n2.

Example:  INTEGER MAT(3,5)

          CHARACTER CITIES(4,5)*15

          REAL SURVEY(1990:1999, 6:12)

 

The DIMENSION statement can also be used to declare 2-D array.  In this case, implicit declaration is assumed unless, the type is declared explicitly.

 

Example:  DIMENSION X(10,10), M(5,7), Y(4,4)

          INTEGER X

          REAL M

 

In this example, arrays X and Y are of type real, while array M is of type integer.

 

10.2     INITIALISATION OF 2-D ARRAY.

2-D array can be initialized using assignment statement or using READ statement.  The initialization can be row-wise or column-wise.

 

Example1:  Declare a 2-D integer array ID of 3 rows, and 3 columns and initialize it row-wise as identity matrix.

 

Solution:  INTEGER ID(3,3), ROW, COL

     DO 17 ROW=1, 3

              DO 17 COL =1,3

                   IF (ROW .EQ. COL) THEN

                        ID(ROW,COL)=1

                   ELSE

                        ID(ROW,COL)=0

                   ENDIF

17   CONTINUE

 

Notice that the index of the outer loop is row, which is also the row subscript of the array ID.  To initialize the array column-wise, we simply interchange the inner and the outer loops.

 

Example 2:  Declare a real array X consisting of 2 rows and 3 columns and initialize it column wise.  Each element should be initialized with its row number.

 

Solution:  REAL X(2,3)

          INTEGER J,K

          DO 27 J=1,3

              DO 27 K=1,3

                   X(K,J)=K

27   CONTINUE

 

We can also read values into a 2-D array.  This can be in whole by using the array name.  In this case, the input data is assumed to be column-wise.  We can also use subscripts to read row-wise or column-wise, part of the array or the whole array.

 

Example 3:  Read all the elements of a 3x3 integer array MATRIX, column-wise

 

Solution 1:  Without subscripts S                 Solution2:   Using Implied loop

     INTEGER MATRIX(3,3)              INTEGER MATRIX(3,3),J,K

     READ*, MATRIX                    READ*, ((MATRIX(K,J),K=1,3),J=1,3)

 

Solution3:   Using DO loop

     INTEGER MATRIX(3,3),J,K

     DO 28 J=1,3

          READ*, (MATRIX(K,J),K=1,3)

28   CONTINUE

 

Example 4:  Read all the elements of an integer array X of size 3x5 row-wise

 

Solution 1:  Using Implied loop                    Solution 2:  Using DO loop

     INTEGER X(3,5),J,K                    INTEGER X(3,5),J,K

     READ*, ((X(K,J), J=1,5), K=1,3)       DO 33 K=1,3

                                                READ*, (X(K,J),J=1,5)

                                      33   CONTINUE

 

10.3   PRINTING 2-D ARRAY

As with reading, we can print the entire array by using the array name.  In this case, the printing is done column-wise on one line.  We can also print individual elements either row-wise or column-wise by specifying the subscripts.  

 

Example:    Read a 3x3 integer array WHT column-wise and print:

(i)                  The entire array row-wise in one line

(ii)                The entire array column-wise in one line

(iii)               One row per line

(iv)              One column per line

(v)                The sum of column 3

 

INTEGER WHT(3,3),SUM,I,J

READ*, WHT

PRINT*, ’PRINTING ROW-WISE’

PRINT*, ((WHT(I,J), J=1,3), I=1,3)

PRINT*, ’PRINTING COLUMN-WISE’

PRINT*, ((WHT(I,J), I=1,3), J=1,3)

PRINT*, ’PRINTING ONE ROW PER LINE’

     DO 5 I=1,3

          PRINT*, (WHT(I,J), J=1,3)

5    CONTINUE

     PRINT*, ’PRINTING ONE COLUMN PER LINE’

     DO 7 J=1,3

          PRINT*, (WHT(I,J), I=1,3)

7    CONTINUE

     SUM=0

     DO 9 I=1,3

          SUM = SUM+WHT(I,3)

9    CONTINUE

     END

 

10.4   PROGRAM EXAMPLES USING 2-D ARRAY

Example 1:  Write a program that reads a 3x3 array row-wise.  The program then finds the minimum element in the array and changes each element of the array by subtracting the minimum and then prints the updated array row-wise.

 

Solution:

INTEGER A(3,3), I,J,MIN

READ*, ((A(I,J), J=1,3), I=1,3)

MIN=A(1,1)

DO 10 I=1,3

          DO 10 J=1,3

              IF (A(I,J) .LT. MIN) MIN=A(I,J)

10   CONTINUE

DO 20 I=1,3

          DO 10 J=1,3

              A(I,J)=A(I,J)-MIN

20   CONTINUE

     PRINT*, ((A(I,J),J=1,3),I=1,3)

     END

Example 2:  Write a program that reads the ID-NUMBERS and GRADES of 30 students into 30x2  2-D integer array, row-wise.  Then program then computes the average grade and prints the IDs of those students blow the average.

 

INTEGER RESULT(30,2),I,J,SUM

REAL AVG

     PRINT*, ’ENTER IDs AND GRADES ROW-WISE’

     DO 10 I=1,30

          READ*, (RESULT(I,J),J=1,2)

10   CONTINUE

     SUM=0

     DO 20 I=1,30

          SUM=SUM+RESULT(I,2)

20   CONTINUE

     AVG=SUM/30.0

     PRINT*, ’THE AVERAGE GRADE=’,AVG

     PRINT*, ’THOSE BELOW AVERAGE ARE:’

     DO 30 I=1,30

          IF (RESULT(I,2) .LT. AVG) PRINT*, RESULT(I,1)

30   CONTINUE

     END

 

10.5   2-D ARRAY IN SUBPROGRAMS

2-D arrays can be used locally in a subroutine or passed as arguments to a subroutine.  However, even though it is allowed to pass variable 2-D arrays as arguments to a subroutine, it is not recommended to do that as it could lead to inefficient programs.

 

Example 1:  Read a 3x2 integer array MAT row-wise.  Using a function COUNT, count the number of zero elements in MAT.

 

     INTEGER MAT(3,2), COUNT, I,J

     READ*, (MAT(I,J),J=1,2),I=1,3)

     PRINT*, ’COUNT OF ZERO ELEMENTS = ’,COUNT(MAT)

     END

 

     INTEGER FUNCTION COUNT(MAT)

     INTEGER MAT(3,2),J,K

     COUNT=0

     DO 77 I=1,3

          DO 77 J=1,2

              IF (MAT(I,J) .EQ. 0) COUNT=COUNT+1

77   CONTINUE

     RETURN

     END

 

Example 2:  Write a subroutine ADDMAT that receives two 4x4 arrays, A and B and returns the result of adding the two arrays in another array C of same size.  Write a main program to test the subroutine.

 

     SUBROUTINE ADDMAT (A,B,C), I,J

     INTEGER A(4,4),B(4,4),C(4,4),I,J

     DO 10 I=1, 4

          DO 10 J=1,4

              C(I,J)=A(I,J)+B(I,J)

10   CONTINUE

     RETURN

     END

   INTEGER A(4,4),B(4,4),C(4,4),I,J

   PRINT*, ’ENTER VALUES FOR A’

   READ*, A

   PRINT*, ’ENTER VALUES FOR RRAY B’

   READ*, B

   CALL ADDMAT(A,B,C)

   PRINT*, ’A+B=’,C

   END

 

11.     OUTPUT FORMATTING

The PRINT statement we have been using so far is used for unformatted or list-directed output.  In this case, the appearance of the output is determined by the parameters being printed.  However, there are situation where we would want to control the precise appearance of the output.  For example, in generating a table involving real numbers as shown below.

 

1995    12.75

1996   125.50

1997     2.50

1998  3516.01

 

To control the manner in which the output is printed, we declare a FORMAT statement and then replace the “*” in the PRINT statement with the label of the FORMAT statement as shown below:

 

K       FORMAT (specification list)

          PRINT K, expression list

 

The expression list in the PRINT statement is printed according to the specification list in the FORMAT statement.

 

The FORMAT statement is a non-executable statement and can appear before or after the associated PRINT statement.   Each PRINT statement can have its own FORMAT statement and a number of PRINT statements can use the same FORMAT statement.

 

The specification list in the FORMAT statement determines how the output will appear both vertically and horizontally.  Thus it consists of a vertical specification and horizontal specifications.

 

11.1   VERTICAL SPECIFICATION:

          The first character in the specification list is used to determine the vertical appearance of the output.  The following table shows the characters used for vertical specification.

Character

Usage

’ ’

(Single Space), start printing on the next line

’0’

(double space), skip one line then start printing

’-’

(triple space), skip two lines then start printing

’+’

(no space), start printing on the current line

’1’

(next page), Move to the top of next page and start printing

 

11.2     HORIZONTAL SPECIFICATIONS:

There are six horizontal specifications. These are for Integer, Real, Character, Logical, Blanks and Literals.

 

11.2.1           Integer Specification:  This is used to specify how integer expressions should be printed.  It has the form Iw          where w is a number describing the width to be used in printing the number.  To determine the minimum width required, we count the number of digits in the number including the minus sign.  If w is greater than the actual size of the number, spaces are added to the left of the number to make the size of the output equal to w.  If w is less than the actual size, then w asterisks are printed instead of the number.

 

Example 1  The following table shows the minimum I specification required to print the numbers:

Number

Minimum I specification

345

I3

67

I2

-57

I3

1000

I4

123456

I6

Example 2:  The following shows FORMAT specifications and the output they generate:

INTEGER M

M=-356

PRINT 10, M

10   FORMAT (’ ’,I4)

 

     INTEGER K,M

     M=-244

     K=12

     PRINT 30,K

     PRINT 35,M

     PRINT 40,K,M

30   FORMAT(’ ’,I3)

35   FORMAT(’ ’,I7)

40   FORMAT(’ ’,I5,I6)

     PRINT 20, -345

     PRINT 30, -345

     PRINT 40, -345

20   FORMAT(’ ’,I7)

30   FORMAT(’0’,I7)

40   FORMAT(’+’,I7)

----+----1----+----2

-356

 

----+----1----+----2

***

     12

 -244    12

----+----1----+----2

   -345

 

   -345   -345

 

11.2.2    FLOAT (REAL) SPECIFICATION

This is used to specify how real expressions should be printed.  It has the form:  Fw.d, where w is the width to be used in printing the expression including decimal point and minus sign.  d is the number of digits to be printed after the decimal point.  If w is larger than required, spaces are added to the left of the number to complete the size to w.  If w is less than required, asterisks are printed.  If d is larger than required, zeros are added to the right of the number.  If d is less than required, the number is rounded to d decimal places.

 

Example: Suppose X=31.286, the table below shows the output if X is printed with the corresponding FORTMAT statements:

FORMAT

OUTPUT

----+----1----+

FORMAT

OUTPUT

----+----1----+

FORMAT(’ ’,F6.3)

31.286

FORMAT(’ ’,F6.2)

 31.29

FORMAT(’ ’,F8.3)

  31.286

FORMAT(’ ’,F7.4)

31.2860

FORMAT(’ ’,F5.3)

*****

FORMAT(’ ’,F6.4)

******

 

11.2.3    CHARACTER SPECIFICATION

This is used to specify how character expressions should be printed.  It has the form Aw, where w is the width to be used in printing the character expression.  If the expression has more than w characters, only the left-most characters are printed.  If the expression has fewer than w characters, spaces are added to the left.

 

Example:  The table below shows the output if the string ’ICS-101’ is printed with the following FORMAT statements:

FORMAT(’ ’,A7)

FORMAT(’ ’,A4)

FORMAT(’ ’,A10)

----+----1----+

ICS-101

----+----1----+

ICS-

----+----1----+

   ICS-101

 

11.2.4    LOGICAL SPECIFICATION

This is used to specify how logical expressions are printed.  It has the form Lw, where w is the width.  The letter T or F is printed if the expression is true of false respectively.  If w is more than 1, spaces are added to the left.

 

Example:  The table below shows the output if .TRUE. is printed with the FORMAT statements.

FORMAT(’ ’,L1)

FORMAT(’ ’,L5)

----+----1----+

T

----+----1----+

    L

 

11.2.5    BLANK (X) SPECIFICATION

This is used to insert blanks between values being printed.  The format is nX, where n is a positive integer representing the number of blanks.

 

Example:  Assume that A=-3.62 and B=12.5, then the following table shows the output if A and B are printed with the corresponding FORMAT statements.

FORMAT(’ ’,F5.2,F4.1)

FORMAT(’ ’,F5.2, 3X, F4.1)

----+----1----+

-3.6212.5

----+----1----+

-3.62   12.5

 

Note:  The X specification can also be used to replace the blank (vertical) control character.  For example, the following Format statements are equivalent: FORMAT(’ ’,I2) & FORMAT(1X,I2)

 

11.2.6    LITERAL SPECIFICATION:

This is used to place character string in a FORMAT statement.

Example:  Consider the following program:

REAL AVG

AVG=65.2

PRINT 5, AVG

5   FORMAT(’ ’, ’THE AVERAGE = ’, F4.1)

 

The output of the program is:     THE AVERAGE = 65.2

 

11.3         SPECIFICATION REPETITION:

If we have consecutive identical specifications, we can represent them as multiple specification.  For example, the following pairs of FORMAT statements are equivalent.

10   FORMAT(’0’,3X,I2,3X,I2

10   FORMAT(’0’,2(3X,I2))

20   FORMAT(’ ’,F5.1,F5.1,F5.1,5X,I3,5X,I3

    C         5X,I3,5X,I3)

20   FORMAT(’ ’,3F5.1,4(5X,I3))

 

12.     FILE PROCESSING

The programs we have written so far, relied on the user to enter the input data using the Keyboard, and the output is sent to the Screen.  However, there are many applications where the amount of data is so much that providing it using the keyboard each time the program is executed is not efficient.  Similarly, the output generated by many applications, is more than a screen full. In such applications, we need another way of handling input and output.  This is achieved using files.  That is, a program can read its input from a data file and also send output to an output file.

 

12.1   OPENING FILES

Before a file can be used for input or output, it must be opened using the OPEN statement.  This has the form:         

OPEN(UNIT=integer expression, FILE=’filename’,  STATUS=’file status’)

Where:  The integer expression is any integer in the range 0…99 (except 5 and 6 which are used by the system to refer to Keyboard and Screen). Each file used in a program must have a unique UNIT number. 

Filename refers to the actual name of the file.  If the file is being used for input, then it must already exist on the computer before the program is executed.  However, if the file is being used for output, then it may or may not exist.  If it does not exist, the program creates it.  If it exists, the program deletes its current content before writing into it. 

          File Status can be OLD, NEW, or UNKNOWN.  If the file is being used for input, the status should be OLD.  If it is being used for output, then it can be set as NEW if the file does not exist. However, it is safer to use UNKNOWN which will work whether the file exist or not.  If a file exists and NEW is used, an error will result.

 

Example 1:  The following OPEN statements open the file POINTS.DAT for input and the file  RESULTS.DAT for output.

     OPEN(UNIT=2, FILE=’POINTS.DAT’,STATUS=’OLD’)

     OPEN(UNIT=3, FILE=’RESULTS.DAT’,STATUS=’UNKNOWN’)

12.2   READING FROM INPUT FILE:

After opening a file for input, we can read data from it just as we read data from keyboard.  The only difference is that we have to specify the unit number of the file we are reading from.  Thus, the READ statement is modified as follows:  READ (UNIT,*) list of variables

 

Example 1:  Read three exam grades from a file EXAM.DAT and print their sum.

    INTEGER G1,G2,G3,SUM

    OPEN (UNIT=10, FILE=’EXAM.DAT’,STATUS=’OLD’)

    READ (10,*) G1,G2,G3

    SUM=G1+G2+G3

    PRINT*, SUM

     END

In many cases, the number of data values in a file is not known.  In this case, we used the following version of the READ statement:              READ (UNIT, *, END=N) list of variables

This is a conditional READ statement.  If the end of file is not reached, we read values for the list of variables from the file, but if the end of file is reached, control goes to the statement labeled N.

 

Example2:  Find the average of real numbers that are stored in the file NUMS.DAT.  Assume that we do not know how many values are in the file and that every value is stored on a separate line.

     REAL NUM,SUM,AVG

     INTEGER COUNT

     OPEN (UNIT=12,FILE=’NUMS.DAT’,STATUS=’OLD’)

     SUM=0.0

     COUNT=0

333  READ (12,*,END=999) NUM

          SUM=SUM+NUM

          COUNT=COUNT+1

          GOTO 333

999  AVG=SUM/COUNT

     PRINT*, AVG

     END

 

12.3   WRITING TO FILES

After opening a file for output, we can write data into it using WRITE statement which has the following form:                  WRITE (UNIT, *) expression list

UNIT is a number identifying the file. The * can be replaced by a format statement label number.

 

Example 1:  Create an output file CUBES.DAT that contains the table of cubes of integers 1 to 20.

    INTEGER NUM

    OPEN (UNIT=20, FILE=’CUBES.DAT’,STATUS=’UNKNOWN’)

    DO 22 NUM=1,20

         WRITE(20,*) NUM,NUM**3

22         CONTINUE

END

 

Example 2:  Create an output file THIRD that contains the values of FIRST followed by values of SECOND.  Assume that we do not know the number of values in FIRST and SECOND and that every line contains one integer value.

     INTEGER NUM

     OPEN (UNIT=15, FILE=’FIRST’, STATUS=’OLD’)

     OPEN (UNIT=17, FILE=’SECOND’, STATUS=’OLD’)

     OPEN (UNIT=19, FILE=’THIRD’, STATUS=’UNKNOWN’)

111  READ (15,*, END=222) NUM

          WRITE(19, *),NUM

          GOTO 111

222  READ (17, *, END=333) NUM

          WRITE(19, *) NUM

          GOTO 222

333  END

12.4   CLOSING FILES AND REWINDING FILES

CLOSING:  If a program uses files for Input and/or Output, the operating system automatically closes all the files that are used at the end of program execution.  However, there are cases we may need to read data from a file more than one time in a single program.  This can be achieved by closing the file after the first reading and then re-opening it for the second read.  There are also cases where we may want to read from a file created by our program (initially opened for output).  In this case, the file has to be closed and the re-opened for input.  The format of the CLOSE statement is:

CLOSE (unit)

 

 REWINDING: After reading from a file, the reading head moves forward towards the end of the file.  If we need to start reading from the beginning again in a single program, then instead of closing and opening the file the second time, it is more efficient to use the REWIND statement.  This moves the reading head to the beginning of the file.  Its format is:           REWIND(unit)

 

13.    APPLICATION DEVELOPMENT:

Real life problems are usually complex, involving many tasks that they cannot be solved using few lines of program code as we have done so far.  This chapter is aimed at teaching us how to handle big applications.  First however, we shall learn two basic data processing techniques, namely, sorting and searching.

 

13.1   SORTING:

This is the process of rearranging a list of items into either ascending or descending order.  There are many techniques developed by computer scientist, here we present a simple one.

We first find the minimum (or maximum) element and interchange it with the first element.  We then find the next smallest from the remaining elements and exchange it with the second element.  We repeat this process with the remaining elements until eventually the list is sorted.  The following subroutine implements this technique.


    SUBROUTINE SORT (A,N)

     INTEGER N, A(N), TEMP, K, L

     DO 11 K=1, N-1

          DO 11 L=K+1, N

                IF(A(K).GT.A(L)) THEN

                     TEMP=A(K)

                     A(K)=A(L)

                     A(L)=TEMP

                ENDIF

11   CONTINUE

     RETURN

     END

The following table shows how the subroutine work when sorting an array of five elements:

 

3, -2, 4, 9, 0

After Round 1

-2

3

4

9

0

After Round 2

-2

0

4

9

3

After Round 3

-2

0

3

9

4

After Round 4

-2

0

3

4

9

 


 

13.2   SEARCHING:

This is the process of determining whether or not, an item is in a given list of items.  There are again many searching techniques, the simplest being the Sequential Search.  The following function implements sequential search.  It returns the index of the element if it exists, else it returns zero.

INTEGER FUNCTION SEARCH (A,N,K)

     INTEGER N, A(N), K,J

     LOGICAL FOUND

     SEARCH=0

     J=1

FOUND=.FALSE.

     DO WHILE (.NOT. FOUND .AND. J .LE. N)

          IF (A(J) .EQ. K) THEN

                FOUND = .TRUE.

                SEARCH=J

          ELSE

                J=J+1

          ENDIF

     END DO

     RETURN

     END

 

1.3       AN APPLICATION (GRADES MAINTENANCE SYSTEM)

Write a program that reads IDs of 20 students and their grades in two 1-D arrays, ID and GRADES row-wise.  The program should allow the following operations interactively through a menu system.

1.       Sort according to ID

2.       Sort according to grades

3.       Change a grade

4.       Exit the program.

 

Solution:  We first write a subroutine MENU that displays the various options after entering the data.  The subroutine should return the option chosen by the user.


     SUBROUTINE MENU (OPTION)

     INTEGER OPTION

     PRINT*, ’GRADES MAINTENANCE SYSTEM’

     PRINT*, ’1. SORT ACCORDING TO ID’

     PRINT*, ’2. SORT ACCORDING TO GRADE’

     PRINT*, ’3. CHANGE GRADE’

     PRINT*, ’4. EXIT THIS PROGRAM’

     PRINT*, ’ENTER YOUR CHOICE’

READ*, OPTION

RETURN

END

 

We can use the function SEARCH written earlier to check that a student exist before we change his grade.  However, we need to modify the SORT subroutine such that as we sort one of the arrays, we also update the other so that we don’t assign wrong grades to students while sorting.  This can be done as shown on the right.

     SUBROUTINE TSORT(A,B,N)

     INTEGER N,A(N),B(N),TEMP,J,K,L

     DO 11 K=1, N-1

          DO 11 K=K+1, N

                IF (A(K).GT.A(L)) THEN

                     TEMP = A(L)

                     A(K)=A(L)

                     A(L)=TEMP

                     TEMP = B(L)

                     B(K)=B(L)

                     B(L)=TEMP

                ENDIF

11   CONTINUE

     PRINT*, ’SORTED DATA: ’

     DO 22 J=1, N

          PRINT*, A(J), B(J)

22   CONTINUE

     RETURN

     END

 


 

Using these subprograms, the Main program can be written as follows:

 

     INTEGER GRADES(20), ID(20), SEARCH, SID, NGRADE, OPTION, K,N

     PRINT*, ’ENTER NUMBER OF STUDENTS’

     READ*, N

     DO 10 K=1, N

          PRINT*, ’ENTER ID AND GRADE FOR NEXT STUDENT’

          READ*, ID(K), GRADES(K)

10   CONTINUE

     CALL MENU(OPTION)

     DO WHILE(OPTION .NE. 4)

          IF (OPTION .EQ. 1) THEN

                CALL TSORT(ID, GRADES, N)

          ELSEIF (OPTION .EQ. 2) THEN

                CALL TSORT(GRADES, ID, N)

          ELSEIF (OPTION .EQ. 3) THEN

                PRINT*, ’ENTER ID AND THE NEW GRADE’

                READ*, SID,NGRADE

                K=SEARCH(ID,N,SID)

                IF (K .NE. 0) THEN

                     GRADES(K)=NGRADE

                ELSE

                     PRINT*, ’ID:’,SID, ’NOT FOUND’

                ENDIF

          ELSE

                PRINT*, ’INPUT ERROR’

          ENDIF

          CALL MENU(OPTION)

     END DO

     END