
Understanding Control Structures in Programming
Explore the fundamentals of control structures in programming, including sequential, selection, repetition, unconditional branching, and subroutine calls with parameter passing. Learn about different types of selection statements and design considerations. Dive into one-way, two-way, and three-way selection structures, tracing their evolution from ALGOL to modern programming languages.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
Control Structures Programs utilize 4 basic control structures Sequential (default, no special instructions required) Selection Repetition Unconditional Branching GO TO statement (including break, continue) subroutine calls (those that involve parameter passing and a return location) For purposes of local scope and easier syntax, we can add blocks, or compound statements ALGOL 60 - first language to introduce blocks Pascal-like languages (including ALGOL) used begin-end C-like languages use { } Lisp uses ( )
Selection Statements Gives a program the ability to choose which instruction(s) to next execute based on conditions Types: 1-Way selection (if statement) 2-Way selection (if-else statement) 3-Way selection (FORTRAN s early if statement) multiple selection (or n-way selection, switch/case) Design issues: what is the form and type of expression that controls the selection? (C allows 0/non-0, Java/C# allow only boolean) how are clauses specified if at all? if nesting is allowed, how is it specified and implemented?
One-way Selection One-way: if without else if condition is true then execute next statement, otherwise skip over it originally, FORTRAN did not have a true IF statement, but when introduced, it was a One-Way selection only (no Else clause, no nesting) if the then clause has more than 1, instruction, we alter the semantics of the statement, to what is in essence an else-goto rather than, an if-then If (.NOT. Condition) GOTO 20 I = 1 J = 2 20 Continue nearly every language since has allowed two-way selections
Two-Way Selection ALGOL 60 introduced the first true two-way selection terms then-clause & else-clause introduced clauses are expected to be a single instruction to easily detect the end of each clause, otherwise, must use blocks ALGOL 60 allowed more than one entry into the two- way selection clauses! in languages where the then is omitted, the condition must be placed in ( ) to denote its end
Three-Way Selection Only available in FORTRAN IF (expression) N1, N2, N3 Meaning: if expression < 0 then goto N1, if = 0 goto N2, if > 0 goto N3 This was easy to translate into machine language code Evaluate expression JL N1 JE N2 JG N3 This was FORTRAN I-IVs only IF statement!
Blocks ALGOL introduced the block structure in part this allowed multiple instructions for the if/else clause it also can be used to show where an if clause ends to permit an else (this is what FORTRAN didn t have) blocks require delimiters begin .. end, { }, ( ) (Python uses indentation), here we see an example in ALGOL if (Boolean expression) then begin statement 1; ... statement n end; Ada and FORTRAN 95 have explicit end-type statements (e.g., endif, endfor)
Nesting Nested If-Then-Else statements can lead to ambiguity if there is a miss-match between conditions and else clauses In Perl, Ruby, ALGOL 60, FORTRAN 77/90/95, Modula-2 and Ada, all clauses must have explicit end statements (even if there is only a single statement in the clause) this avoids the dangling or mismatched else problem In C/C++/Java/C# and Pascal, a compiler rule matches mismatched elses with the last unmatched condition in order to the change this matching behavior, you must use blocks
Dangling Else Example if sum = = 0 then if count = = 0 then result = 0 else result = 1 end end Which condition does the else go with? Is result = 1 if sum != 0 or if sum = = 0 and count != 0? Example in C if(sum = = 0) if (count = = 0) result = 0; else result = 1; if sum = = 0 then if count = = 0 then result = 0 end else result = 1 end
Multiple Selection Constructs ALGOL-W introduced the case statement Pascal, Modula and Ada, FORTRAN 90/95 all use this C/C++/Java/C# use the switch statement implementation of the switch differs in that execution continues to test each condition even after a previous action executed unless you use break statements to fix this oddity, in C# you must end each case with a break or goto C# also permits string comparisons Lisp uses the COND statement which can utilize any form of condition, not just comparing an ordinal to a list of values all of these allow for a default if none of the cases is selected default in C-languages, else in Pascal, when others in Ada Perl/Python don t have a multi-selection statement at all!
Nested If-Else Constructs Cond in Lisp is really a nested if-then-else function Lisp also provides a default by using T as the final condition Other languages have provided a specific if-then-else nested construct for convenience Ada uses elsif if the intention is to do else if so that you do not have to explicitly end each if statement with an end if Python, among other languages uses elif so that you don t have to continue to indent Ada without elsif: if Count < 10 then Bag1 := True; else if Count < 100 then Bag2 := True; else if Count < 1000 then Bag3 := True; end if; end if; end if; Ada with elsif: if Count < 10 then Bag1 := True; elsif Count < 100 then Bag2 := True; elsif Count < 1000 then Bag3 := True; end if;
Repetition Statements Every language has included some form of repetition, either counter-controlled (early FORTRAN), logically- controlled, iterator-based or some combination Issues: how is repetition controlled? is testing before or after the loop body? (pre vs. post test) where should the control mechanism appear in the loop? for counter-controlled loops what are legal types and the scope of the loop control variable? what happens to the variable when the loop terminates? can the loop s controlling variables (terminating value, step- size) be altered during execution? are the loop controlling variables (terminating value, step-size) evaluated once (before executing the loop) or after each iteration? what are legal step-sizes (for counter-controlled loops)
FORTRANs DO statement DO label variable = initial, terminal [,step] example: Do 10 K = 1, 10 FORTRAN I IV: a posttest loop, stepsize defaults to 1 label is a line number that indicates the last instruction in the loop body this line usually has one instruction called CONTINUE as in 10 CONTINUE FORTRAN 77, 90 and 95: pretest loop Integers (literals or variables) only for initial, terminal, step the values of initial, terminal and step are computed prior to loop execution so that the number of loop iterations is computed at that time and static if a variable changes values during loop execution, it has no impact on the number of loop iterations
Example DO 10 I = J, K * 10, L K = K + 1 L = L + 2 10 CONTINUE initvalue = J terminalvalue = K * 10 stepvalue = L iterationcount = max(int((K*10 J) / L), 1) If J = 1, K = 5, L = 2, the loop would iterate 25 times in spite of K and L changing in the loop body In FORTRAN I-IV, this is a post-test loop so it must iterate at least 1 time, in later FORTRANs, this would become 0
ALGOL For Loop ALGOL 60 introduced an extremely flexible for loop as a response to FORTRAN s primitive and restrictive Do the programmer controls the number of iterations by a counter controlled mechanism like FORTRAN s DO but where the step size and terminating value could change during iterations enumerating a list of values to iterate through using a logical statement to control termination or any combination thereof Basic form: for <var> := <list>{,<list>} <list> <expr> | <expr> while <boolean> | <expr> step <expr> until <expr> do <stmt> <expr> can be a literal value or arithmetic expr
Examples for count :=1, 2, 3, 4, 5, 6, 7 do list[count]:=0 for count:= 1 step 1 until 7 do list[count]:=0 for count:=1, count+1 while (count <=7) do list[count]:=0 for I := 1, 4, 13, step 5 until 23, 3*I while I < 300, 8, -4 do the values for I iterate through: 1, 4, 13, 18, 23, 69, 207, 8, -4
Other Languages For Loops COBOL Perform <expr> Times <statements> End-Perform Perform Varying <var> From <expr> By <expr> Until <expr> <statements> End-Perform PL/I DO <var> = <start> TO <stop> {BY <stepsize>}; <statements> END; <start>, <stop> and <stepsize> can be int or float values like FORTRAN though, the values are only evaluated once before the loop starts can have multiple lists of <start> TO <stop> values DO I = 1 TO 10, 20 to 30, 50 TO 100; Ada for <var> in [reverse] <range> loop ... end loop <range> is a subrange as in 1..10 (the values can be ints or enumerated types)
Continued Pascal for <var> := <init> (to | downto) <final> do <var>, <init>, <final> are any ordinal type but are evaluated prior to the start of the loop step size is fixed as 1 or -1 (-1 for downto) Common Lisp: (do ((<var> <init> <step>)) ((<endtest> {. <result>})) <statements>) <init>, <step>, <endtest> and <result> can be functions or atoms <result> if specified is returned when the loop exits as this function s return value (otherwise the last <statements> s result is returned) <var> s scope is only for the loop itself Common Lisp also has the DOTIMES loop for a true counting loop
Iterator Loops Iterate once for each item in the specified list (or data structure) Algol s for loop has the capability of iterating over a list, but the list must be explicitly enumerated Python: for <var> in <range>: <range> will be a tuple or range(value [, value] [, value]) note that Python s for loop can also be a counting loop by using the range function as in for x in range(0, 10, 2) which iterates over 0, 2, 4, 6, 8, 10 C# has a foreach statement which can iterate across array elements Java 5.0 s for loop has been enhanced to work on objects of type Iterable Common Lisp has a dolist statement much like C# s foreach
Logically Controlled Loops Issues pretest vs. posttest (test condition before entry or after execution?) pre-test can block entry to loop body, post-test must execute body at least once in C, C++ and Java, the post-test loop has the same semantics as the pre-test loop: repeat while the condition is true in Pascal, the semantics are reversed: repeat until condition becomes false C-like languages, Pascal, Modula-2 have both pretest and posttest loops Ada only has posttest FORTRAN has no logically controlled loop (even FORTRAN 95) is this type of statement separate from the counter-controlled loop?
Exiting Loops Should exiting a loop only be permitted at the end when the test returns false or can premature exiting (and returning) be permitted? Ada has a conditional-less loop (infinite loop) which requires a GOTO to break out of loop ... end loop C/C++/Java/C# and Modula-2 have break, continue, exit (all forms of GOTO statements) Java has break and exit but not continue Multiple exits harm readability exception handling is a more reliable and readable way to go COBOL has an odd form of exception handling in loops Perform <paragraph> Thru <paragraph> both paragraphs are executed, if an error arises in the first paragraph, control exits to the second paragraph
Problems with Unconditional Branching Can make programs unreadable, harms readability and reliability making maintenance more challenging The GO TO statement is too primitive it is an invitation to make a mess of one s program GOTO statements are required in assembly/machine code because they do not have the high-level language constructs, but the high level languages should offer these constructs and let the compiler do the work Most languages have some form of GOTO statement Modula-2, Bliss, CLU, Euclid, Gypsy do not! Java has a GOTO, but it hasn t been implemented (yet) What we learned from FORTRAN was that the GOTO is not needed if you have good control statements
GOTO Labels Used in ALGOL 60, C, FORTRAN and Ada as locations for GOTO commands in Ada, <<label>> in FORTRAN and Pascal, unsigned integer constant (20, 100, etc...) in Pascal, labels must be declared as if they were variables (but cannot be modified or passed as a parameter) in C, ALGOL 60, any legal identifier Most languages restrict the use of unconditional branches with respect to which label can be reached in Pascal, the scope of the label is the same as the scope of a variable and the target of the GOTO must be within the control statement that includes the GOTO or a statement in the same group that contains the GOTO or in a statement in an enclosing subprogram scope