## Control-of-Flow Constructs FOR, WHILE, IF and SWITCH

The MATLAB language has the following constructs for controlling the logical flow of information in a script or function

• Fixed repetition - the for loop
• Indefinite repetition - the while loop
• Single decision - the if/else construct
• Multiple options - the if/elseif/else construct
• Multiple options with multiple tags - the switch construct

[Back to main page] [Back to language features]

The FOR construct is a control construct used to repeat a set of calculations or operations a definite (or pre-determined) number of times. The syntax of the for-loop is

```   for expression

statements

end

```

The keywords for and end define the body (or extent) of the loop. If either of these keywords is omitted, the loop will not work and you will get an error. Hence, you should always match the for/end pairs when entering code containing these loops.

The flow-chart to the right illustrates the flow of logic in a for-loop. When a for-loop is encountered in the flow of the logic of a program, the loop expression is evaluated and the first element (if the expression involves a vector) or first column (if the expression involves an array) is extracted and assigned to a loop variable (the left-hand side of the loop expression). If the loop variable is not empty, the statements within the body of the loop are executed.

When the loop statements are finished, the flow of logic then returns to the loop expression to get the next value of the loop variable. If a value is not available, the loop is exited. Otherwise, the statements in the loop are re-executed. The looping operation is continued until all the values available in the loop expression have been used (or a break statement is encountered).

As noted, the shape characteristics of expression determine the specific number of times that the statements are repeated. The following examples provide an overview of this feature of a for-loop.

Example 1: Working through the elements of a vector

The following code fragment will cycle through the elements of the vector v, displaying the value of the element and the value of the square root of that element in subsequent passes through the loop.

```    v = [1 4 2 7];
for s = v
disp(' ')
disp(s)
disp(sqrt(s))
pause(1)
end
```
In this case, the loop expression is the assignment s = v and the loop variable is s. The body of the loop is composed of the two disp statements. Each time through the loop, s is assigned to the "next" element in v (with MATLAB keeping track of which element from v is the current element).

Example 2: An alternative way of working through a vector

An alternative way of writing the loop in Example 1 is to be explicit about which element is involved by forming (in the loop expression) and using (in the body of the loop) an index variable.

```    v = [1 4 2 7];
for j = 1:length(v)
disp(' ')
disp(j)
disp(v(j))
disp(sqrt(v(j)))
pause(1)
end
```

The expression (the assignment of the integers 1 to 4 to the variable j, in this case) creates a loop index variable which is useful in calculations that deal with the index of an element in a vector rather than the value of that element.

While equivalent to the loop in Example 1, the index-explicit form has some advantages over the index-implicit form. First, the loop index variable tells you what cycle through the loop you are on which is helpful for generating progress displays (such as using the value of j to generate a message such as "You are on turn 7 of 52 turns.").

Also, knowing what index is "current" allows you to access the elements of other vectors that might be involved in the calculations within the body of the loop. For example, the array product of two vectors (a.*b) requires the use of an explicity created indexing variable:

```    a = [1 5 2 7];
b = [4 1 8 4];
for j = 1:length(a)
disp(' ')
c(j) = a(j)*b(j)
pause(1)
end
```

Each time through the loop, a different element of the result (c) is created and the value of j for the particular pass permits precise identification of that element.

[NB. Explicit loops that accomplish array operations are slower than the array operation they mimic. Whenever possible, you should vectorize you code by using array operations rather than loops.]

Example 3: Working through the columns of an array

If expression involves an array variable on the right-hand side, loop deals with the columns of that array. For example,

```
array = [3 4 1 7
1 9 5 2];

for vector = array
disp(' ')
disp(sum(vector))
pause(1)
end
```

sequentially displays the sums over the columns of array (equivalent to what the built-in function sum would do).

An equivalent, index-explicit version of this loop can also be created.

