7. Control Flow |
Overview
|
Note: These notes cover Chapter 6 of the textbook, except Sections 6.5.3, 6.6.2, and 6.7. You are not required to study Sections 6.5.3, 6.6.2, and 6.7. |
Ordering Program Execution: What is Done First?Categories for specifying ordering in programming languages:
|
Expression Evaluation
|
Operator Precedence Levels
|
Evaluation Order in Expressions
a:=B[i]; load a from memory c:=2*a+3*d; compute 3*d first, because waiting for a to arrive in processor a:=b+c; d:=c+e+b; rearranged as d:=b+c+e, it can be rewritten into d:=a+e |
Expression Reordering Problems
|
Short-Circuit Evaluation
if (unlikely_condition && expensive_condition()) ... ... i:=1; while i<=10 and a[i]<>0 do i:=i+1 |
Assignments
|
Assignments (cont'd)
|
Structured and Unstructured Flow
|
Sequencing
|
Selection
if (<expr>) <stmt> [else <stmt>] Condition is integer-valued expression. When it evaluates to 0, the else-clause statement is executed otherwise the then-clause statement is executed. If more than one statement is used in a clause, grouping with { and } is required <statements> elsif <cond> then <statements> elsif <cond> then <statements> ... else <statements> end if |
Selection (cont'd)
switch (<expr>) { case <const>: <statements> break; case <const>: <statements> break; ... default: <statements> } |
Iteration
|
Enumeration-Controlled Loops
DO 20 i = 1, 10, 2 ... 20 CONTINUE which is defined to be equivalent to i = 1 20 ... i = i + 2 IF i.LE.10 GOTO 20 Problems: |
Enumeration-Controlled Loops (cont'd)
where the EBNF syntax of <forlist> is <forlist> -> <enumerator> [, enumerator]* <enumerator> -> <expr> | <expr> step <expr> until <expr> | <expr> while <cond> for i := 1, 3, 5, 7, 9 do ... for i := 1 step 2 until 10 do ... for i := 1, i+2 while i < 10 do ... |
Enumeration-Controlled Loops (cont'd)
for <id> := <expr> downto <expr> do <stmt> <statements> end loop for <id> in reverse <expr>..<expr> loop <statements> end loop Iterates i from 1 to n by testing i <= n before each iteration and updating i by 1 after each iteration for (int i = 1; i <= n; i++) ... |
Problems With Enumeration-Controlled Loops
#include <limits.h> main() { int i; for (i = 0; i <= INT_MAX; i++) ... } because the value of i overflows (INT_MAX is the maximum positive value int can hold) after the iteration with i==INT_MAX and i becomes a large negative integer i = 0; while (i < 10); { i++; } |
Logically-Controlled Pretest Loops
where the condition is a Boolean expression and the loop will terminate when the condition is false. Multiple statements need to be enclosed in begin and end where the loop will terminate when expression evaluates to 0 and multiple statements need to be enclosed in { and } |
Logically-Controlled Posttest Loops
where the condition is a Boolean expression and the loop will terminate when the condition is true where the loop will terminate when the expression evaluates to 0 and multiple statements need to be enclosed in { and } |
Logically-Controlled Midtest Loops
<statements> exit when <cond>; <statements> exit when <cond>; <statements> ... end loop outer: loop ... for i in 1..n loop ... exit outer when cond; ... end loop; end outer loop; |
Recursion
{ if (a==b) return a; else if (a>b) return gcd(a-b, b); else return gcd(a, b-a); } |
Tail Recursive Functions
int gcd(int a, int b) { start: if (a==b) return a; else if (a>b) { a = a-b; goto start; } else { b = b-a; goto start; } } which is just as efficient as the iterative implementation of gcd: int gcd(int a, int b) { while (a!=b) if (a>b) a = a-b; else b = b-a; return a; } |
Continuation-Passing-Style
|
Other Recursive Function Optimizations
typedef int (*int_func)(int); int summation(int_func f, int low, int high) { if (low==high) return f(low) else return f(low)+summation(f, low+1, high); } can be rewritten into the tail-recursive form: int summation(int_func f, intlow, int high, int subtotal) { if (low==high) return subtotal+f(low) else return summation(f, low+1, high, subtotal+f(low)); } (define summation (lambda (f low high) (if (= low high) ;condition (f low) ;then part (+ (f low) (summation f (+ low 1) high))))) ;else-part rewritten: (define summation (lambda (f low high subtotal) (if (=low high) (+ subtotal (f low)) (summation f (+ low 1) high (+ subtotal (f low)))))) |
Avoid Algorithmically Inferior Recursive Programs
(define fib (lambda (n) (cond ((= n 0) 1) ((= n 1) 1) (#t (+ (fib (- n 1)) (fib (- n 2))))))) (define fib (lambda (n) (letrec ((fib-helper (lambda (f1 f2 i) (if (= i n) f2 (fib-helper f2 (+ f1 f2) (+ i 1)))))) (fib-helper 0 1 0)))) |