Presentation is loading. Please wait.

Presentation is loading. Please wait.

Statement-Level Control Structures

Similar presentations


Presentation on theme: "Statement-Level Control Structures"— Presentation transcript:

1 Statement-Level Control Structures
Chapter 8 Statement-Level Control Structures

2 Augment Sebesta Material
Programming Languages-Cheng (Fall 2004) Edited.pptx Type Systems and Structures- Bermúdez

3 Chapter 8 Topics Introduction Selection Statements
Iterative Statements Unconditional Branching Other Selection Statements Practical PL Level Iteration and Recursion Guarded Commands Conclusions Copyright © 2015 Pearson. All rights reserved.

4 Levels of Control Flow Within expressions (Chapter 7)
Among program units (Chapter 9) Among program statements (this chapter) Copyright © 2015 Pearson. All rights reserved.

5 Control Statements: Evolution
FORTRAN I control statements were based directly on IBM 704 hardware Much research and argument in the 1960s about the issue One important result: It was proven that all algorithms represented by flowcharts can be coded with only two-way selection and pretest logical loops Copyright © 2015 Pearson. All rights reserved.

6 Control Structure A control structure is a control statement and the statements whose execution it controls Design question Should a control structure have multiple entries? Copyright © 2015 Pearson. All rights reserved.

7 Selection Statements A selection statement provides the means of choosing between two or more paths of execution Three general categories: One-way selection statements Two-way selectors statements Multiple-way selectors statements Nested selection statements? Copyright © 2015 Pearson. All rights reserved.

8 Selection Statements Very Early One-Way Examples Limitation:
FORTRAN IF: IF (boolean_expr) statement Limitation: Can select only a single statement; to select more, a GOTO must be used, as in the following example IF (.NOT. condition) GOTO 20 ... 20 CONTINUE

9 Two-Way Selection Statements
General form: if control_expression then clause else clause Clause can be single statements or compound statements Control_expression arithmetic/Boolean expressions Design Issues: What is form and type of control expression? How are the then and else clauses specified? How should the meaning of nested selectors be specified? Copyright © 2015 Pearson. All rights reserved.

10 The Control Expression
If the then reserved word or some other syntactic marker is not used to introduce the then clause, the control expression is placed in parentheses In C89, C99, Python, and C++, the control expression can be an arithmetic expression In most other languages, the control expression must be a Boolean expression Copyright © 2015 Pearson. All rights reserved.

11 Clause Form In many contemporary languages, the then and else clauses can be single statements or compound statements In Perl, all clauses must be delimited by braces (they must be compound) In Python and Ruby, clauses are statement sequences without delimiters Python uses indentation to define clauses if x > y : x = y print " x was greater than y" Copyright © 2015 Pearson. All rights reserved.

12 Nesting Selectors Java example Which if does the else match?
if (sum == 0) if (count == 0) result = 0; else result = 1; Which if does the else match? Java's static semantics rule: else matches with the nearest previous if Copyright © 2015 Pearson. All rights reserved.

13 Nesting Selectors (continued)
To force an alternative semantics, compound statements with delimiters may be used: if (sum == 0) { if (count == 0) result = 0; } else result = 1; The above solution is used in C, C++, and C# Copyright © 2015 Pearson. All rights reserved.

14 Nesting Selectors (continued)
Statement sequences as clauses: Ruby if sum == 0 then if count == 0 then result = 0 else result = 1 end Copyright © 2015 Pearson. All rights reserved.

15 Nesting Selectors (continued)
Python if sum == 0 : if count == 0 : result = 0 else : result = 1 Copyright © 2015 Pearson. All rights reserved.

16 Selection Statements FORTRAN 90 and Ada solution
use special words to resolve semantics of nested selectors e.g. (Ada) Advantage: flexibility and readability if .. then if … then else end if if .. then if … then end if else

17 Selector Expressions In ML, F#, and Lisp, the selector is an expression; in F#: let y = if x > 0 then x else 2 * x If the if expression returns a value, there must be an else clause (the expression could produce a unit type, which has no value). The types of the values returned by then and else clauses must be the same. Copyright © 2015 Pearson. All rights reserved.

18 Multiple-Way Selection Statements
Allow the selection of one of any number of statements or statement groups Design Issues: What is the form and type of the control expression? How are the selectable segments specified? Is execution flow through the structure restricted to include just a single selectable segment? How are case values specified? What is done about unrepresented expression values? Copyright © 2015 Pearson. All rights reserved.

