0% found this document useful (0 votes)
65 views34 pages

Programming in FORTRAN95: Thomas Kalscheuer 24. January 2008

This document provides a summary of structured programming concepts in FORTRAN95 including: 1) Decision statements such as IF-THEN-ELSE constructs and SELECT CASE constructs. 2) Loops such as DO loops, DO WHILE loops, and EXIT/CYCLE commands. 3) Internal subprograms like FUNCTIONS and SUBROUTINES that allow code reusability.

Uploaded by

Kurnia Angga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
65 views34 pages

Programming in FORTRAN95: Thomas Kalscheuer 24. January 2008

This document provides a summary of structured programming concepts in FORTRAN95 including: 1) Decision statements such as IF-THEN-ELSE constructs and SELECT CASE constructs. 2) Loops such as DO loops, DO WHILE loops, and EXIT/CYCLE commands. 3) Internal subprograms like FUNCTIONS and SUBROUTINES that allow code reusability.

Uploaded by

Kurnia Angga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 34

Programming in FORTRAN95

Lecture III
Thomas Kalscheuer

24. January 2008

Uppsala universitet Page 1


1 – Structured programming - Part 1
Structured programming - Part 1
Old sins ...
Go To Statement Considered Harmful
- Edsger W. Dijkstra -

In the old Fortran standards, i.e. Fortran 77 and before, constructs of


the type
if (scalar-logical-expression) goto label1
..
label1 continue
or
label2 continue
..
if (scalar-logical-expression) goto label2

were used to jump from an if-statement to an arbitrary position in a


program. Nested if-goto-statement are very often extremely hard to
read and make a program difficult to maintain and unstructured.

Do never ever use goto and continue in your


programs!
Decision statements
There is no programming language, no matter how structured,
that will prevent programmers from writing bad programs.
- L. Flon -

General form of an if construct:

[name:] if (scalar-logical-expression1) then


exec-block-1
[else if (scalar-logical-expression2) then [name]
exec-block-2 ]
...
[else [name]
exec-block-e ]
end if [name]
Properties:

• The condition statements scalar-logical-expression1,


scalar-logical-expression2 etc. are evaluated one after the other
until one is true and the associated executable block (one of
exec-block-1, exec-block-2 etc. ) is executed. After that, control
passes to the first statement after end if.

• If no condition is fulfilled, no block is executed, unless there is a


final else clause.
In the scalar logical expression of the if statement and if construct the
following scalar relational operators can be used:

scalar relational meaning example of scalar


operator logical expression
.lt. or < less than i<0
.le. or <= less than or equal a .le. b
.eq. or == equal (i-j) .eq. (a-b)
.ne. or /= not equal a /= 0
.gt. or > greater than ((a+b)**2.0 - c) > 0
.ge. or >= greater than or equal i .ge. 0

Table 1: Scalar relational operators. Examples for integer numbers i,


j and real numbers a, b.
There are five logical operators which act on logical expressions:

logical precedence logical example


operator meaning
.not. 1 negation .not. (a == 0)
.and. 2 intersection (a>2) .and. (a<5)
.or. 3 union (a<=2) .or. (a>=5)
.eqv. 4 equivalence test_done .eqv. .true.
.neqv. 4 non- test_done .neqv. .true.
equivalence

Table 2: Logical operators. Examples for a real number a and a


logical variable test_done.
The exam example again (1st version):
Did the student pass the exam?
! written by Thomas Kalscheuer, 2/11/2005
! compile with: g95 -o exam_passed exam_passed.f90
!
! reads the percentage of correct exam answers
! given by a student and prints whether student
! passed the exam
program exam_passed

implicit none

! percentage of correct answers


real :: percentage
print *, "Enter percentage of correct answers:"
read *, percentage

if (percentage >= 50.0) then


print *, "The student passed the exam."
else
print *, "The student failed the exam."
end if

end program exam_passed


The exam example again (2nd version):
Did the student pass the exam and if so, with which mark did he
pass?
! written by Thomas Kalscheuer, 2/11/2005
! compile with: g95 -o exam_mark_if exam_mark_if.f90
!
! reads the percentage of correct exam answers
! given by a student and prints whether student
! passed the exam and with which mark.
program exam_mark_if