```
array = [3 4 1 7
1 9 5 2];

for j = 1:size(array,2)
disp(' ')
disp(j)
disp(sum(array(:,j)))
pause(1)
end
```
The advantages of the explicit version are that you are not forced into using the columns of a variable and that you are able to address the elements in variables that are not involved in the expression portion of the for-loop.

Example 4: Nesting for-loops

No, this has nothing to do with birds. "Nesting" refers to the act of putting a for-loop within a for-loop. The idea is not too complicated as the following example shows:

```
a = [1 3 5 ; 4 1 7];
[r,c] = size(a);
for j = 1:r
disp(['Row #',int2str(j)])
for k = 1:c
disp(sprintf('Element (%.0f,%.0f) is %.1f',j,k,a(j,k)))
pause(1)
end
end
```

The two loops "walk" though the array (by rows) and display the value found at the j,k element of the array.

While not complicated, for-loops (nested or not) can lead to problems that prevent your code from running or lead to mysterious results. Such problems can be avoided if you follow these rules

• Always match the number of fors with the number of ends.
• Never change the value of the loop variables or index variables within a loop.

Keeping these guides in mind will eliminate many hours of tedious debugging.

The WHILE construct is related to the FOR construct in that it creates a loop that repeats a set of statments. The primary difference is in the number of times the loop statements are executed. A for-loop repeats a pre-determined number of times (set by the nature of the loop expression). A while-loop repeats an indefinite (and potentially infinite) number of times.

The syntax of the while-loop is

```   while logical_expression

statements

end
```

The keywords while and end define the body (or extent) of the loop. If either of these keywords is omitted, the loop will not work and you will get an error. Hence, you should always match the while/end pairs when entering code containing these loops.

The flowchart to the right illustrates the flow of logic in a program when it encounters a while-loop. Before the loop can begin, a test variable for the loop must be created. The nature of the test variable is problem-specific and the examples below will help you see what is possible.

Once the test variable is defined, the loop begins by evaluating the loop expression. In contrast to the assignment expression in a for-loop, the loop expression in a while-loop is a logical expression (i.e., it has a yes/no, 0/1, true/false result) that involves the test variable. If the loop expression is true (yes, 1), the statements in the while-loop execute. Once a false (no, 0) result is encountered, the loop terminates and the program continues.

IMPORTANT: The test variable must be updated withing the loop. Failure to allow for updating will lead to the dreaded infinite loop (i.e., your program will never terminate).

The following examples illustrate some common uses and constructions of the while-loop.

Example 1: Moving through a vector

You can use a while-loop to access the elements of a vector in a fashion similar to a for-loop. The key issue is knowing when to stop. The following code fragent shows how to do this:

```
v = [2 8 5 9];
j = 1;                    % set the test variable
while j <= length(v)
disp(' ')
disp(v(j))
j = j + 1;             % update test variable
end
```

Note that it is very important to update the index (j). If not, the loop would forever display the first element of v.

Example 2: Meeting a criterion

while-loops are key constructs in many numerical algorithms. For example, a common activity is to iterate on a function to find a root. However, you do not generally know how long it will take to find the root and so you cannot use a for-loop construct to implement the algorithm (directly).

As a specific example, consider finding the square root of 2 via Newton's Method. In this approach, you start off with a guess and then refine that guess (iteratively) until some desired level of accuracy is obtained.

```
guess = 2;
err = 1000;                   % initialize test variable
tolerance = 1e-6;
while abs(err) > tolerance
old = guess;
guess = (guess + 2/guess)/2   % refine guess
err = old - guess;            % important update!
end
disp(err)
```

Example 3: Using an infinite loop

There are instances where an infinite loop is the "best" construct for implementing an algorithm. For instance, MATLAB can be thought of as using an infinite loop (the prompt at the command line) which is broken only when you quit the program.

A simple example of using an infinite loop productively is as follows:

```
while 1
name = input('What is your name? ','s');
if isempty(name)
break             % the exit!
end
end
```
Note that no test variable is used (the loop expression is always true!). To terminate the loop, an if construct is used that allows the loop to be broken if no name is entered.