19 Multiple-Way Selection: Examples
C, C++, Java, and JavaScript switch (expression) { case const_expr1: stmt1; case const_exprn: stmtn; [default: stmtn+1] } Copyright © 2015 Pearson. All rights reserved.

20 Multiple-Way Selection: Examples
Design choices for C’s switch statement Control expression can be only an integer type Selectable segments can be statement sequences, blocks, or compound statements Any number of segments can be executed in one execution of the construct (there is no implicit branch at the end of selectable segments) default clause is for unrepresented values (if there is no default, the whole statement does nothing) Copyright © 2015 Pearson. All rights reserved.

21 Selection Statements Multiple Selection Constructs
C: switch (expression) { case const_expr_1: statement_1; case const_expr_k: statement_k; [default: def_statement;] (optional) }

22 Multiple-Way Selection: Examples
Differs from C in that it has a static semantics rule that disallows the implicit execution of more than one segment Each selectable segment must end with an unconditional branch (goto or break) Also, in C# the control expression and the case constants can be strings Copyright © 2015 Pearson. All rights reserved.

23 Multiple-Way Selection: Examples
Ruby has two forms of case statements-we’ll cover only one leap = case when year % 400 == 0 then true when year % 100 == 0 then false else year % 4 == 0 end Copyright © 2015 Pearson. All rights reserved.

24 Implementing Multiple Selectors
Approaches: Multiple conditional branches Store case values in a table and use a linear search of the table When there are more than ten cases, a hash table of case values can be used If the number of cases is small and more than half of the whole range of case values are represented, an array whose indices are the case values and whose values are the case labels can be used Copyright © 2015 Pearson. All rights reserved.

25 Multiple-Way Selection Using if
Multiple Selectors can appear as direct extensions to two-way selectors, using else-if clauses, for example in Python: if count < 10 : bag1 = True elif count < 100 : bag2 = True elif count < 1000 : bag3 = True Copyright © 2015 Pearson. All rights reserved.

26 Multiple-Way Selection Using if
The Python example can be written as a Ruby case case when count < 10 then bag1 = true when count < 100 then bag2 = true when count < 1000 then bag3 = true end Copyright © 2015 Pearson. All rights reserved.

27 Scheme’s Multiple Selector
General form of a call to COND: (COND (predicate1 expression1) (predicaten expressionn) [(ELSE expressionn+1)] ) The ELSE clause is optional; ELSE is a synonym for true Each predicate-expression pair is a parameter - Semantics: The value of the evaluation of COND is the value of the expression associated with the first predicate expression that is true Copyright © 2015 Pearson. All rights reserved.

28 Iterative Statements The repeated execution of a statement or compound statement accomplished either by iteration or recursion; Focus on iteration, since recursion is a unit-level control (e.g., using functions) General design issues for iteration control stmts: How is iteration controlled? Counter-controlled vs logical-controlled 2. Where is the control mechanism in the loop? pretest (before loop body is executed) vs posttest (after loop body is executed) Copyright © 2015 Pearson. All rights reserved.

29 Counter-Controlled Loops
A counting iterative statement has a loop variable, and a means of specifying the initial and terminal, and stepsize values Design Issues: What are the type and scope of the loop variable? Should it be legal for the loop variable or loop parameters to be changed in the loop body, and if so, does the change affect loop control? Should the loop parameters be evaluated only once, or once for every iteration? Copyright © 2015 Pearson. All rights reserved.

30 Counter-Controlled Loops: Examples
C-based languages for ([expr_1] ; [expr_2] ; [expr_3]) statement - The expressions can be whole statements, or even statement sequences, with the statements separated by commas The value of a multiple-statement expression is the value of the last statement in the expression If the second expression is absent, it is an infinite loop General Case –what interpretation when omit one? for ( init ; control ; increment) ; Copyright © 2015 Pearson. All rights reserved.

31 Counter-Controlled Loops:
Design choices: There is no explicit loop variable Everything can be changed in the loop The first expression is evaluated once, but the other two are evaluated with each iteration - It is legal to branch into the body of a for loop in C Copyright © 2015 Pearson. All rights reserved.

