43
Functions

Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Embed Size (px)

Citation preview

Page 1: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Functions

Page 2: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Program complexity

• the more complicated our programs get, the more difficult they are to develop and debug.

• It is easier to write short algorithms and short programs and easier to debug them.

• We will now start to develop ways of reducing program complexity, by breaking problems down into manageable chunks.

Page 3: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Subprograms

• A subprogram is a small program unit that is dedicated to performing a particular task.

• It is not part of the main program, but…

• It is called by the main program when needed.

• There are two types of subprograms– functions– subroutines

Page 4: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Intrinsic functions

• An intrinsic function is one that is built in to the language.

• Examples we have used include SQRT, ABS, REAL, SIN

• There are many others

• Most are mathematical (see pages 324-325)

Page 5: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Why we need functions

• Rather than having to write the FORTRAN code to compute the square root of a number, it is easier and probably more accurate, to call upon the intrinsic SQRT function that has been written for us.

• PRINT*, The square root of “, num, “is: “, SQRT(num)

Page 6: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

What about missing functions

• In our last lab we needed to compute the factorial of each of a series of integers.

• It would have been very convenient if a function already existed to do this!– Kfact = FACTORIAL(k)

• Unfortunately it doesn’t

Page 7: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Good news/bad news

• The good news is that we can create our own functions so that eventually we could write program statements like this:– Kfact = FACTORIAL(k)

• The bad news is that it means we must write a program to do the needed computations.

• However, once the function has been written, we can call it whenever we want.

Page 8: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Programmer-defined functions

• A programmer-defined function is one which the programmer has produced (like the FACTORIAL example.)

• The f90 name for these are ‘Function Subprograms’

Page 9: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

What a function does

• a function performs a set of operations on the data that is passed in to it.

• When the operations are finished, the function sends the result back to the calling program segment

Page 10: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Function structure

• function heading

• specification section

• execution section

• END FUNCTION

Page 11: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Function headings

• start with keyword FUNCTION

• then lists the ‘formal arguments’

• formal arguments are the names the function will use for data that is coming in to the function from the calling program.

• The variable names do not have to match the names of the ‘actual arguments’ used by the calling program.

Page 12: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Specification section

• declare variables that are used in the function

• must also declare the data type for the formal arguments

