As a program becomes more sophisticated, it must be able to make decisions about what commands it should execute. For example, if a user enters an invalid email address in the "To" field of an email, the program that sends emails should alert the user instead of blindly sending an email that cannot be delivered. This is known as controlling the flow of a program. In almost every language it is achieved by using if statements (the main exception is assembly language which uses conditional jumps). if statements are conditional statements. This means that they redirect program flow depending on whether or not a "condition" is True or False. From our previous discussions on expressions, you probably can already guess that Boolean expressions and relational operators will play a role here. In Object Pascal, an "if" statement is structured something like the following:
if BooleanExpression then Statement
[else OtherwiseStatement]
Note that the Boolean expression is bounded by if...then. This means that if the Boolean expression evaluates to True then Statement is executed. [else OtherwiseStatement] is optional. If it is provided and the Boolean expression is False then OtherwiseStatement is executed. If it is not provided then the program just moves on to the next line of code. Since the if...then or if...then...else constructs are statements themselves, any number of if statements can be chained together. To understand this, copy and paste the program below into Workspace and run it:
{$APPTYPE CONSOLE}
program Workspace;
var
Num : Char;
begin
{$I Debug.inc}
Write('Enter a single number to get its name: ');
Readln(Num);
if Num = '0' then Writeln('Zero')
else if Num = '1' then Writeln('One')
else if Num = '2' then Writeln('Two')
else if Num = '3' then Writeln('Three')
else if Num = '4' then Writeln('Four')
else if Num = '5' then Writeln('Five')
else if Num = '6' then Writeln('Six')
else if Num = '7' then Writeln('Seven')
else if Num = '8' then Writeln('Eight')
else if Num = '9' then Writeln('Nine')
else Writeln(Num,' is not a single digit number!');
Readln;
end.
On Line 8, we start with an if...then statement that evaluates the Boolean Expression Num = '0'. If you entered '0' at the prompt then the word Zero was printed to the screen. Otherwise, the first else statement is executed. The first else on line 9 leads to another if statement which checks if the number entered is '1'. This continues to occur until one of the statements evaluates to True.
To watch the flow of an "if" statement, set a breakpoint on Line 9 next to the first if. Now hit F9. Follow the instructions in the program and enter a 5 as the single digit. If the breakpoint was set correctly, it should pause the program at this point. You can hover the mouse above Num to see that it contains '5'. Now press F8 in the editor until you reach Line 13. Since Num = '5' is a true statement, the if statement will execute Writeln('Five') and jump past the rest of the if statements. Press F8 and you should see this happen. The program has now written the word "Five" to the screen. If you now press F9 it will resume execution until it exits.
In addition to "if" statements, most languages also have case statements (also known as switch statements). In Object Pascal, the proper syntax of a case statement is the following:
case OrdinalExpression of
ConstantExpr1: Statement1;
ConstantExpr2: Statement2;
...
ConstantExprN: StatementN;
[else OtherwiseStatement;]
end;
The OrdinalExpression between case and of is generally an integer or character. If one of the ConstantExpr's matches this value, then the statement corresponding to that ConstantExpr is executed. This is best understood by converting our previous example into a case statement instead of an if statement:
{$APPTYPE CONSOLE}
program CaseStatements;
var
Num : Char;
begin
{$I Debug.inc}
Write('Enter a single number to get its name: ');
Readln(Num);
case Num of
'0': Writeln('Zero');
'1': Writeln('One');
'2': Writeln('Two');
'3': Writeln('Three');
'4': Writeln('Four');
'5': Writeln('Five');
'6': Writeln('Six');
'7': Writeln('Seven');
'8': Writeln('Eight');
'9': Writeln('Nine');
else Writeln(Num,' is not a single digit number!');
end;
Readln;
end.
If no match is found and the optional else clause is present at the end, the OtherwiseStatement is executed. The key difference between an if statement and a case statement in Object Pascal is the way in which the machine code is written. An if statement executes each statement sequentially until an expression evaluates to true. A case statement allows the program to jump directly to the statement which should be executed. This is achieved by clever machine code generation by the compiler and is beyond the scope of Unit 1. What you should take away from this, however, is that a case statement will on average be faster than an if statement since multiple expressions do not have to be evaluated. You can observe this behavior by setting a breakpoint on Line 9 where the case statement begins and run the program. Enter 5 for the number and when the execution pauses at the breakpoint, press F8 once and you will see that the code execution jumps directly to the correct statement. Thus, the case statement is extremely useful in situations where there are a large number of ordinal alternatives to choose from. The key word here is ordinal. A string cannot be used in a case statement (but a single character can) nor can a real number. Fortunately, many of the things we have to choose among are ordinal and when they are not we simply use if statements.