32 Counter-Controlled Loops
C-based languages Syntax: for ([expr_1] ; [expr_2] ; [expr_3]) loop body Loop body can be single, compound, or null statement Expressions can be whole statements, or even statement sequences, with the statements separated by commas The value of a multiple-statement expression is the value of the last statement in the expression for (i = 0, j = 10; j == i; i++) All expressions of C’s for statement are optional If expr_2 is absent, it is an infinite loop

33 Counter-Controlled Loops
for ([expr_1] ; [expr_2] ; [expr_3]) loop body Operational Semantics: expr_1 % initialization (evaluate once) loop: if expr_2 = 0 goto out % loop control (each iter) [loop_body] expr_3 % increment loop counter? goto loop out: …

34 Counter-Controlled Loops
Design choices for C: There is no explicit loop variable or loop parameters All involved variables can be changed in the loop body It is legal to branch into loop body The first expression is evaluated once, but the other two are evaluated with each iteration

35 Counter-Controlled Loops: Examples
C++ differs from C in two ways: The control expression can also be Boolean The initial expression can include variable definitions (scope is from the definition to the end of the loop body) for (int i=0; i < len; i++) { … } Java and C# Differs from C++ in that the control(middle) expression must be Boolean Copyright © 2015 Pearson. All rights reserved.

36 Counter-Controlled Loops
FORTRAN 95 Syntax: Do label var = initial, terminal [, stepsize] stepsize can be any value but zero parameters can be expressions Design choices: Loop var must be integer; loop parameters can be expressions The loop var cannot be changed in the loop, but loop parameters can because they are evaluated only once, it does not affect loop control Single entry structure – loop can be entered through Do statement

37 Counter-Controlled Loops
Fortran 95: Do label var = init_expression, terminal_expression [, step_expression] Operational Semantics for Fortran 95 Do statement init_value = init_expression terminal_value = terminal_expression step_value = step_expression do_var = init_value iteration_count = max(int((terminal_value– init_value+step_value)/step_value), 0) loop: if iteration_count  0 goto out [loop body] do_var = do_var + step_value iteration_count = interation_count – 1 goto loop out: …

38 Counter-Controlled Loops
Another form of Do statement for FORTRAN 95 [name:] DO variable = initial, terminal [, stepsize] END DO [name] Uses a special word for closing: END DO

39 Counter-Controlled Loops
Ada Syntax: for var in [reverse] discrete_range loop ... end loop; reverse indicates that values of discrete range are assigned in reverse order Step size is always one (or next element in discrete_range)

