## PASCAL Programming: § 4: Selection and Iteration Structures

#### Instructor: M.S. Schmalz

A key feature of computer programs is decision making, where the program selects a result from among a list of alternatives. The PASCAL statements that support such decision making are collectively called selection structures and include the IF..THEN..ELSE and CASE statements. We will later see that the CASE statement is not in vogue (i.e., isn't used much) because it is harder to read clearly than an IF statement.

Computer program design is also facilitated by the use of program structures called loops that cause the block of statements within the loop to repeat or iterate. The latter term gives rise to the concept of iteration structures, which in PASCAL include the FOR, WHILE, and REPEAT statements.

This section is organized as follows:

4.1. Overview of Selection Structures
4.2. IF and CASE statements
4.3. Overview of Iteration Structures
4.4. WHILE, FOR, and REPEAT statements
4.5. Variable Loop Limits

In Section 4.1, we discuss the basic justification and concepts associated with iteration and selection structures, with examples of modularity in the block-IF statement. We then discuss usage of the IF and CASE statements (Section 4.2). An overview of iteration structures is given in Section 4.3, with usage of the WHILE, FOR, and REPEAT statements discussed in Section 4.4. The final topic of this section is the use of variable loop limits, which allows you to "customize" a loop with limit values that are passed into a procedure through its argument list.

### 4.1. Overview of Selection Structures.

We begin with several observations about decision making in computer programs.
• Observation. In the early days of computer programming, when programmers did not have high-level languages like PASCAL, it was very difficult to make decision structures. One had to use assembly language constructs such as branch-on-zero and formulate decision tests based on numeric values. In contrast, humans tend to make decisions based on non-numeric and qualitative criteria. Since digital computers currently use only ones and zeroes, we have to find a way to reduce the decision tests to those simple values.

Definition. A logical operator is an operation that inputs one or more values equal to zero or one, and outputs a zero (i.e., logical false) or a one (i.e., logical true).

Definition. A relational operator is an operation that inputs one or more numeric or alphabetical values and compares them to a prespecified criterion (e.g., is x greater than 3?). The result of a relational operator is a zero, if the test that the operator implements fails, and a one if the test succeeds.

Definition. A logical predicate is comprised of one or more logical or relational operations, and produces a zero or one as a result.

Definition. A Boolean value is a one or a zero.

Definition. The logical operators NOT(x), AND(x,y), and OR(x,y) are defined as follows, where x and y) are Boolean values:

```     NOT(x)    x=0  x=1
--------+----------+
|  1    0  |
+----------+

AND(x,y)  x=0  x=1
--------+----------+
y=0   |  0    0  |
|          |
y=1   |  0    1  |
+----------+

OR(x,y)   x=0  x=1
--------+----------+
y=0   |  0    1  |
|          |
y=1   |  1    1  |
+----------+
```

Definition. The relational operators are defined as:

```   NAME             SYMBOL     MEANING
---------------  ---------- -------------------------------------
greater-than     x >  y     "x" is greater than "y"
greater-equal    x >= y     "x" is greater than or equal to "y"
equals           x ==  y    "x" equals "y"
not-equals       x <> y     "x" does not equal "y"
less-equal       x <= y     "x" is less than or equal to "y"
less-than        x <  y     "x" is less than "y"
```

Observation. As we mentioned in Section 3, various attempts have been made to render computer languages more like English. One of the key constructs in this effort is the IF..THEN..ELSE statement, which is structured as follows:

```       IF logical-predicate THEN
-- statements to execute if the
predicate evaluates to true --
ELSE
-- statements to execute if the
predicate evaluates to false --
ENDIF
```
Example. Suppose your program has a flag (a logical or Boolean decision variable) that causes statements to be printed to your computer monitor. For example:
```       IF flag THEN
WRITELN('Flag is true')
ELSE
WRITELN('Flag is false')
ENDIF
```

Remark. PASCAL facilitates decisions among multiple alternatives via the BLOCK-IF statement, which is comprised of multiple IF..THEN..ELSE statements that are chained together, as follows:

```       IF predicate-1 THEN
-- statements to execute if
predicate-1 evaluates to true --
ELSEIF predicate-2 THEN
-- statements to execute if
predicate-2 evaluates to true --
ELSEIF
...
ELSEIF predicate-n THEN
-- statements to execute if
predicate-n evaluates to true --
ELSE
-- statements to execute if the preceding
predicates all evaluate to false --
ENDIF
```

