Steve Mumford takes a look at how C handles the processes of decision and interation.
Up to this point, the flow of the programs in this series has been somewhat linear and the computer has not had to make many decisions on the route it takes through the code - executions starts with the first line in main() and continues until the program terminates. However, this rigidity is unacceptable on all but the most basic of programs, and techniques are needed which allow the flow of the program to be altered. In this article, I will be describing the ways in which you can interrupt the stream of the program to allow conditional execution of program segments to take place. After that, I'll move on to mention the forms of loop available in C.
if (condition) { /* some statements */ }
The statements contained within the braces are only executed if the condition evaluates as being true - otherwise, the computer simply skips over them and continues executions wherever the id construction finishes. Greater flexibility is provided by the else keyword, allowing you to chain several if statements together, providing a method of making multi-choice decisions.
if (guess == number) { printf("You are correct!\n"); } else if ((guess > number-5) && (guess < number+5)) { printf("Well, you were close.\n"); } else { printf("Sorry, that's not right.\n"); }
switch (x) { case 1: printf("x = 1\n"); break; case 2: printf("x = 2\n"); break; default: printf("x does not equal 1 or 2\n"); break; }
This code fragment examines the value of the integer x and then makes the comparisons give in the block - if x is equal to a constant included after a case statement, the program begins execution at that point and continues until it reaches a break statement or the end of the switch block.
The statements after the default keyword are executed if none of the case statements match the value given after the switch command. This feature makes the switch construction particularly useful for creating menu systems - after the user has picked an option from the menu, it can be checked against a list of possibilities and the appropriate action take. If the user happens to enter an option that is not supported by the menu, the default action is taken, and this might be to inform the user to make another choice.
The break statement is particularly important here, as once a case has been found that matches the switch expression, the program begin execution at that point and will ignore any following case comparisons, continuing execution until the next break. Although this can be useful in a few cases, after you've spent a good while implementing your menu structure, it's somewhat demoralising to find that the computer is executing most of the options regardless of your choice.
There are a couple of restrictions on the switch construction - firstly, it can only test for integers (and characters, since these are actually stored as an integer). Secondly, you must not include two case constants with the same value in the same switch.
for (initialisation; loop condition; increment) { /* statements to be repeated */ }
The initialisation is usually something simple like x=0 which prepares the variable to be used as the looping flag. However, you must still remember to declare the variable earlier in the program. The loop will continue repeating while the condition given in the middle of the statement is true - this might be x<=5. Finally, the increment statement is applied to the flag on each successive loop, and in this case it could be x++. Putting this together would give a loop similar to the following:
for (x=0; x<=5; x++) { printf("The value of x is %d\n", x); }
This fragment would loop six times, printing out the numbers 0 to 5 on the screen. This is a somewhat contrived example, and the for loop can be used for more creative tasks - for instance, an infinite loop can be constructed by leaving all three fields blank, and the only way to escape from such a loop is by using the break command.
while(condition) { /* statements to be repeated */ }
The statements are repeated while the condition given at the top of the loop is true, but it's important to see that since the comparison is made at the head of the structure, the statements in the loop will never get executed if the condition is false to begin with.
The second form is known as the do-while loop, and it looks rather similar in its construction - however, you must remember to include the semi-colon at the end of the block!
do { /* statements to be repeated */ } while (condition);
The major difference is that the statements in the loop are always executed at least once, because the comparison is only made at the end of the block. If the construction feels a little familiar, that because it's similar to REPEAT-UNTIL in BASIC, with the difference being in the way it tests for the end condition. REPEAT-UNTIL loops until a condition is met, and do-while iterates while a condition is met - they're said to be logically opposite.
C has a related command named continue - this is less severe when compared to break, and instead of exiting the loop completely, it just forces an early iteration:
for (x=0; x < 15; x++) { if (x==13) continue; printf(x = %d\n", x); }
For the supersitious among you, this program fragment will print out the integers from 0 to 14, missing out the number 13. When the continue command is issued, it immediately skips pas the rest of the statements in the loop, and returns control to the head of the block. The loop flag is incremented and the end condition tested, and if the loop is still valid it continues as normal.
x = 0; loop: x++; if (x < 50) goto loop; printf("x = 50!\n");
To perform a goto you must have defined a label elsewhere in the program by including a valid identifier followed by a colon. In this case, the label is loop:. The fragment keeps incrementing x and returning to loop until x is equal to 50. So now you know, but for the benefit of programmers everywhere, please try to avoid using it.
Source: | Acorn User - 154 - April 1995 |
Publication: | Acorn User |
Contributor: | Steve Mumford |