470 likes | 514 Views
This chapter provides an introduction to selection and iterative statements in programming languages. Learn about different levels of control flow, imperative vs declarative programming paradigms, examples of imperative and declarative code, types of control flow, and design issues related to selection statements.
E N D
Chapter 8Statement-Level Control Structures Peter A. Ng CS 350 Programming Language Design Indiana University – Purdue University Fort Wayne
Chapter 8 Topics • Introduction • Selection statements • Iterative statements • Unconditional branching
Introduction • There are three levels of control flow . . . • Within expressions(Chapter 7) • Among program statements(this chapter) • Among program units (Chapters 9 and 13) • A control structureis a control statement, and the statements whose execution it controls • It is generally agreed that a control structure should only be enteredfrom its beginning • It is a bad practice to use gotos to jump to a labeled statement inside a control structure (Why?)
Control Flow • In computer science, control flowrefers to the order in which the individualstatements, instructions or function calls of an imperative programare executed or evaluated. • Acontrol flow statement is a statement whose execution results in a choice being made as to which of two or more paths should be followed.
Imperative vs Declarative • There are two ways in which we can write code: • imperative and • declarative.
Imperative vs Declarative Programming Paradigm • Imperative programming: • telling the "machine" how to do something, • and as a result what you want to happen will happen. • (Uses statements (commands) that change a program’s • statement). • Declarative programming: • telling the "machine"what you would like to happen, • and let the computer figure out how to do it. • (Focuses on what the program should accomplish • without specifying how the program should achieve • the result.)
Examples of imperative and declarative code For example, let's say we wish to double all the numbers in an array. We could do this in an imperative style: var numbers = [1,2,3,4,5] var doubled = [] for(vari=0; i<numbers.length; i++) { varnewNumber= numbers[i] *2 doubled.push(newNumber) } console.log(doubled) //=> [2,4,6,8,10]
Imperative Programming We explicitly iterate over the length of the array, pull each element out of the array, double it, and add the doubled value to the new array, mutating the doubled array at each step until we are done.
Adeclarative approach might usethe Array.map function and look like: var numbers = [1,2,3,4,5] var doubled =numbers.map(function(n){ return n *2 }) console.log(doubled) //=> [2,4,6,8,10]
A declarative approach might usethe Array.map function and look like: map creates a new array from an existing array, where each element in the new array is created by passing the elements of the original array into the function passed to map (function(n) { return n*2 } in this case).
A declarative approach might usethe Array.map function and look like: What the map function does is abstract away the process of explicitly iterating over the array, and lets us focus on what we want to happen. Note that the function we pass to map is pure; it doesn't have any side effects (change any external state), it just takes in a number and returns the number doubled.
Types of Control Flow • The kinds of control flow statements supported by different languages vary, but can be categorized by their effect: • continuation at a different statement (unconditional branch or jump), • executing a set of statements only if some condition is met (choice - i.e., conditional branch), • executing a set of statements zero or more times, until some condition is met (i.e., loop - the same as conditional branch), • executing a set of distant statements, after which the flow of control usually returns (subroutines, coroutines, and continuations), • stopping the program, preventing any further execution (unconditional halt).
Introduction • Böhm and Jacopini showed (1966) that a programming language requires only two control statements in addition to the normal sequence • Two-way selection among alternate statements(e.g. if-else) • Logical pre-test loop What else control statements should a language define, beyond selection and logical pretest loops? • This is a question of how much a language should be expanded for writability, while also considers simplicity, size, and readability
Selection statements • A selection statement provides the means of choosing between two or more paths of execution • Two general categories • Two-way selection • Multiple-way selection • Design Issues • What is the form and type of the expression that makes the selection? • How are the then and else clauses specified? • How to specify the nested selectors?
Two-way selection statements if2*a = 18 then result := 1; else result := 0; a := 2*a; endif; if ( 2*a – 18 ) { result = 0; a = 2*a; } else result = 1; if ( 2*a == 18 ) result = 1; else { result = 0; a = 2*a; } • C and C++ allow arithmetic expressions to be used as Boolean values in control expression • C and Java use { } whenever there is more than one statement in an alternative • Ada doesn’t need { }. C Java Ada
Two-way Selection Statements if ( sum == 0 ) if( count == 0 ) result = 0; else result = 1; if( sum == 0 ) { if ( count == 0 ) result = 0; } else result = 1; ifsum = 0 then ifcount = 0 then result := 0; endif; else result := 1; endif; if ( sum == 0 ) if ( count == 0 ) result = 0; else result = 1; • The “dangling else” problem occurs when two-way selectors are nested • Java, C, and C++ resolve this ambiguity differently • Java's static semantics rule: else matches with the nearest previous if • C, C++, and C# force compound statement • Ada resolves the problem with the endif syntax Dangling else Java C Ada
Two-way Selection Statements (`cont) • Statement sequences as clauses: Ruby ifsum == 0 then ifcount == 0 then result = 0 else result = 1 end end
Two-way Selection Statements (`cont) • Python if sum == 0 : if count == 0 : result = 0 else : result = 1
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 expression that controls the selection? • How to specify the selectable segments? • Is execution flow through the structure restricted to include just a single selectable segment? • What is done about unrepresented expression values?
Multiple-way selection statements • The C, C++, and Java switch statement • If break is not used, this statement actually has multiple entry points switch (expression) { constant_expression_1 : segment_1; constant_expression_1 : segment_2; ... constant_expression_n : segment _n; [default: segment_n+1] }
Multiple-Way Selection: Examples • C’s switch statement • Control expression can be 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 switch( c ) { case 'A': capa++; break; case 'a': littlea++; break; default : total++; }
Multiple-Way Selection: Examples • C# • 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
Multiple-Way Selection: Examples • Ruby has many forms of case • print "Enter your grade: " • grade = gets.chomp • case grade • when "A" • puts 'Well done!' • when "B" • puts 'Try harder!' • when "C" • puts 'You need help!!!' • else • puts "You just making it • up!" • end • print "Enter your grade: " • grade = gets.chomp • case grade • when "A", "B" • puts 'You pretty smart!' • when "C", "D" • puts 'You pretty dumb!!' • else • puts "You can't even use a computer!" • end
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
Chained else-ifs • More powerful than case or switch • Allows case to be determined by a series of questions • However, chained else-ifs can lead to deep nesting and poor readability • Special syntax has been developed for chained else-ifs in Ada and Perl • if count < 10 then • digits := 1; • elsif count < 100 then • digits := 2; • elsif count < 1000 then • digits := 3; • else • digits := 4 • end if;
Iterative statements • An iterative statement causes the repeat execution of a list of statements zero or more times • Repetition can be implemented by either iteration or recursion • General design issues for iteration control statements • How is iteration controlled? • Where is the control mechanism in the loop? • Logical pretest or posttest?
Iterative statements • Iteration is usually controlled by . . . • A counter • A evaluation of Boolean conditions Count-controlled loops Condition-controlled loops Collection-controlled loops
Counter-controlled loops • A counter-controlled loop usually includes . . . • A loop variable • Initial loop variable value • Terminal loop variable value • The counter increments with the default value (step size) • Design Issues • What are the type and scope of the counter? • What is the value of the counter at loop termination? • Should it be legal for the counter or loop parameters to be changed in the loop body? • If so, does the change affect loop control? • Should the loop parameters be evaluated only once, or once for every iteration?
Counter-controlled loops for ( [expr_1] ; [expr_2] ; [expr_3] ) [ loop_body] • C counter-controlled loops • The expressions can a sequence of statements, which separated by commas (,) • For example: for (i = 0, j = 10; j == i; i++ ) ● ● ● • Omit the second expression for an infinite loop • for(c = 'a'; c <= 'z'; c++) • printf("ASCII(%c) = %d\n",c,c); • for(;;){ • i++; • if(i > max) {break;} • printf("i = %d\n",i); • } • for(;c < max;){ • c++; • printf("c = %d\n",c); • }
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 of the variable is from the definition to the end of the loop body) n starts with a value of 0, and i with 100, the condition is n!=i (that n is not equal to i). Because n is increased by one and i decreased by one, the loop's condition will become false after the 50th loop, when both n and i will be equal to 50.
Counter-Controlled Loops: Examples • Java and C# • Differs from C++ in that the control expression must be Boolean for (int i = 1; i <= 5; i++){ Console.WriteLine(i); } for(intx = 10; x < 20; x = x+1){ System.out.print("value of x : " + x ); System.out.print("\n"); } Java C#
Condition-controlled loops • Design issue • Pre-testor post-test? • Pre-test: test the Boolean expression before loops • Post-test: test the Boolean expression after loops • Language examples • Pascal has separate pre-test and post-test logical loop statements • while-do and repeat-until • repeat-until exits with a truecondition a := 5; while a < 6 do begin writeln (a); a := a + 1 end; n:=0;t:=i; REPEAT n:=n+t; t:=t+1; UNTIL t>100;
Condition-controlled loops • C and C++ support both, but the control expression for the post-test version exits with a falsecondition • whileand do-while statements • Java is like C, except the control expression must be Boolean • And the body can only be entered at the beginning since Java has no goto • Perl has two pretest logical loops, while and until, but no posttest logical loop while ( x < 10 ) { printf( "%d\n", x ); x++; } do { c = input_char(); output_char(c); } while (c != '\n');
User-located loop control mechanisms • It is often convenient to exit a loop early • This causes no reliability problems • Design issue • Should the control be transferable out of more than one loop if loops are nested?
User-located loop control mechanisms • C , C++, C#, and Java use the break statement • Itis unconditional • It exits one level of loop/switch statement in C and C++ • Java, Pearl, and C# may include a label with break like Ada • C, C++, Java have the continuestatement • It skips the remainder of aiteration, but does not exit the loop
Syntax of Breakstatement • The break statement can be used in terminating all three loops: for, whileand do...while loops.
Example of Break statement /* C program to demonstrate the working of breakstatement by terminating a loop, if user inputs negative number */ # include <stdio.h> int main(){ float num,average,sum; inti,n; printf("Maximum no. of inputs\n"); scanf("%d",&n); for(i=1;i<=n;++i){ printf("Enter n%d: ",i); scanf("%f",&num); if(num<0.0) break; //for loop breaks if num<0.0 sum=sum+num; } average=sum/(i-1); printf("Average=%.2f",average); return 0; }
Syntax of Continue statement • It is sometimes desirable to skip some statements inside the loop. In such cases, continue statements are used.
Example of Continue statement //program to demonstrate the working of continue statement in C programming # include <stdio.h> int main(){ inti,num,product; for(i=1,product=1;i<=4;++i){ printf("Enter num%d:",i); scanf("%d",&num); if(num==0) continue; / *In this program, when num equals to zero, it skips the statement product*=num and continue the loop. */ product*=num; } printf("product=%d",product); return 0; }
Iteration Based on Data Structures • This concept is to include iterator operations in the behavior of a data structure for a collection • Usually, the iteration can use the following data-structure-specific method calls • start • getNext • advance • hasNext • … • Java • A user-defined collection that implements the Collectioninterface can be traversed with an implementation of the Iteratorinterface
Unconditional branching • Problem • Without restrictions imposed by the language or by programming standards, goto statements can make programs unreadable, highly unreliable, and difficult to maintain • Hard to read when execution order does match order of appearance • Break and exit sometimes improve readability, which are not bad • Some languages do not have them at all • For example, Java
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
Assignment Five • 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