In the 1970s, programming language designers were looking for simpler ways to write statements that were previously involved expressions. Since the programmers made more errors on complex statements, it seemed reasonable to attempt to distill the BLOCK-IF into a more concise representation. In PASCAL, this representation is called the CASE statement. Instead of relational operators, the CASE statement simply specifies possible values for a variable, together with statements to be executed if that variable has a given value. For example, consider the following CASE statement (written in pseudocode) for a academic grade evaluation:

```       CASE OF grade:
'A':  WRITELN('Excellent work!');
'B':  WRITELN('You did well...');
'C':  WRITELN('Average performance.');
'D':  WRITELN('Needs some improvement...');
END-CASE
```
Certainly this simple instance of the CASE statement is easier to read than the corresponding BLOCK-IF statement:
```       IF grade == 'A' THEN
WRITELN('Excellent work!')
WRITELN('You did well...');
WRITELN('Average performance.');
WRITELN('Needs some improvement...');
ENDIF
```
The problem with CASE statements occurs not when the statement blocks are small, or when there are a few alternatives. Rather, the CASE statement begins to defeat its design goal of conciseness and readability when the blocks of statements become large or when there are many alternatives. In such expressions, a given CASE statement may span several pages or more. When you are trying to debug such statements, it becomes very difficult to remember where you are in the statement, and one tends to feel lost. As a result, we prefer to use only IF or BLOCK-IF statements for decision structures.

### 4.2. PASCAL Selection Structures.

The PASCAL language provides IF or BLOCK-IF constructs, where the latter is a variation of the IF statement, as discussed in Section 3.1. We define these statements as follows:

`IF..THEN..ELSE` statement:

Purpose: The IF statement provides a mechanism for decision based on a logical predicate.

Syntax: ```IF predicate THEN actions-if-predicate-is-true ```

`ELSE actions-if-predicate-is-false ; ` , where

`actions-if-predicate-is-true` are one or more PASCAL statements

`actions-if-predicate-is-false` are one or more PASCAL statements

Example:

```IF ((score > 90) AND (score <= 100)) THEN
ELSE
WRITELN('You did not get an A')
;
```

Notes: When single statements are used in an IF statement block, one must take care not to put a semicolon after the statement that follows the IF...ELSE block. Otherwise, the PASCAL compiler will infer that the IF statement should be terminated at the semicolon. So, the semicolon goes after the ELSE predicates, as shown above. When the IF statement is used to execute large blocks of compound statements, then the BEGIN..END construct should be used to delimit those statement blocks.

`IF..THEN..ELSEIF..THEN..ELSE` (Block-IF) statement:

Purpose: The Block-IF statement provides a mechanism for decision based on multiple logical predicates. This can be useful for grouping data items into prespecified categories.

Syntax: ```IF predicate1 THEN actions-if-predicate1-is-true ```

```ELSEIF predicate2 THEN actions-if-predicate2-is-true : ELSEIF predicateN THEN actions-if-predicateN-is-true ELSE actions-if-predicates-are-false ;``` , where

`actions-if-predicate-is-true` are one or more PASCAL statements

`actions-if-predicate-is-false` are one or more PASCAL statements

Example:

```	 IF ((score > 90) AND (score <= 100)) THEN
ELSEIF ((score > 80) AND (score <= 90)) THEN
ELSEIF ((score > 70) AND (score <= 80)) THEN
ELSEIF ((score > 60) AND (score <= 70)) THEN
ELSE
WRITELN('You got an E')
; ```

PASCAL also supports nested decision structures, in which an IF statement contains other IF statements in its list of executable statements. This allows the programmer to specify decisions based on concepts or criteria that are hierarchically structured.

### 4.3. Overview of Iteration Structures.

We begin with several observations about iteration in computer programs.
• Observation. In the early days of computer programming, when programmers did not have high-level languages like PASCAL, the programming of repetitive sections of code was quite clumsy. For example, to make a section of code repeat N times, one had to use assembly language constructs that incremented a counter and tested it against N, using branch-on-zero and the infamous go-to for transferring control to the partition of code that executed after the loop ended. If the programmer did not code the loop properly, the loop could keep running... and running...forever (or until the computer was powered down). This condition is called an infinite loop, and is more difficult to accidentally program in Pascal than in assembly language.