implicit none

! percentage of correct answers


real :: percentage

Uppsala universitet Page


1010
print *, "Enter percentage of correct answers:"
read *, percentage

if (percentage >= 90.0) then


print *, "The student passed with m.v.g."
else if ((percentage >= 75.0) .and. &
(percentage < 90.0)) then
print *, "The student passed with v.g."
else if ((percentage >= 50.0) .and. &
(percentage < 75.0)) then
print *, "The student passed with g."
else
print *, "The student failed the exam."
end if
end program exam_mark_if
General form of a case construct:
[name:] select case
(expression) [case selector
[name]
block ]
...
[case default [name]
block ]
end select
[name] Properties:
• case constructs allow a more readable way for branching than
the if construct, if a single expression is checked for
various values and value ranges.
• The default takes the place of the final else clause in an
if construct.
• Leading or trailing statements must either both be unnamed or
both bear he same name, case statement may be named only, if
the leading statement is named and must wear the same name.
• The expression expression must be of scalar logical, integer or
character type. The specified values in each selector must be of
this type.
• The general form of a selector is a list of non-overlapping values
and ranges enclosed in parantheses:
– For a single value:
case (value)
– For a range:
case (low:high)
where only one of low or high must be present
– Example for an integer expression:
case (:1, 5, 7, 9:12, 16:)
– The selector must be a constant, not a variable.
The exam example again (3rd version with case construct):
Did the student pass the exam and if so, with which mark did he
pass?
! written by Thomas Kalscheuer, 2/11/2005
! compile with: g95 -o exam_mark_case exam_mark_case.f90
!
! reads the percentage of correct exam answers
! given by a student and prints whether student
! passed the exam and with which mark.
program exam_mark_case

implicit none

! percentage of correct answers


integer :: percentage
print *, "Enter percentage of correct answers:"
read *, percentage

det_mark: select case (percentage)


case (90:)
print *, "The student passed with m.v.g."
case (75:89)
print *, "The student passed with v.g."
case (50:74)
print *, "The student passed with g."
case (:49)
print *, "The student failed the exam."
end select det_mark

end program exam_mark_case


Loops
General form of a deterministic loop:
[name:] do var = expr1, expr2[, expr3]
[block]
end do
[name] Properties:
• Same as in lecture II but you are allowed to give your loops
names in order to produce easily readable code.
• The loop counter var is increased at the end of every loop
iteration for use in the following iteration.
• You may not modify the loop counter var inside the loop.
Example:
Summation of two square matrices A and B with N =10 elements via
two nested loops.

! matrix dimension
integer, parameter :: N = 10
! matrices
real, dimension(1:N,1:N) :: A, B, C

column_loop: do j = 1:N
row_loop: do i = 1:N
C(i,j) = A(i,j) + B(i,j)
end do row_loop
end do column_loop
General form of a non-deterministic loop:
[name:] do
block
if (scalar-logic-expression) exit [name]
block
if (scalar-logic-expression) cycle [name]
block
end do
[name] Properties:
• The duration of the loop is not determined beforehand. So you
need to check inside the loop whether you want to exit it
completely or perhaps cycle.
• To exit means to skip the rest of the loop completely and jump to
the first executable statement after end do.

Uppsala universitet Page


2020
• To cycle means to skip the part of the current loop iteration that
comes after the cycle command.

• If the cycle or exit commands are used without loop


names they refer to the innermost loop.
General form of a do while loop:

[name:] do while (scalar-logical-expression)


block
end do

[name] Properties:

• The do while loop is only entered, if scalar-logical-expression is


fulfilled.

• If scalar-logical-expression is not fulfilled at the beginning of a loop