40 Counter-Controlled Loops: Examples
Python for loop_variable in object: - loop body [else: - else clause] The object is often a range, which is either a list of values in brackets ([2, 4, 6]), or a call to the range function (range(5), which returns 0, 1, 2, 3, 4 The loop variable takes on the values specified in the given range, one for each iteration The else clause, which is optional, is executed if the loop terminates normally Copyright © 2015 Pearson. All rights reserved.

41 Counter-Controlled Loops: Examples
F# Because counters require variables, and functional languages do not have variables, counter-controlled loops must be simulated with recursive functions let rec forLoop loopBody reps = if reps <= 0 then () else loopBody() forLoop loopBody, (reps – 1) This defines the recursive function forLoop with the parameters loopBody (a function that defines the loop’s body) and the number of repetitions () means do nothing and return nothing Copyright © 2015 Pearson. All rights reserved.

42 Logically-Controlled Loops
Repetition control is based on a Boolean expression More general than counter-controlled loops Every counting loop can be built with a logical loop, but not vice-versa Design issues: Pretest or posttest? Should the logically controlled loop be a special case of the counting loop statement or a separate statement? Copyright © 2015 Pearson. All rights reserved.

43 Logically-Controlled Loops
Pascal has separate pretest and posttest logical loop statements (while-do and repeat-until) C and C++ also have both while (count > 0) { } do { } while (count > 0); Legal to branch into both while and do loop bodies with goto a label

44 Logically-Controlled Loops
Ada has a pretest version, but no posttest FORTRAN 77, 90, and 95 have neither Perl has two pretest logical loops, while and until, but no posttest logical loop while (count > 0) { } until (count == 0) {

45 Logically-Controlled Loops: Examples
C and C++ have both pretest and posttest forms, in which the control expression can be arithmetic: while (control_expr) do loop body loop body while (control_expr) - In both C and C++ it is legal to branch into the body of a logically-controlled loop Java is like C and C++, except the control expression must be Boolean (and the body can only be entered at the beginning) -- Java has no goto Copyright © 2015 Pearson. All rights reserved.

46 Logically-Controlled Loops: Examples
F# As with counter-controlled loops, logically-controlled loops can be simulated with recursive functions let rec whileLoop test body = if test() then body() whileLoop test body else () - This defines the recursive function whileLoop with parameters test and body, both functions. test defines the control expression Copyright © 2015 Pearson. All rights reserved.

47 User-Located Loop Control Mechanisms
User modifies the control flow of program More convenient for the programmers to decide a location for loop control (other than top or bottom of the loop) Simple design for single loops (e.g., break) Design issues for nested loops Should the conditional be part of the exit? Should control be transferable out of more than one loop? Copyright © 2015 Pearson. All rights reserved.

48 User-Located Loop Control Mechanisms
C , C++, Python, Ruby, and C# have unconditional unlabeled exits (break) Java and Perl have unconditional labeled exits (break in Java, last in Perl) C, C++, and Python have an unlabeled control statement, continue, that skips the remainder of the current iteration, but does not exit the loop Java and Perl have labeled versions of continue Copyright © 2015 Pearson. All rights reserved.

49 User-Located Loop Control
Exit statement: Unconditional unlabeled exit: break (C, C++) for (index=0; index<10; index++) { if (value < 0) break; } Unconditional labeled exit: break (Java, C#), last (Perl) C#: outerLoop: for (row=0; row<numRows; row++) for (col = 0; col < numCols; col++) { sum += matrix[row][col]; if (sum > 1000) break outerLoop; Perl: LINE: while (<STDIN>) { last LINE if /^$/;

50 User-Located Loop Control
Skip the rest of loop body: C/C++ have unlabeled control statement (continue) while (sum < 1000) { value = getNextValue(); if (value < 0) continue; sum += value; } Java, Perl, and C# have statements similar to continue, except they can include labels that specify which loop is continued

51 Iteration Based on Data Structures
The number of elements in a data structure controls loop iteration Control mechanism is a call to an iterator function that returns the next element in some chosen order, if there is one; else loop is terminate C's for can be used to build a user-defined iterator: for (p=root; p==NULL; traverse(p)){ ... } Copyright © 2015 Pearson. All rights reserved.

52 Iteration Based on Data Structures
Loops are controlled by number of elements in a data structure Perl, Javascript, PHP, and C# have such statements Perl: @values = (1, 2, 3, 4, 5); foreach $value { print “Value is $value\n”; } \ C#: String[] strList = {“Bob”, “John”, “Carol” }; foreach (String name in strList)

53 Iteration Based on Data Structures
More general approach Utilizes a user-defined data structure and a user-defined function (called an iterator) to go through the structure’s elements Java has a Collection interface that contains two methods: boolean add(Object obj) - adds elements to collection Iterator iterator() - used to visit the elements in the collection one by one.

54 Iteration Based on Data Structures (continued)
PHP - current points at one element of the array - next moves current to the next element - reset moves current to the first element Java 5.0 (uses for, although it is called foreach) For arrays and any other class that implements the Iterable interface, e.g., ArrayList for (String myElement : myList) { … } Copyright © 2015 Pearson. All rights reserved.

55 Iteration Based on Data Structures (continued)
C# and F# (and the other .NET languages) have generic library classes, like Java 5.0 (for arrays, lists, stacks, and queues). Can iterate over these with the foreach statement. User-defined collections can implement the IEnumerator interface and also use foreach. List<String> names = new List<String>(); names.Add("Bob"); names.Add("Carol"); names.Add("Ted"); foreach (Strings name in names) Console.WriteLine ("Name: {0}", name); Copyright © 2015 Pearson. All rights reserved.

56 Iteration Based on Data Structures (continued)
Ruby blocks are sequences of code, delimited by either braces or do and end Blocks can be used with methods to create iterators Predefined iterator methods (times, each, upto): 3.times {puts ″Hey!″} list.each {|value| puts value} (list is an array; value is a block parameter) 1.upto(5) {|x| print x, ″ ″} Iterators are implemented with blocks, which can also be defined by applications Copyright © 2015 Pearson. All rights reserved.

57 Iteration Based on Data Structures (continued)
Ruby blocks are attached methods calls; they can have parameters (in vertical bars); they are executed when the method executes a yield statement def fibonacci(last) first, second = 1, 1 while first <= last yield first first, second = second, first + second end puts "Fibonacci numbers less than 100 are:" fibonacci(100) {|num| print num, " "} puts - Ruby has a for statement, but Ruby converts them to upto method calls Copyright © 2015 Pearson. All rights reserved.

58 Unconditional Branching
Transfers execution control to a specified place in the program Represented one of the most heated debates in 1960’s and 1970’s Major concern: Readability Some languages do not support goto statement (e.g., Java) C# offers goto statement (can be used in switch statements) Loop exit statements are restricted and somewhat camouflaged goto’s Copyright © 2015 Pearson. All rights reserved.

59 Unconditional Branching
Transfers execution control to a specified location in the program goto label Problem: readability Some languages do not have them: e.g., Java Loop exit statements are restricted and somewhat camouflaged goto’s Label forms: Unsigned int constants: Pascal (with colon) FORTRAN (no colon) Identifiers with colons: ALGOL 60, C Variables as labels: PL/I

60 Other Selection Statements
Programming Language Principles Lecture 20 Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida

61 Structured Programming
Federal Law: Abandon Goto's ! Originally, Fortran had goto's: if a .lt. b goto 10 ... 10 Controversy surrounding Goto's: Paper (letter to editor ACM Comm.) in 1968 by E. Dijkstra: 1719 citations "Goto statement Considered Harmful" argument: Goto's create “spaghetti code".

62

63 Structured Programming (cont’d)
Legacy: structured programming: use of sequencing (;) alternation (if) iteration (while) Sufficient to solve any problem. Part of focus on *control* during first 40 years in programming. During 80's, 90's and beyond, focus shifted to *data* (OO-programming)

64 Structured Programming (cont’d)
Common (former) use of goto: break out of loop(s), maybe deeply nested: while true do begin if (...) then goto 100; end; 100: ...

65 Structured Programming (cont’d)
In C, this can be accomplished using a 'break' statement, but consider this ... while (...) { switch (...) { ... goto loop_done; /* break won't do */ { } loop_done: ...

66 Structured Programming (cont’d)
When executing a jump, we might be: exiting one or more procedure calls. exiting many nested loops. diving into the middle of a procedure diving into the middle of a loop. What happens to the stack ???

67 Structured Programming (cont’d)
Goto's in general described using *continuations*: A continuation captures the context (state) in which execution might continue. Continuations essential to denotational semantics

68 Statement Sequencing Basic assumption:
A sequence of statements will have side effects. Not always desirable; easier to reason (prove correct) programs in which functions have no side effects. Sometimes side-effects are *very* desirable. Example: rand() function. want it to produce a different number each time it's called.

69 Statement Selection Most languages use a variant of the original if...then...else introduced in Algol 60: if condition then statement else if condition then statement ... else statement

70 Statement Selection (cont’d)
switch (condition) { case a: block_a; case b: block_b : ... default: block_c} is often syntactical sugar for if (condition == a) block_a else if (condition == b) block_b else block_c

71 Short-Circuited Conditions
Design goal: implement if’s efficiently. Jump code: efficient organization of code to take advantage of short-circuited boolean expressions. Value of expression never stored in a register.

72

73

74 Short-Circuited Conditions (cont’d)
If the value of the entire expression is needed, we can still use jump code. Example (Ada): found := p /= null and then p.key =val; equivalent to if p /= null and then p.key=val then found := true; else found := false; end if;

75 Short-Circuited Conditions (cont’d)
Jump code: r1 := p if r1=0 goto L1 r2 := r1->key if r2 <> val goto L1 r1 := 1 goto L2 L1: r1:=0 L2: found := r1

76 Case/Switch Statements
Alternative syntax for nested if...then...else statements. Example: i := (* potentially complicated expression *) if i=1 then clause_A else if i=2 or i=7 then clause_B else if i >=3 and i <= 5 then clause_C else if i=10 then clause_D else clause_E

77 Corresponding CASE statement

78 Case/Switch Statements (cont’d)
Purpose of case statement is not only syntactic elegance, but efficiency. Wish to *compute* the address to which to branch. So, list ten cases (range of values tested): Store addresses starting at location T (jump table). Calculate r1 (the test expression value). First test for r1 out of range Subtract 1 from r1, obtaining an offset (0..9). Get address T[r1], store in r2. Branch to (indirect) r2.

79

80

81 Case/Switch Statements (cont’d)
Advantages: fast, occupies reasonable space if labels are dense. Disadvantage: can occupy enormous amounts of space if values are not dense (e.g. 1, 3..5, )

82 Case/Switch Statements (cont’d)
Pascal, C don't allow ranges (avoid binary search). Standard Pascal doesn't allow a default clause: Run-time semantic error if no case matches expression. Many Pascal compilers *do* allow it as an extension.

83 Case/Switch Statements (cont’d)
Modula provides an optional ELSE clause. Ada requires labels to cover *ALL* values in the domain of the type of the expression. Ranges and an *others* clause are allowed. C, Fortran 90: OK for expression to match no value: statement does nothing.

84 Case/Switch Statements (cont’d)
C is different in other respects: A label can have an empty arm, Control "falls" through to next label. Effectively allows lists of values. Example: switch (grade) { case 10: case 9: case 8: case 7: printf("Pass"); break; default: printf("Fail"); break; }

85 Case/Switch Statements (cont’d)
'break' needed to prevent fallthrough. If a value matches test expression, fall-through takes place i.e., there are no more comparisons.

86 Case/Switch Statements (cont’d)
Example: switch (grade) { case 10: case 9: case 8: case 7: num_pass++; case 6: borderline++; case 0: case 1: case: 2 case 3: case 4: case: 5 fail ++; default: total++; break; } In C, a forgotten break can be a difficult bug to find.

87 Practical PL Level Iteration and Recursion
Programming Language Principles Lecture 21 Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida

88 Iteration Execute a block multiple times for its side effects.
Enumeration controlled loops: Execute a block for every value in a finite set. Fortran: do 10 i=1,10,2 ... 10 continue :

89 Classic Problems in Fortran
'do' as prefix of assignment: do7i=j+3*4,20 do loop do7i=j assignment 'do7i' is a valid identifier. 'do' not a reserved word in Fortran. Need to look ahead arbitrary distance, to the 'comma'.

90 Classic Problems in Fortran (cont’d)
Loop body can change the loop index: do 10 i=2,20 i=i-1 10 continue infinite loop Goto's can jump into the middle of a loop. So what's the value of the index, in that case ??

91 Classic Problems in Fortran (cont’d)
If goto branches out of loop, value of i is last assigned. If loop terminates normally, value of i is implementation-defined. Last increment of i can cause overflow: negative value ??? Fortran loop is bottom-tested: loop body will execute at least once.

92 Pascal (and Modula, and most languages with enumeration controlled loops): for i := first to last by step do begin ... end;

93 Pascal (cont’d) Questions:
Can i, first or last be modified in the loop? If so, what is the effect? What if first > last? What 's the value of i when done? Can one jump from outside, into the loop? What if first has a side effect on i, or on last, or vice-versa? for i := first to last by step do begin ... end;

94 Pascal (cont’d) Most languages prohibit modifying the loop index.
Very expensive to check at compile time. Need to check for: Assignments to i Nested loops that use i. Passing i to a procedure by reference. Reading i.

95 Pascal (cont’d) What does this Pascal for statement do? i := 7;
for i := i+1 to i+8 do begin ... end; What if instead of i+1, we had f(i), where f takes i as a reference parameter ?

96 Modern For Loops Are Top-Tested

97 Modern For Loops Are Top-Tested (cont’d)
Works only for positive steps. In Pascal, for i := 10 down to 1 do ... In Ada, for i in reverse do ... In Modula, FOR i := 10 to 1 STEP -1 compile-time constant

98 Modern For Loops Are Top-Tested (cont’d)
In C, C++, Java, it's simple. No loop index. for (e1; e2; e3) body; Code is: e1; L2: if not e2 goto L1 body e3; <--- any 'continue' branches here goto L2 L1: ...

99 Modern For Loops Are Top-Tested (cont’d)
NOT equivalent to: e1; while (e2) { body; /* if this contains a 'continue', */ e3; /* e3 is not executed */ }

100 Modern For Loops Are Top-Tested (cont’d)
In C, programmer's responsibility: effect of overflow. index, other variables, can be modified inside loop. e1, e2, e3 are all optional. If e2 is missing, it's considered to be a 1 (true).

101 Access to the Index Outside the Loop
Fortran IV, Pascal, leave the loop index undefined. Fortran 77, Algol 60, leave the "last value assigned". In Pascal, var c: 'a' .. 'z'; for c := 'a' to 'z' do begin ... end; (* what's the value of c ? *)

102 Access to the Index Outside the Loop (cont’d)
Compiler forced to generate slower code Two branches in each iteration

103 Access to the Index Outside the Loop (cont’d)
Several languages (Algol W, Algol 68, Ada, Modula-3, new ISO C++): loop header *declares* loop index. loop index's type is inferred from loop bounds. not visible outside the loop.

104 Combination Loops Algol 60 allows a 'for-list' of enumerated values/ranges. Syntax: Stmt 'for' id ':=‘ Enumerator list ',' 'do' Stmt Enumerator Expr Expr 'step' Expr 'until' Expr Expr while Condition

105 Combination Loops (cont’d)
Algol Examples (all three are equivalent): for i := 1, 3, 5, 9 do ... for i := 1 step 2 until 10 do ... for i := 1, i + 2 while i < 10 do ...

106 Iterators An iterator allows examination of the elements in a data structure, one at a time. Various kinds of iterators available in Clu, Java Java has a built-in iterator class.

107 Iterator Methods in Java
Iterator ix = x.iterator(); Constructs and initializes an iterator for the elements of x. ix is the new iterator. The class for x must define the iterator() method.

108 Iterator Methods in Java (cont’d)
ix.hasNext() Returns true iff x has a next element. ix.next() Return next element; Throws NoSuchElementException if there is no next element.

109 Iterator Methods in Java (cont’d)
ix.remove() Removes last element returned by ix.next(). Throws UnsupportedMethodEXception if method not implemented. Throws IllegalStateException if ix.next() not yet called or did not return an element.

110 Using the Iterator Iterator ix = x.iterator(); while (ix.hasNext())
examine(ix.next()); Much better than for (int i=0; i<x.size(); i++) examine (x.get(i));

111 Advantages of Iterators
More abstraction. Object class "knows" how to iterate. Often possible to implement next() more efficiently than get(). Example: linked list. Data structures often have no get-by-index method.

112 "Faking" an Iterator in C Using a "fake" iterator in C:

113 Logically Controlled Loops (cont’d)
Semantically less complex (fewer subtleties). Execute statement (or block) until a condition becomes true/false (while) Variations (syntactic sugar of each other): while condition do block; (Pascal, Modula) while (condition) block; (C, C++, Java) for i := irrelevant_expression while condition do statement (Algol) 10 if negated-condition goto 20 block goto 10 (Fortran)

114 Logically Controlled Loops (cont’d)
Post-tested loops (execute at least once): repeat statements until condition (Pascal) do statement while condition (C, C++, Java)

115 Mid-Tested Loops (Quit Anytime):
statement_list when condition exit ... end (Modula-1) 'exit' is built in, along with 'when', so exiting from a nested construct is impossible.

116 Modula-2 Favored a simple EXIT Statement LOOP line = ReadLine;
IF AllBlanks(line) THEN EXIT END; ConsumeLine(line) END; EXIT statements are only allowed to appear inside LOOPs. Difficult to enforce.

117 Modula-3 EXIT can abort a WHILE, REPEAT, or FOR loop. C: for (;;) {
line = read_line(stdin); if (all_blanks(line)) break; consume_line (line); }

118 C Loops [M. Scott says "for some reason, for(;;) has traditionally been favored over the equivalent while (1)". The actual original reason was efficiency, not style: older compilers would actually test the 1 each time around the while loop. With today's compilers, it should make no difference.

119 Mid-Tested Loops (cont’d):
Euclid, Ada: loop ... exit when condition; end loop;

120 Mid-Tested Loops (cont’d):
Java: loops can be labeled, 'break' statement has optional label. outer: while (true) { get_line(line); for (i=1; i<=length; i++) if line[i]='#' break outer; consume_line(line); }

121 Recursion Any iterative formulation can be expressed as recursion, and vice versa. They are equally powerful. Some functional languages do not allow iteration. Iteration often more efficiently implemented.

122 Recursion (cont’d) Optimizing compilers for functional languages usually generate very good code. The use of iteration/recursion is mostly a matter of ease of use: Iteration more efficient than recursion ? Naive implementations are.

123 Recursion (cont’d) For some problems, iteration seems natural.
for (i=low; i<=high; i++) total += f(i); For other problems, recursion seems more natural: let gcd a b = a eq b -> a | a < b -> gcd a (b-a) | gcd (a-b) b

124 Recursion (cont’d) In C, int gcd (int a, int b) { if (a==b) return a;
else if (a > b) return gcd(a-b,b); else return gcd(a, b-a); } In both cases, the choice could go the other way.

125 Recursion (cont’d) GCD in C, non-recursive: int gcd(int a,int b) {
while(a!=b) if (a > b) a = a - b; else b = b - a; return a; }

126 Tail-Recursion Additional computation never follows a recursive call. (nothing done as recursion unwinds). No need to allocate stack space dynamically: we can reuse previous space. Continuation-passing style: can always avoid doing work after recursive call by passing that work into the recursive call, a continuation.

127 Tail-Recursion in Scheme

128 Normal-Order Evaluation
Normal order (passing unevaluated parameters) is used for macros in C. Example: #define DIVIDES(n,a) (!((n) % (a))) /* true iff n % a is zero */ Preprocessor replaces DIVIDES (x,y+z) (textually!, no evaluation) with (!((x) % (y+z)))

129 Normal-Order Evaluation (cont’d)
Parentheses (n), (a) are crucial. Without them, DIVIDES (x,y+z) is replaced with (!(x % y+z)) which is equivalent to (!((x % y)+z))

130 Normal-Order Evaluation (cont’d)
Macros are problematic: #define MAX(a,b) ((a) > (b) ? (a) : (b) MAX(x++, y++) will increment either x (or y) TWICE !

131 Normal-Order Evaluation (cont’d)
Advantage of macros: Efficient ! No function call overhead. In C++, 'inline' tells compiler to try to convert function call to a macro. Algol 60 uses normal order, with PL order also available.

132 Guarded Commands Designed by Dijkstra
Purpose: to support a new programming methodology that supported verification (correctness) during development Basis for two linguistic mechanisms for concurrent programming (in CSP) Basic Idea: if the order of evaluation is not important, the program should not specify one Copyright © 2015 Pearson. All rights reserved.

133 Selection Guarded Command
Form if <Boolean expr> -> <statement> [] <Boolean expr> -> <statement> ... fi Semantics: when construct is reached, Evaluate all Boolean expressions If more than one are true, choose one non-deterministically If none are true, it is a runtime error Copyright © 2015 Pearson. All rights reserved.

134 Loop Guarded Command Form Semantics: for each iteration ...
do <Boolean> -> <statement> [] <Boolean> -> <statement> ... od Semantics: for each iteration Evaluate all Boolean expressions If more than one are true, choose one non-deterministically; then start loop again If none are true, exit loop Copyright © 2015 Pearson. All rights reserved.

135 Guarded Commands: Rationale
Connection between control statements and program verification is intimate Verification is impossible with goto statements Verification is possible with only selection and logical pretest loops Verification is relatively simple with only guarded commands Copyright © 2015 Pearson. All rights reserved.

136 Non-Determinacy Construct in which the choice between alternatives is deliberately unspecified. Example: n + n++ in C (order of evaluation unspecified)

137 Non-Determinacy (cont’d)
Sometimes makes it easier to reason about program. Mostly a set of guarded commands from which any guard that is true can be selected.

138 Non-Determinacy (cont’d)
Example (SR, adopted Dykstra's guarded command): if a >= b -> max := a; [] b >= a -> max := b; fi Nondeterministic choice made among guards that evaluate to true.

139 Non-Determinacy (cont’d)
Also used for loops: do a > b -> a := a - b; [] b > a -> b := b - a; od gcd := a Loop quits when no guard is true. We wish to ensure fairness: each candidate equally likely to execute.

140 Conclusions Variety of statement-level structures
Choice of control statements beyond selection and logical pretest loops is a trade-off between language size and writability Functional and logic programming languages use quite different control structures Copyright © 2015 Pearson. All rights reserved.


Download ppt "Statement-Level Control Structures"

Similar presentations


Ads by Google