Presentation is loading. Please wait.

Presentation is loading. Please wait.

Control Structures Any mechanism that departs from straight-line execution: –transfer of control (closest to machine): gotos –Selection: if-statements.

Similar presentations


Presentation on theme: "Control Structures Any mechanism that departs from straight-line execution: –transfer of control (closest to machine): gotos –Selection: if-statements."— Presentation transcript:

1 Control Structures Any mechanism that departs from straight-line execution: –transfer of control (closest to machine): gotos –Selection: if-statements –Multiway-selection: case statements –Unbounded iteration: while-loops –Definite iteration: for-loops –Iterations over collections –unbounded transfer of control: exceptions, backtracking

2 GoTo Recall that machine language consists of basic arithmetic (add, subtract, logical and, logical or etc.), access to memory (memory to memory, memory to register, register to memory), and branching. Branch statements are either unconditional (go to address X) or conditional (if result of this operation is 0 then go to address X). All you need for a universal machine: increment, decrement, branch on zero. All the rest is programmer convenience! But convenience facilitates reasoning about program.…

3 Selection if Condition then Statement -- Pascal, Ada if (Condition) Statement -- C, C++ Java To avoid ambiguities, use end marker: end if, “}” To deal with alternatives, use keyword or bracketing: if Condition then if (Condition) { Statements Statements } elsif Condition then else if (Condition) { Statements Statements} else else { Statements Statements} end if;

4 Nesting if Condition then if (Condition) if Condition then if (Condition) { Statements Statements end if; } else else { Statements Statements end if; }

5 Statement Grouping Pascal introduces begin-end pair to mark sequence C/C++/Java abbreviate keywords to { } Ada dispenses with brackets for sequences, because keywords for the enclosing control structure are sufficient: for J in 1.. N loop … end loop; –More writing => more readable The use of grouping in C a reminder that it is an expression language The use of grouping in C++/Java is just syntactic tradition Another possibility (ABC, Python): make indentation significant

6 Short-Circuit Evaluation If x is more than five times greater than y, compute z: if x / y > 5 then z := … -- but what if y is 0? If y /= 0 and x/ y > 5 then z := … -- but operators evaluate their arguments Solutions: –a lazy evaluation rule for logical operators (LISP, C, etc) –a control structure with a different syntax C1 && C2 does not evaluate C2 if C1 is false if C1 and then C2 then ditto C1 || C2 does not evaluate C2 if C1 is true if C1 or else C2 then ditto

7 Multiway selection The case statement is needed when there are many possibilities “at the same logical level.” (I.e. depending on same condition) Can be simulated with a sequence of if-statements, but logic become obscured. case Next_Char is when ‘I’ => Val := 1; when ‘V’ => Val := 5; when ‘X’ => Val := 10; when ‘C’ => Val := 100; when ‘D’ => Val := 500; when ‘M’ => Val := 1000; when others => raise Illegal_Numeral; end case;

8 The well-structured case statement Action following each choice is atomic (no flow-through) There are no duplicate choices All possible choices are covered There is mechanism to specify a default outcome for choices not given explicitly. In some languages for sake of efficiency:: Type of expression must be discrete: and enumerable set of values (floating-point numbers not acceptable)

9 Implementation (compiler consideration) Finite set of possibilities: can build a table of addresses, and convert expression into table index: –compute value –transform into index –retrieve address of corresponding code fragment –branch to code fragment and execute –branch to end of case statement All cases have the same execution cost All choices should be static: computable at compile-time

10 Complications case (X + 1) is -- any integer value (discrete but large) when integer’first.. 0 => Put_Line (“negative”); when 1 => Put_Line (“unit”); when 3 | 5 | 7 | 11 => Put_Line (“smal prime”); when 2 | 4 | 6 | 8 | 10 => Put_Line (“small even”); when 21 => Put_Line (“the house wins”); when 12.. 20 | 22.. 99 => Put_Line (“manageable”); when others => Put_Line (“Irrelevant”); end case; Implementation must be combination of tables and if-statements.

11 Indefinite loops All loops can be expressed as while-loops (good for invariant/assertion reasoning as we will see later) Condition is evaluated at each iteration If condition is initially false, loop is never executed while Condition loop.. end loop; equivalent to if Condition then while Condition loop … end loop; end if; (provided Condition has no side-effects…)

12 What if we want to execute at least once? Pascal introduces until-loop. C/C++ use different syntax with while: while (Condition) { … } do { … } while (Condition) While form is most common Can always simulate with a boolean variable: first := True; while (Condition or else first) loop … first := False; end loop;

13 Breaking out More common is the need for an indefinite loop that terminates in the middle of an iteration. C/C++/Java: break Ada : exit statement loop -- infinite loop compute_first_part; exit when got_it; compute_some_more; end loop;