• should also declare the INTENT of the arguments– IN (data sent in only, ‘passed by value’)– OUT (data sent out only)– INOUT (data sent in and out, ‘passed by reference

(address)’

Page 13: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Execution section

• normal FORTRAN commands for processing the variables that are available to the function.

• Important: functions return a value to the main program so don’t forget to set the variable containing that value.

Page 14: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

END FUNCTION

• This statement is followed by the name of the variable whose value will be sent back to the calling program after the function is over.

Page 15: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Where functions go

• Function subprograms can be placed in one of three locations– Just before the END PROGRAM statement

(internal subprogram)– In a module which can be imported into the

program (module subprogram)– After the END PROGRAM statement (external

subprogram)

• Text examples are all internal subprograms.

Page 16: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Internal subprograms

• placed in a special subprogram section of the main program– at the end– under the heading CONTAINS

• the main program is called the ‘host’

Page 17: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Program structure

comments

specification

execution section

function

END PROGRAM Poisson_Probability

PROGRAM Poisson_Probability

FUNCTION factorial(N)

END FUNCTION factorial

CONTAINS

.../factorial(N)

Page 18: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Actual and formal arguments

• The most confusing thing about functions is how the data gets into them and what goes back.

• The main program puts actual data into a function when it calls it– PRINT*, SQRT(num), ABS(-5), MOD(14, a)

• The actual arguments are then matched up with the formal arguments in the function heading

Page 19: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Actual and formal arguments

• Must match in terms of data type and size

• The names do not need to match.

• This is because a function is a generic program segment. It is designed to take any data that is of the right type and size.

• This makes it useful in many settings, not just a single one.

Page 20: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Arguments match in type, size and name

PROGRAM FactDemo

CONTAINS

PRINT*, n, ‘factorial is’, factorial(n)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

actual argument

formal argument

Page 21: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Arguments match in type and size, but not name

PROGRAM FactDemo

CONTAINS

PRINT*, num, ‘factorial is’, factorial(num)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

actual argument

formal argument

Page 22: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Function names

• Functions return data values

• Therefore, they must have a data type– INTEGER, REAL, CHARACTER, LOGICAL

• The function name is typed in the body of the function (see next slide)

• The value associated with the function name is then returned to the calling program when the function ends.

Page 23: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

The function name is declared (assigned a data type)

PROGRAM FactDemo

CONTAINS

PRINT*, num, ‘factorial is’, factorial(num)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

Page 24: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

A value is assigned to the function name

PROGRAM FactDemo

CONTAINS

PRINT*, num, ‘factorial is’, factorial(num)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

Page 25: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

The value in the function name is returned to the main program

PROGRAM FactDemo

CONTAINS

PRINT*, num, ‘factorial is’, factorial(num)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

Page 26: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Assignment statement examplePROGRAM FactDemo

CONTAINS

nfact = factorial(num)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

Page 27: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Returning to main program

• Usually, only the value contained in the function name is returned to the main program.

• The purpose of functions is to perform one task on a set of given data and return the result.

• However, there are ways to return other things through the INTENT command. It is dangerous to do this however.

Page 28: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

INTENT

• Formal arguments are matched up with actual arguments in one of two ways – by value– by reference (address)

• The one that is chosen is stated in the INTENT clause of the declaration.

• It is important to pay attention to this.

Page 29: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

INTENT (IN) :: n

5Main program

Function subprogram.n is set to whatever numwas and will not be allowedto change anywhere in thefunction.

5

num

n

Page 30: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

no INTENT specified

5Main program

Function subprogram.n is set to whatever numwas and will be allowedto change anywhere in thefunction. If it changes, sowill num in the main program!

5

num

n

Page 31: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Pass by reference (address)INTENT (INOUT) :: n

5Main program

Function subprogram.Instead of making a copyof num, the function usesthe original and gives it thetemporary name n. So, if n is changed in thefunction, num changes inthe main program.

5

num

n

Page 32: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

The value in the function name is returned to the main program

PROGRAM FactDemo

CONTAINS

PRINT*, num, ‘factorial is’, factorial(num)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

Page 33: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Variable scope

• Scope refers to the extent to which a variable exists in a program

• Usually, variables exist only in the program segment in which they are declared.

• This is called ‘local scope’.

• For example, when this function is over and returns to the main program, local variable ‘i’ , and all other local variables cease to exist.

• i passes out of scope

Page 34: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

The value in the function name is returned to the main program

PROGRAM FactDemo

CONTAINS

PRINT*, num, ‘factorial is’, factorial(num)

FUNCTION factorial(n) INTEGER :: factorial, i INTEGER, INTENT(IN) :: n factorial = 1 DO i = 1, n factorial = factorial * i ENDDOEND FUNCTION factorial

END PROGRAM FactDemo

Page 35: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Fundamental principals of scope

• An item within a subprogram is not accessible outside of that subprogram

• Global variables are accessible everywhere in the program– these are the ones declared in the main program– DO NOT assign these within functions unless you have

passed them in through the formal arguments, otherwise your function is no longer truly independent of the main, and the effects of variable assignments become hard to predict.

Page 36: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

• PROGRAM Temperature_Conversion_1 • !-----------------------------------------------------------------------• ! Program to convert several Fahrenheit temperatures to the • ! corresponding Celsius temperatures. The function Fahr_to_Celsius • ! is used to perform the conversions. Identifiers used are: • ! Fahr_to_Celsius : internal function subprogram that converts• ! Fahrenheit temperatures to Celsius• ! FahrenheitTemp : a Fahrenheit temperature to be converted• ! CelsiusTemp : the corresponding Celsius temperature• ! Response : user response to "More data?" query• !• ! Input: FahrenheitTemp, Response• ! Output: CelsiusTemp• !-----------------------------------------------------------------------

Temperature conversion program

Page 37: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

• IMPLICIT NONE • REAL :: FahrenheitTemp, CelsiusTemp • CHARACTER(1) :: Response • DO • ! Get a Fahrenheit temperature • WRITE (*, '(1X, A)', ADVANCE = "NO") "Enter a Fahrenheit temperature: " • READ *, FahrenheitTemp • ! Use the function Fahr_to_Celsius to convert it to Celsius • CelsiusTemp = Fahr_to_Celsius(FahrenheitTemp) • ! Output the result • PRINT '(1X, 2(F6.2, A))', FahrenheitTemp, & • " in Fahrenheit is equivalent to ", CelsiusTemp, " in Celsius" • ! Check if more temperatures are to be converted • WRITE (*, '(/ 1X, A)', ADVANCE = "NO") & • "More temperatures to convert (Y or N)? " • READ *, Response • IF (Response /= "Y") EXIT • END DO

Main program

Page 38: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

• CONTAINS• • !- Fahr_To_Celsius --------------------------------------- • ! Function to convert a Fahrenheit temperature to Celsius • ! • ! Accepts: A temperature Temp in Fahrenheit • ! Returns: The corresponding Celsius temperature • !---------------------------------------------------------- • FUNCTION Fahr_to_Celsius(Temp) • REAL:: Fahr_to_Celsius • REAL, INTENT(IN) :: Temp • Fahr_to_Celsius = (Temp - 32.0) / 1.8 • END FUNCTION Fahr_to_Celsius• • END PROGRAM Temperature_Conversion_1

Conversion function

Page 39: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

• PROGRAM Poisson_Probability• !-----------------------------------------------------------------------• ! Program to calculate the Poisson probability function using the• ! function subprogram Poisson. Identifiers used are:• ! AveOccurs : average # of occurrences of phenomenon per time period• ! NumOccurs : number of occurrences in a time period• ! Probability : Poisson probability• ! NumProbs : number of probabilities to calculate• ! I : DO-loop control variable• ! Poisson : internal function subprogram to calculate Poisson Probability• ! Factorial : internal function subprogram to calculate factorials• !• ! Input: NumProbs and values for AveOccurs and NumOccurs• ! Output: Poisson probabilities• !-----------------------------------------------------------------------

Poisson program

Page 40: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

• IMPLICIT NONE REAL :: AveOccurs, Probability • INTEGER :: NumProbs, I, NumOccurs • PRINT *, "This program calculates Poisson probabilities." • WRITE (*, '(1X, A)', ADVANCE = "NO") &• "How many probabilities do you wish to calculate? " • READ *, NumProbs DO I = 1, NumProbs • WRITE (*, '(1X, A)', ADVANCE = "NO") &• "Enter average # of occurrences per time period: " • READ *, AveOccurs • WRITE (*, '(1X, A)', ADVANCE = "NO") &• "Enter # of occurrences for which to find probability: " • READ *, NumOccurs • Probability = Poisson(AveOccurs, NumOccurs) • PRINT '(1X, "Poisson probability = ", F6.4 /)', Probability • END DO

Main program

Page 41: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

• CONTAINS • !-Poisson ------------------------------------------------------------ • ! Function to calculate the Poisson probability • ! N -Lambda • ! Lambda * e • ! Poisson(N) = ------------------ • ! N! • ! Function Factorial is called to calculate N• ! • ! • ! Accepts: Real number Lambda and integer N • ! Returns: The poisson probability given by the formula above • !--------------------------------------------------------------------- • FUNCTION Poisson(Lambda, N) • REAL :: Poisson • REAL, INTENT(IN) :: Lambda • INTEGER, INTENT(IN) :: N • Poisson = (Lambda ** N * EXP(-Lambda)) / REAL(Factorial(N)) • END FUNCTION Poisson

Poisson function

Page 42: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

• !- Factorial --------------------------------------------------------- • ! Function to calculate the factorial N! of N which is 1 if N = 0, • ! 1 * 2 * . . . * N if N > 0. • ! • ! Accepts: Integer N • ! Returns: The integer N!• ! • ! Note: I is a local integer variable used as a counter. • !--------------------------------------------------------------------- • FUNCTION Factorial(N) • INTEGER, INTENT(IN) :: N • INTEGER :: Factorial, I • Factorial = 1 • DO I = 2, N • Factorial = Factorial * I • END DO • END FUNCTION Factorial

• END PROGRAM Poisson_Probability

Factorial function

Page 43: Functions. Program complexity the more complicated our programs get, the more difficult they are to develop and debug. It is easier to write short algorithms

Logical functionPROGRAM logical_functionLOGICAL :: OKINTEGER :: iDO i=1,10 IF (divby3(i)) THEN PRINT*, i, " is evenly divisible by 3." ENDIFENDDO

CONTAINS

FUNCTION divby3(num)LOGICAL :: divby3INTEGER, INTENT(IN) :: numIF (MOD(num,3) == 0) THEN divby3 = .true.ELSE divby3 = .false.ENDIFEND FUNCTION divby3

END PROGRAM logical_function