Chapter 3. Control Structures and Program Design ► Two broad categories of control statement: Branches Loops ► These will make the program more complex. To avoid programming errors, a formal program design procedure is needed, which is based on the technique known as top-down design.
► 3.1 Top-down design techniques program to be solved design an algorithm (step-by-step procedure) for finding solution substak pseudocode Fortan statement unit test each program final progam pseudocode Fortan statement Fortan statement Fortan statement Fortan statement unit test each program
► 3.2 Pseudocode and Flowcharts Stands forms to describe the algorithm Pseudocode: hybrid mixture of English & Fortran Flowchart: graphical description
► 3.3 Control Constructs: Branches Block IF construct Logical IF statement if (logical expression) then statement block end if logical expression statement block.false..true. if (logical expression) statement
ELSE and ELSE IF clauses if (logical expression 1) then statement block 1 else if (logical expression 2) then statement block 2 else statement block n end if logical expression 1 statement block 1.false..true. logical expression 2.false..true. statement block 2
Example using Block if: Solve ax 2 +bx+c=0 for x given a, b, and c. Design the algorithm: ► Read the input data a, b, and c ► Calculate the roots ► Write out the roots
Flowchart start read a, b, c echo a, b, c b**2-4.*a*c < 0b**2-4.*a*c = 0 write 'The equation has complex roots.' write 'The equation has two identical read roots.' write 'The equation has two distinct real roots.' calculate real_part, imag_part calcaulate x1calcaulate x1, x2 write real + i imag read – i imag write x1write x1, x2 stop.false..true.
progam roots ! Purpose: ! This program solves for the roots of a quadratic equation of the form ! a*x**2 + b*x + c = 0. It calculates the answers regardless of the type of ! roots that the equation possesses. implicit none ! Declare the variables used in this program real :: a ! Coefficient of x**2 term of equation real :: b ! Coefficient of x term of equation real :: c ! Constant term of equation real :: discriminant ! Discriminant of the equation real :: imag_part ! Imaginary part of equation (for complex roots) real :: real_part ! Real part of equation (for complex roots) real :: x1 ! First solution of equation (for real roots) real :: x2 ! First solution of equation (for real roots) ! Prompt the user for the coefficients of the equation write(*,*) 'This program solves for the roots of a quadratic ' write(*,*) 'equation of the form a*x**2 + b*x + c = 0. ' write(*,*) 'Enter the coefficients a, b, and c: ' read(*,*) a, b, c ! Echo back coefficients write(*,*) 'The coefficients a, b, and c are: ', a, b, c ! Calculate discriminant discriminant = b** *a*c >Continued on next page...
...< ! Solve for the roots, depending upon the value of the discriminant if (discriminant > 0.0) then x1 = (-b + sqrt(discriminant)) / (2.0*a) x2 = (-b - sqrt(discriminant)) / (2.0*a) write(*,*) 'This equation has two real roots:' write(*,*) 'x1 = ', x1 write(*,*) 'x2 = ', x2 else if (discriminant == 0.0) then x1 = (-b) / (2.0*a) write(*,*) 'This equation has two identical real roots:' write(*,*) 'x1 = x2 = ', x1 else ! there are complex roots, so... real_part = (-b) / (2.0*a) imag_part = sqrt(abs(discriminant)) / (2.0*a) write(*,*) 'This equation has complex roots:' write(*,*) 'x1 = ', real_part, ' +i ', imag_part write(*,*) 'x2 = ', real_part, ' -i ', imag_part end if end program
"Name" Block IF Constructs [name:] if (logical expression 1) then statement block 1 else if (logical expression 2) then [name] statement block 2 else [name] statement block n end if [name]
"Nested" Block IF Constructs A better program is: if (test 1) then statement block if (test 2) then statement block if (test 3) then statement block end if outer: if (test 1) then statement block middle: if (test 2) then statement block inner: if (test 3) then statement block end if inner end if middle end if outer
Example Using Block IF and Nested Block IF ► Block IF if (x > 95) then write(*,*) 'Grade is A' else if (x > 86) then write(*,*) 'Grade is B' else if (x > 76) then write(*,*) 'Grade is C' else if (x > 66) then write(*,*) 'Grade is D' else write(*,*) 'Grade is E' end if 95 < x A 86 < x ≤ 95 B 76 < x ≤ 86 C 66 < x ≤ 76 D 0 < x ≤ 66 0 < x ≤ 66E
► Nested Block IF aif: if (x > 95) then write(*,*) 'Grade is A' else aif bif: if (x > 86) then write(*,*) 'Grade is B' else bif cif: if (x > 76) then write(*,*) 'Grade is C' else cif dif: if (x > 66) then write(*,*) 'Grade is F' else dif write(*,*) 'Grade is F' end if dif end if cif end if bif end if aif
CASE construct [name:] select case (integer case_expression) case (case_selector_1) [name] statement block case (case_selector_2) [name] statement block... case default [name] statement block end select [name]
► 3.4 Control Constructs: Loops ► while loops ► iterative loops (counting loops) WHILE Loop do statement block if (logical_expression) exit statement block end do logical expression statement block.false..true. statement block do while (logical_expression) statement block end do logical expression statement block.false..true.
Examle: Recall in a set of numbers and calculate the mean and standard deviation of the data x<0 n=n+1 sum_x=sum_x+x sum_x2=sum_x2+x.false..true. read x x_bar = sum_x/n std_dev = sqrt((n*sum_x2-sum_x**2) / (n*(n-1))
progam stats_2 ! Purpose: ! To calculate mean and standard deviation of input data set ! containing an arbitrary number of input values. ! implicit none integer :: n = 0 ! The number of input samples real :: std_dev ! The standard deviation of the input samples real :: sum_x = 0 ! The sum of the input values real :: sum_x2 = 0 ! The sum of the squares of the input values real :: x = 0 ! An input data value real :: x_bar ! The average of the input samples ! While loop to read input values do ! Read in next value write(*,*) 'Enter number:' read(*,*) x write(*,*) 'The number is ', x ! Test of loop exit if (x < 0) exit ! Otherwise, accumulate sums n = n + 1 sum_x = sum_x + x sum_x2 = sum_x2 + x**2 end do >Continued on next page...
...< ! Check to see if we have enough input data if (n < 2) then write(*,*) 'At least 2 values must be entered!' else x_bar = sum_x / real(n) std_dev = sqrt((real(n)*sum_x2-sum_x**2)/(real(n)*real(n-1)) write(*,*) 'The mean of this data set is:', x_bar write(*,*) 'The standard deviation is: ', std_dev write(*,*) 'The number of data points is:', n end if end program
Iterative Loop (Counting loop) do index = istart, iend[, incr] statement block end do index*incr ≤ iend*incr statements.false..true. index = index+incr index=istart 1.istart, iend, incr can be contatns, variables or expression of integer. 2.If incr is not specified, incr=1.
progam stats_3 ! Purpose: ! To calculate mean and standard deviation of input data set, ! where each input value can be positive, negative or zero. ! implicit none integer :: i ! Loop index integer :: n = 0 ! The number of input samples real :: std_dev ! The standard deviation of the input samples real :: sum_x = 0 ! The sum of the input values real :: sum_x2 = 0 ! The sum of the squares of the input values real :: x = 0 ! An input data value real :: x_bar ! The average of the input samples ! Get the number of data to input write(*,*) 'Enter number of points: ' read(*,*) n ! Check to see if we have enough input data if (n < 2) then write(*,*) 'At least 2 values must be entered.' else ! Loop to read input values do i = 1, n write(*,*) 'Enter number: ' read(*,*) x write(*,*) 'The number is ', x sum_x = sum_x + x sum_x2 = sum_x2 + x**2 >Continued on next page...
...< ! Calculate statistics x_bar = sum_x / real(n) std_dev = sqrt((real(n)*sum_x2-sum_x**2)/(real(n)*real(n-1)) write(*,*) 'The mean of this data set is:', x_bar write(*,*) 'The standard deviation is: ', std_dev write(*,*) 'The number of data points is:', n end program
► Examples do i = 1, end do do i = 1, 10, 2... end do do i = 1, 10, end do do i = 3, -3, end do i = 1, 2, 3,..., 10 i = 1, 3, 5, 7, 9 Initially, 1*(-1) > 10*(-1) so exits i = 3, 1, -1, -3
Notes: do i = 1, 4... i = 2 end do do i = 1, 5... if (i >= 3) exit... end do do i = 1, end do goto 100 will produce infinite loops branch out of a do loop is ok but, branch into the loop is illegal
► CYCLE statement ► EXIT statement ► Nesting loops (loop within loop) do i = 1, 5 if (i == 3) cycle write(*,*) i end do do i = 1, 5 if (i == 3) exit write(*,*) i end do do i = 1, 3 do j = 1, 4 write(*,*) i, j end do the output will be 1, 2, 4, 5 the output will be 1,