14 Multiple exits Within nested loops, useful to specify exit from several of them Ada solution: give names to loops Otherwise: use a counter (Modula) or use a goto. Outer: while C1 loop... Inner: while C2 loop... Innermost: while C3 loop... exit Outer when Major_Failure; exit Inner when Small_Annoyance;... end loop Innermost; end loop Inner; end loop Outer;

15 Definite loops Counting loops are iterators over discrete domains: for J in 1..10 loop … for (int I = 0; I < N; I++ ).. Design issues: –Evaluation of bounds (only once, ever since Algol60) –Scope of loop variable –Empty loops –Increments other than one –Backwards iteration –non-numeric domains

16 Evaluation of bounds for J in 1.. N loop … N := N + 1; end loop; -- terminates? In Ada, bounds are evaluated once before iteration starts. The above always terminates (and is abominable style). The C/C++/Java loop has hybrid semantics: for (int J = 0; J < last; J++) { … last++; -- may not terminate! }

17 The loop variable Best if local to loop and treated as constant Avoids issue of value at termination, and value on abrupt exit counter : integer := 17; -- outer declaration... for counter in 1..10 loop do_something; -- 1 <= counter <= 10 end loop; … -- counter is still 17

18 Different increments The universal Algol60 form: for J from Exp1 to Exp2 by Exp3 do… Too rich for most cases. Exp3 is most often +1, -1. What is meaning if Exp1 > Exp2 and Exp3 < 0 ? In C/ C++ for (int J = Exp1; J <= Exp2; J = J + Exp3) … In Ada: for J in 1.. N loop -- increment is +1 for J in reverse 1.. N loop -- increment is -1 Everything else can be programmed with while-loop

19 Non-numeric domains Ada form generalizes to discrete types: for M in months loop … Basic pattern on other data-types: define primitive operations: first, next, more_elements: Iterator = Collection.Iterate(); // build an iterator over a collection of elements element thing = iterator.first; // define loop variable while (iterator.more_elements ()) {... thing = iterator.next (); // value is each successive element }

20 How do we know it’s right? Pre-Conditions and Post-conditions: {P} S {Q} means: if Proposition P holds before executing S, and the execution of S terminates, then proposition Q holds afterwards. Need to formulate pre- and post-conditions for all statement forms, and syntax-directed rules of inference. {P and C} S {P} (P and C} while C do S end loop; {P and not C} i.e. on exit from a while-loop we know the condition is false.

21 Efficient exponentiation function Exp (Base : Integer; Expon : Integer) return integer is N : Integer := Expon; -- to pick up successive bits of exponent Res : Integer := 1; -- running result Pow : Integer := Base; -- successive powers: Base ** (2 ** I) begin while N > 0 loop -- inv: Res * (Pow ** N) == Base ** Expop if N mod 2 = 1 then Res := Res * Pow; end if; Pow := Pow * Pow; N := N / 2; -- y ** k == (y^2) ** (k/2). Note: 13/2 = 6 (floor op) end loop; return Res; end Exp;

22 Efficient exponentiation example 2 ** 13, so 2 is the base (local variable Pow) and 13 is the exponent (local variable N). Initial Res is 1. First time through loop, Res goes to 2, Pow goes to 4 and N goes to 6. (2**13 = 2 (2**12) = 2 (4 ** 6)) Second time, Pow goes to 16 and N goes to 3. (4**6 = 16 ** 3). Third time: Res goes to 2*16 = 32 and Pow goes to 16*16=256 and N goes to 1. Finally: Res goes to 32 * 256

23 Adding invariants (alternative approach) function Exp (Base : Integer; Expon : Integer) return integer is … declarations … {i = 0} to count iterations begin while N > 0 loop {i := i + 1} if N mod 2 = 1 then { N mod 2 is ith bit of Expon from left} Res := Res * Pow; { Res := Base ** (Expon mod 2 ** i} end if; Pow := Pow * Pow; { Pow := Base ** (2 ** i)} N := N / 2; { N := Expon / ( 2 ** i) } end loop; return Res; {i = log Expon; N = 0; Res = Base ** Expon} end Exp;

24 Assertion-Invariant Style Very good programming practice. Often helps you reason through difficult loops (e.g. if you implement dynamic programming, you will find them useful). Can be extended to handle exceptions.

25 Example of Loop with Exception (What is post-condition?) with Integer_Text_Io; use Integer_Text_Io; function Get_Data return Integer is X : Integer; begin loop begin Get (X); return X; -- if got here, input is valid, so leave loop exception when others => Put_Line (“input must be integer, try again”); -- will restart loop to wait for a good input end; end loop; end;


Download ppt "Control Structures Any mechanism that departs from straight-line execution: –transfer of control (closest to machine): gotos –Selection: if-statements."

Similar presentations


Ads by Google