Obviously, more complex logic can be incorporated into such a loop (the MATLAB command line is an example, as mentioned previously) but the key issue to using an infinite loop productively is to provide the exit!

The IF/ELSE construct

An IF construct is a decision construct as opposed to a repeat construct. The if construct allows you to conditionally (or optionally) execute blocks of code.

The simplest form of the if construct has the following syntax

```   if logical_expression

block #1 statements

else

default statements

end```

The keywords (if, else and end) define the construct and separate the statements into blocks that are executed in a mutually exclusive fashion (i.e., one or the other of the two statement blocks is executed but not both). The else keyword (and the associated block of "default" statements) may be omitted but the if and end keywords may not.

The flow diagram to the right illustrates the flow of the logic in a program when an if-construct is encountered. Once the test variable is defined, the logical expression associated with the initial if keyword is evaluated. If the result is "true", the statements between the if and else keywords (or the if and end keywords, if the else is omitted) are executed and the flow continues after the end keyword.

If the result of the logical expression is "false", the statements between the else and end keywords are executed. If the else keyword is omitted, the if-construct essentially skips the block of statements that it contains.

The IF/ELSEIF/ELSE construct

The general form of the if construct has the following syntax:

```   if logical_expression #1

block #1 statements

elseif logical_expression #2

block #2 statements

:
:

elseif logical_expression #k

block #k statements

:
:

elseif logical_expression #n

block #n statements

:
:

else

default statements

end```

Each of the elseif keywords defines a set of statements (a block) and the construct as a whole acts to create a set of blocks that are executed on a mutually exclusive basis (i.e., only 1 of the blocks is executed). As with the simpler form (the if/else construct), the else keyword (and its associated block of statements) may be omitted.

Note: If you mean to use the elseif keyword, do not write it as two words (else if). Separating the pieces of this keyword will create a nested if-construct when one is not intended.

The order of the blocks is important. The construct executes the first block for which the associated logical expression is true. For example, if the second and fifth logical expressions are true for the test variable for a particular construct, only the second block will be executed. The flow of the program will never reach the fifth block.

It is important, then, two keep two principles in mind when using if-constructs:

1. Keep it simple. Use the if/elseif/else form only when absolutely necessary. If only two options are involved, the simpler if/else form is easier to read and more reliably created.
2. Whenever possible, organize your if-constructs so that the else keyword is properly used. The block associated with the else keyword should be reached only when all other options (logical expressions) have turned false.

The SWITCH construct

The switch construct, like the if construct, is a mechanism for conditional execution of a set of blocks. Hence, it is a decision construct. The structure of the swich construct is very like the if/elseif/else construct. Hence, the discussion here will be brief.

The syntax is:

```   switch switch_expression

case case_expression_list #1

block #1

case case_expression_list #2

block #2

:
:

case case_expression_list #k

block #k

:
:

case case_expression_list #n

block #n

otherwise

default block

end```

For each case keyword, a comparison of the result of the switch expression is compared to all of the expressions in the case list. If there are any matches, the associated block of statements is executed and the program flow continues after the end keyword that terminates the construct. If no matches are found, the block associated with the (optional) otherwise keyword is executed.

The primary advantage of the switch construct over the if construct is in the nature of the comparison that is carried out for each case. The switch construct allows multiple chances per case for a match to be found and permits either scalar (equality) or string comparisons to be carried out, depending on the nature of the switch expression.

You should use a switch construct when you have a set of definable cases, each with a finite number of tags (case expressions) for comparing to a target values (the switch expression). Relative comparisons (like < and >) are still better handled with an if construct.

As with the if construct, the order of the case statements isimportant. Once a match is found, the cases that follow the sucessful case are never executed.

[Back to main page] [Back to language features]
Comments? Contact Jim Maneval at maneval@bucknell.edu