statement level flow of control selection structures copyright © 2003-2014 by curt hill

40
Statement Level Flow of Control Selection Structures Copyright © 2003-2014 by Curt Hill

Upload: baldwin-preston

Post on 26-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

Statement Level Flow of Control

Selection Structures

Copyright © 2003-2014 by Curt Hill

Copyright © 2003-2014 by Curt Hill

Control Structures• In the beginning was FORTRAN• FORTRAN reflected the machine

that it was designed on: IBM 704• It had five control structures:

– Unconditional GOTO– Logical If– Arithmetic If– Do loop– Computed GOTO

• We should be critical but they just did not know any better

1 and 2 of the Five• Unconditional GOTO

GOTO 5– FORTRAN was column oriented and

statement labels were numbers– These resided in columns 1-5

• Logical ifif (a.gt.e) GOTO 12– It could only have one statement

following it and not every statement either

– Usually an assignment or goto

Copyright © 2003-2014 by Curt Hill

3 and 4 of the Five• Arithmetic if

if(a)10,20,30– A must be an integer– Then we branched to one of the three labels

based on A negative, zero or positive

• Do loopdo 15,i=1,10,2– Similar to the counting for of many languages– First number was the last statement of the loop– There was an assignment, limit and increment– The do was actually a trailing decision loop

Copyright © 2003-2014 by Curt Hill

Last of the Five

• Computed GOTOgoto (10,15,20,5,30), i– Precursor to a case– If i = 1 goto first label– If i = 2 goto second label etc

– All of these translated directly into 704 machine language

Copyright © 2003-2014 by Curt Hill

Is that the best we can do?• In those days we did not know what

would make for good programming practices, but in the early sixties the goto wars began

• Those who only knew Assembly or FORTRAN or COBOL got carried away and used gotos to make some rather beastly execution flows– These were motivated by efficiency– Machines were quite expensive and

people still relatively inexpensive (>$5/CPU second)

Copyright © 2003-2014 by Curt Hill

What’s wrong with this?

Copyright © 2003-2014 by Curt Hill

IF (A.GT.B) GOTO 20. . .

50 IF (A.EQ.C) GOTO 70 A = B * C20 IF(C.EQ.0) GOTO 90

A = A * 2IF (R.GT.2) GOTO 40C = A+B*2-CIF(B.GT.C) GOTO 50READ(*,5)R,C

40 B = B + R - CGOTO 50. . .

70 CONTINUE . . .90 CONTINUE

The GOTO Wars• The Structured Programming

types coined the term spaghetti code to describe how these programs used flow of control– These were led by Dijkstra and

others

• The war was fought in the Journals– Titles: goto considered harmful

Copyright © 2003-2014 by Curt Hill

Crushing Victory

• In 1966 Bohm and Jacoppini proved that any program could be written with just three structures: sequence, if and while– This cut the theoretical ground

out from under the GOTO proponents

– The war did last several more years

Copyright © 2003-2014 by Curt Hill

Last Shot• The last shot was in 1974 when

D.E. Knuth published Structured Programming with GOTOs– Among other things it said that

good programmers used the GOTO in a way that was reasonable before there were languages that supported it

– This was almost a face saving article on behalf of the GOTO crowd and marked the end of the war

Copyright © 2003-2014 by Curt Hill

Preprocessors• By the late sixties there were a

number of preprocessors for FORTRAN that would make real control structures and translate them into if-goto structures– These did what the compiler did in

assembly language: convert nice structures into what the machine has

• However the languages that supported structured programming rapidly supplanted FORTRAN as the king of the languages

Copyright © 2003-2014 by Curt Hill

Three or More?• Just because you can program

with just the three does not mean that we should only have the three– Writability is aided by more– Structured programming does

demand that each control structure be single entry and single exit

– The worst control structure ever created was a multiple entrance, multiple exit loop

– However, multiple exit loops are not a problem

Copyright © 2003-2014 by Curt Hill

Compound statements• FORTRAN’s flow of control would

not have been near the problem if the IF could have had multiple statements

• Forcing a GOTO after an IF made it seem like the GOTO was the correct statement– Recall Sapir Whorf hypothesis

• ALGOL 60 introduced the compound statement, which was a BEGIN - END similar to what we see in its descendants Pascal and Ada

Copyright © 2003-2014 by Curt Hill

Compound Statements

• The ALGOL 60 compound statement was called a block and was stronger than the compound statement in Pascal or C– It allowed declaration of variables

and scope

• C++ and Java also allow this more general block in that you can declare variables but not always new functions

Copyright © 2003-2014 by Curt Hill

Selection statements

• The design issues:– How many ways?

•1, 2, many

– What controls the selection? Form and type?

– What restrictions on what statement(s) are controlled?

– Nesting of selections?

Copyright © 2003-2014 by Curt Hill

One way• The FORTRAN IF was one way• It had a one statement then• It had no else, which if needed

was constructed using GOTOs• A boolean controlled it, but the

statement was only executed on true

• It also used negative logic– The if said when to GOTO which

bypassed the next statements rather than the condition to execute them

– Thus the next statement was an elseCopyright © 2003-2014 by Curt Hill

Two Way• ALGOL 60 had the one way and

also had two way• It introduced the THEN and

ELSE as well as the block• Most languages have followed

this pattern since then• FORTRAN 66 did not but 77 did

Copyright © 2003-2014 by Curt Hill

Nesting• The two way if makes nesting a

problem• If an if is in an if who gets the

else?• The Pascal solution is to give

the else to the first unmatched if– Use a compound statement to

override that approach– This takes a disambiguation rule,

since the grammar is actually ambiguous on this point

Copyright © 2003-2014 by Curt Hill