Definition. A loop is a section of code that repeats itself.

Definition. A loop index or loop counter is an integer variable that is used to keep track of how many times a loop has executed.

Definition. A loop limit is a variable or constant that is integer-valued, which determines the number of times a loop will execute, or a maximum value of the loop index to be reached at loop termination.

Definition. A loop increment is the step size for incrementing the loop counter.

Example. The following pseudocode fragment

```     WRITELN('before loop starts')
FOR i = 1 TO 5 DO:
WRITELN('iteration number ',i)
ENDFOR
WRITELN('after loop ends')
```
generates this output on the computer monitor:
```     before loop starts
iteration number 1
iteration number 2
iteration number 3
iteration number 4
iteration number 5
after loop ends
```
Here, the loop index is the variable "i", and the loop limits are one and five, with an implicit loop increment of one.

Definition. In certain kinds of loops (WHILE..DO and REPEAT), there is no loop index, but a loop predicate that is a logical predicate (defined in Section 4.1). When the predicate evaluates to false, the loop terminates.

Example. Let's rewrite the preceding FOR loop as a loop with a predicate. The following pseudocode fragment

```     WRITELN('before loop starts')
i := 0                             ## Initialize counter variable
WHILE (i <= 5) DO:                 ## Loop with predicate in ()
i := i + 1                       ## Increment counter variable
WRITELN('iteration number ',i)
ENDFOR
WRITELN('after loop ends')
```
generates the same output as before, namely,
```     before loop starts
iteration number 1
iteration number 2
iteration number 3
iteration number 4
iteration number 5
after loop ends
```
Here, the loop predicate is the relational test "`i <= 5`", which causes the loop to terminate after i is incremented to six.

• Question. Apart from basic knowledge about iteration structures, what can we learn from the preceding examples?

Answer. First observe that the WHILE..DO loop is more tedious to write and understand than the FOR loop, because the WHILE loop requires that the predicate variable (in this case, "i") be changed within the loop. In contrast, the FOR loop increments and keeps track of i internally (i.e., in a manner transparent to the programmer).

Second, the WHILE..DO construct only executes the loop contents while the predicate is satisfied. As soon as the predicate evaluates to false, the loop terminates.

Example. Consider a situation where one adds characters to a word to form a prespecified test word, as in the following pseudocode:

```     WRITELN('before loop starts')
string := 'ADDIS A'               ## Initialize test variable
test   := 'ADDIS ABABA'           ## Test value to stop loop on
WHILE string <> test DO:
WRITELN('string = ',string)     ## Show string before it's modified
string := string || 'AB'        ## Append "AB" to the string
WRITELN('string = ',string)     ## Show string after it's modified
ENDFOR
WRITELN('after loop ends')
WRITELN('string = ',string)       ## Write final value of string
```
which forms this output:
```     before loop starts
after loop ends
```
• Question. What happened -- why did the string "ADDIS ABABA" not get printed within the loop? Why did we have to add a WRITELN statement after the loop to print it?

Answer. The WHILE loop iterates until the predicate is satisfied. In the above example, the predicate tells the runtime module to stop executing the loop when string equals "ADDIS ABABA". That means that as soon as the string equals the test value of ADDIS ABABA, then the loop terminates. Thus, the value of the completed string never gets written from inside the loop. Hence, the value of string must be written outside the loop. Since flow of control is sequential, this means that the WRITELN statement must be placed at the end of the loop.

• Observation. Suppose we want to have the loop execute completely at least once. This can be done by modifying the WHILE loop so that the controlling predicate is at the end of the loop, instead of at the beginning.

Example. Contrast the following pseudocode fragment with the WHILE loop example that we just discussed:

```     WRITELN('before loop starts')
string := 'ADDIS A'               ## Initialize test variable
test   := 'ADDIS ABABA'           ## Test value to stop loop on
REPEAT                            ## Start loop
WRITELN('string = ',string)     ## Show string before it's modified
string := string || 'AB'        ## Append "AB" to the string
WRITELN('string = ',string)     ## Show string after it's modified
UNTIL (string == test)            ## Test for loop termination
WRITELN('after loop ends')
WRITELN('string = ',string)       ## Write final value of string
```
which forms this output:
```     before loop starts
after loop ends
```
Note that the output is the same, but the loop structure is different, because the predicate is expressed using the opposite relational operator (i.e., "==" instead of "<>"). This is due to the semantics or meaning of the statement
`WHILE (x is true) DO <statements>`
which has the same meaning as
`REPEAT <statements> UNTIL (x is false)`
Thus, a WHILE loop can be approximated by a REPEAT loop merely by moving the predicate to the end of the loop and negating the logic of the predicate.

We next examine the PASCAL syntax of the FOR, WHILE, and REPEAT loops.

### 4.4. PASCAL Iteration Structures.

PASCAL supports the following three iteration structures:

`FOR` loop:

Purpose: Repeat statements within the loop while the loop index is incremented within specified bounds.

Syntax: ```FOR loop-index := initial-value TO final-value DO ```

`statements ;` , where

`loop-index` is the counter to be incremented

`initial-value` is the beginning value of the loop index

`final-value` is the ending value of the loop index

Example:

```     n := 5
FOR i := 1 to n DO
WRITELN('i = ', i) ;
```

Notes: In the preceding example, we have used a parameterized loop, whereby the variable n contains the loop index' final value. This technique is useful in software engineering and will be discussed in greater detail in Section 4.5.

`WHILE..DO` loop:

Purpose: The WHILE loop is also called a conditional loop, since it terminates based on a condition encoded in a logical predicate.

Syntax: ```WHILE predicate DO statements ;``` , where

`predicate` is the controlling condition.

Example:

```     x := 10
WHILE x > 5 DO
BEGIN
x := x - 2
WRITELN('x = ', x)
END; ```

`REPEAT..UNTIL` loop:

Purpose: The REPEAT loop is another example of a conditional loop.

Syntax: ```REPEAT statements UNTIL predicate;``` , where

`predicate` is the controlling condition.

Example: (approximation of previous WHILE loop)

```     x := 10
REPEAT
BEGIN
x := x - 2 ;
WRITELN('x = ', x);
END;
UNTIL x <= 5 ; ```

In the example of the FOR loop, we saw how a variable could be used to specify a loop index. We next elaborate this technique, and show how it can be used to encapsulate a loop in a procedural construct.

### 4.5. Variable Loop Limits.

It is not difficult to use PASCAL constructs to write flexible loops. Here follows a simple example of a loop encapsulated in a procedure:
```   PROGRAM TestLoop;              {Program specification}
VAR x,y: integer;            {Declare variables x,y as integer}

PROCEDURE Loop(x,y:integer); {Function specification: inputs}
VAR i: integer;            {Declare loop index}
BEGIN                      {Function begins here}
FOR i := x TO y DO       {Loop specification}
WRITELN('i = ', i);    {Loop contents or body}
END;                       {Function ends here}

BEGIN                        {Program begins here}
x := 4;                    {Assign starting loop index value}
y := 7;                    {Assign ending loop index value}
Loop(x,y);                 {Call to procedure "Loop"}
END.                         {Program ends here}
```
In the preceding PASCAL code, note that the VAR statement specifies a variable of integer datatype. In this case, the variables x and y are specified as integers. Additionally, the `WRITELN` statement outputs the value of i to the screen, as follows:
```     i = 4
i = 5
i = 6
i = 7
```
per the preceding discussion.

Variable loop limits are especially useful when performing tasks in image and signal processing or database manipulations, where the data structure size is parameterized, i.e., can be changed by changing a value encoded in a variable. For example, one often processes images of varying size, cuts or pastes parts of images, etc. By having variable loop indices, you do not need to recode each loop explicity with different limits for different sized images. Once you know how large the image is, you can merely pass the loop limits through the procedure call's argument list and constrain processing to any size image or neighborhood of an image that is within the prespecified array limits.

Good software engineering practice dictates that all loop limits be specified in terms of variables if the loop is to be called from within a procedure, and the loop limits are at any time expected to be flexible. Rather than having to recode a program with variable loop limits (which can be a difficult task), variable limits that are already implemented make the task of resizing a loop much easier. As noted previously, this facilitates modularity and portability of PASCAL code, and makes debugging much easier.

This concludes our overview of selection and iteration structures in PASCAL.
We next discuss PASCAL files, file I/O, and arrays.