iteration, the loop is terminated at this point.
Internal subprograms
General form of a program (bracketed parts are optional):
[program program_name]
[declaration statements]
[executable statements]
[contains
internal subprograms]
end [ program [program_name]]
• Internal subprograms are preceeded by a contains statement
in the host (main program) and they are functions and
subroutines.
• Functions and subroutines are particularly useful when the same
piece of code e.g. a long arithmetic expression or a block of code
is evaluated repeatedly.
General form of internal subprograms:
function function_name ([dummy-argument-list])
[declaration statements]
[executable statements]
end function [function_name]

Functions are called with their function name in expressions or


assignments.
subroutine subroutine_name [([dummy-argument-list])]
[declaration statements]
[executable statements]
end subroutine [subroutine_name]

Subroutines are called with the call

keyword.
Arguments of subprograms:
• The dummy arguments listed in dummy-argument-list, i.e.
defined in the header of an internal subprogram, must have the
same type as the actual arguments which are used when the
internal subprogram is called from the main program.
• Dummy arguments and function names must be formally
declared in the declaration statements of the internal subprogram.
• The variable names of dummy arguments (in the internal
subprogram) and actual arguments (in the main program) may
differ.
• The result of the function is returned as function_name to the
main program.
• If a dummy argument is modified in a internal subprogram so is
its actual argument upon return from the internal subprogram
(given the argument intent permits it.)
Argument intent:

• Imagine you have a very long list of dummy arguments. In


order not to loose your head you may wish to group them into
the following groups:
– input variables: only their values need to be known and they
are not modified in the subprogram.
– output variables: those variables to which values are
assigned in the subprogram. Their original values from the
main program are not used in the subprogram.
– input/output variables: Their original values from the main
program are used in the subprogram and they are modified
in the subprogram.
• The corresponding argument intents are in, out and inout.
• The specification of dummy argument intents is an important
element of structured programming.
Examples:
a) sum of array elements
! written by Thomas Kalscheuer, 1/11/2005
! compile with: g95 -o sum_array sum_array.f90
!
! sums all elements of an array
program sum_array

implicit none

! array dimension
integer, parameter :: n = 5
! array
real, dimension(1:n) :: x
! total sum of array elements
real :: total_sum

write (*, fmt = ’(a)’, advance = ’no’) &


"Enter array (5 elements): "
read *, x

total_sum = total(x, n)
print *, "Sum is: ", total_sum

contains

!----------------------------------------------
function total(x, n)
! input variables
! array of real numbers
real, intent(in), dimension(:) :: x
! number of array elements
integer, intent(in) :: n

! output variables
! sum of array elements
real :: total

! local variable
! counter
integer :: i

total = 0.0
do i = 1,n
Uppsala universitet Page
3030
total = total + x(i)
end do

end function total


!----------------------------------------------

end program sum_array


b) rotation of a 2D vector
! written by Thomas Kalscheuer, 1/11/2005
! compile with: g95 -o rotation rotation.f90
!
! rotates a 2D vector by a given angle
program rotation

implicit none
! 2D vectors
real, dimension(1:2) :: x_old, x_new
! angle of rotation
real :: alpha

write (*, fmt = ’(a)’, advance = ’no’) &


"Enter 2D vector: "
read *, x_old
write (*, fmt = ’(a)’, advance = ’no’) &
"Enter angle of rotation: "
read *, alpha

call rotate_2D_vector(x_old, alpha, x_new)

print *, "Rotated 2D vector: ", x_new


contains

!----------------------------------------------
! subroutine rotate_2D_vector rotates a 2D
! vector v_old by a given angle beta. The
! result is returned in v_new.
subroutine rotate_2D_vector(v_old, beta, v_new)

! input variables
! vector to be rotated
real, intent(in), dimension(1:2) :: v_old
! angle of rotation
real, intent(in) :: beta

! output variables
! rotated vector
real, intent(out), dimension(1:2) :: v_new

! local variables
! constant pi
real, parameter :: pi=3.14159265358979323846

v_new(1) = v_old(1)*cos(beta*pi/180.0) + &


v_old(2)*sin(beta*pi/180.0)
v_new(2) = -v_old(1)*sin(beta*pi/180.0) + &
v_old(2)*cos(beta*pi/180.0)

end subroutine rotate_2D_vector


!----------------------------------------------

end program rotation

You might also like