Language Choices• The ALGOL 60 solution is to

disallow an if as the then statement– Especially since it introduced blocks– C and C++ follow Pascal

• Perl forces all thens and elses to be compound statements

• Ada has different endings for different things– Thus an IF always starts an implied

compound statement

• Python uses indentationCopyright © 2003-2014 by Curt Hill

Python Example

Copyright © 2003-2014 by Curt Hill

if sum == 0 : if count == 0 : result = 0 else : result = 1

Syntactic boundaries• Where does the condition end and

the executable statement begin?• In FORTRAN I you could only compare

a variable to a variable or constant– There were ANDs/ORs added later– Thus it was easy to tell what came next

• In most later languages an expression may be on both sides of a the relational and there are complications added by ANDs and Ors

Copyright © 2003-2014 by Curt Hill

Boundaries• Pascal has a THEN to terminate

its if condition• C/C++/Java enclose the condition

in parentheses so do not need a Then

• All of these only allow a single statement for the then or else, so the compound statement is heavily used

• When an END or } is encountered it is not obvious what started it

Copyright © 2003-2014 by Curt Hill

Ada and Boundaries• Ada uses another approach

– It uses end if to terminate an if so does not need the compound statement

– The then part starts with THEN and ends with ELSE or END IF

– This also straightens out the nesting issues

• Modula 2 closes every control structure with end, which is somewhat similar to Ada but less readable

Copyright © 2003-2014 by Curt Hill

Need for Multiways

• Very often we run into situations like the following– Series of Ifs– The then part does something– The else part is another IF– The comparison condition is

always the same: variable = constant

– All ifs have the same variable, but different constants

Copyright © 2003-2014 by Curt Hill

Multiway Selectors• The design issues:

– About the same as Ifs– What controls the selection? Form

and type?– What restrictions on what

statement(s) are controlled? Single, sequences or compound statements?

– How to encapsulate the statement?– May just a single segment be

executed?– What to do about unrepresented

values?

Copyright © 2003-2014 by Curt Hill

FORTRAN• The FORTRAN arithmetic if and

computed goto are the first• Computed GOTO

goto (10,15,20,5,30), i– If i = 1 goto first label– If i = 2 goto second label etc

• Arithmetic ifif(a)10,20,30– Then we branched to one of the

three labels based on A negative, zero or positive

Copyright © 2003-2014 by Curt Hill

FORTRAN Problems

• These are much more insidious than modern cases because the target labels can be anywhere in the program – before or after

• Moreover these labels may be accessed by other GOTOs– This violates single entry principle

• These are strongly based on IBM 704

Copyright © 2003-2014 by Curt Hill

A Modern Case?• ALGOL-W was the first with a

near modern case• The statements are numbered

by occurrence without a label• The case selector must be a

positive integer• Each statement may be a

compound statement

Copyright © 2003-2014 by Curt Hill

ALGOL W Case

Copyright © 2003-2014 by Curt Hill

case j of begin x:=5; // Chosen by j=1 begin // Chosen by j=2 r := 2; s := x*r; end; z := 0;// Chosen by j=3 end

Pascal generalizes this• Case labels explicitly identify the value • The label and the selector must match

and be ordinal type• The labels can be in logical not

numeric order• This allows negative and non-

contiguous values as well• Subranges of values and lists of values

are allowed• No option for an ELSE clause though

most dialects have a non-standard way to do it

Copyright © 2003-2014 by Curt Hill

Pascal Case

Copyright © 2003-2014 by Curt Hill

case color of blue: x := 5; red,green: begin

r := 2; j := 5; end; end;

C Family

• The C, C++, Java switch is primitive– The lack of a break allows multiple

segments to be executed– The case makes for difficult ranges– However the default is good

• The Ada case follows Pascal in function (slightly different form) but has an others clause

• FORTRAN 90 is similar to AdaCopyright © 2003-2014 by Curt Hill

C Example

Copyright © 2003-2014 by Curt Hill

switch (i) { case 2: r = 4; j = 5; // allows drop into case 5: x = 7; break; default: x = 0; }

Ruby Example

Copyright © 2003-2014 by Curt Hill

leap = case

when year % 400 == 0 then true

when year % 100 == 0 then false

else year % 4 == 0

end

Implementation

• Conversion into nested if then else• Table of addresses

– Search it– Hash into it– Jump into it

• This only works for contiguous values

Copyright © 2003-2014 by Curt Hill

Multiple nested ifs• Recall that the switch or case

statement is not very general– Series of Ifs– The then part does something– The else part is another IF– The comparison condition is always the

same: variable = constant– All ifs have the same variable, but

different constants

• In some sense the case generalizes the if from Boolean to other ordinal values

Copyright © 2003-2014 by Curt Hill

Is that good enough?• There are many more situations

where this kind of structure does not work but we still have the if then else if then else if form– But the form of the condition is

different

• How can this be handled?• The default is that each if should

have its own complete structure– Pascal, C family– This can be error prone when it is

deeply nestedCopyright © 2003-2014 by Curt Hill

Ada Does Better

• Ada allows an elsif which condenses the amount of writing for deeply nested if then elses

• It also allows fewer end items• Notice that the difference

between a case and nested if is that the case only examines one expression to determine the selection

Copyright © 2003-2014 by Curt Hill

Ada Example

Copyright © 2003-2014 by Curt Hill

-- Increment NumPos/Neg/ZeroIF X > 0 THEN NumPos := NumPos + 1;ELSIF X < 0 THEN NumNeg := NumNeg + 1;ELSE -- X is zero NumZero := NumZero + 1;END IF;

Now What?

• This concludes selection statements– Except guarded statements

• Next we need to consider looping

Copyright © 2003-2014 by Curt Hill