Programs with Selection Logic
In this chapter, we will explain the following:
• What are Boolean expressions
• How C represents Boolean values
• How to write programs using if
• How to write programs using if...else
• Where semicolons are required, where they are optional, and where they must not be put
• How a program should be tested
• Why symbolic constants are useful and how to use them in a C program
4.1 Introduction
In the last chapter, we showed how to write programs using sequence logic—programs whose statements are executed “in sequence” from the first to the last.
In this chapter, the programs will use selection logic—they will test some condition and take different courses of action based on whether the condition is true or false. In C, selection logic is implemented using the if and the if...else statements.
Each of these can be either true or false. These are examples of a special kind of Boolean expression called relational expressions. Such expressions simply check if one value is equal to, not equal to, greater than, greater than or equal to, less than, and less than or equal to another value. We write them using relational operators.
The C relational operators (with examples) are:
== equal to k == 999, a*a + b*b == c*c
!= not equal to s != 0, a != b + c
> greater than a > 100
>= greater than or equal to b*b >= 4.0*a*c
< less than n < 0
<= less than or equal to score <= 65
Boolean expressions are normally used to control the flow of program execution. For example, we may have a variable (h, say) which starts off with a value of 0. We keep increasing it by 1 and we want to know when its value reaches 100. We say we wish to know when the condition h == 100 is true. A condition is the common name for a Boolean expression.
The real power of programming lies in the ability of a program to test a condition and decide whether it is true or false. If it is true, the program can perform one set of actions; and if it is false, it can perform another set or simply do nothing at all.
For example, suppose the variable score holds the score obtained by a student in a test, and the student passes if her score is 50 or more and fails if it is less than 50. A program can be written to test the condition
score >= 50
If it is true, the student passes; if it is false, the student fails. In C, this can be written as:
if (score >= 50) printf("Pass\n");
else printf("Fail\n");
When the computer gets to this statement, it compares the current value of score with 50. If the value is greater than or equal to 50, we say that the condition score >= 50 is true. In this case the program prints Pass. If the value of score is less than 50, we say that the condition score >= 50 is false. In this case, the program prints Fail.
In this chapter, we will see how Boolean expressions are used in if and if...else statements and, in the next chapter, we will see how they are used in while statements.
4.2.1 AND, &&
With the relational operators, we can create simple conditions. But sometimes, we need to ask if one thing is true AND another thing is true. We may also need to know if one of two things is true.
For these situations, we need compound conditions. To create compound conditions, we use the logical operators AND, OR, and NOT.
For example, suppose we want to know if the value of h lies between 1 and 99, inclusive.
We want to know if h is greater than or equal to 1 AND if h is less than or equal to 99. In C, we express this as:
(h >= 1) && (h <= 99) In C, the symbol for AND is &&.
Note the following:
• The variable h must be repeated in both conditions. It is tempting, but wrong, to write
h >= 1 && <= 99 //this is wrong
• The brackets around h >= 1 and h <= 99 are not required, but it is not wrong to put them. This is so since && (and ||, see next) have
lower precedence than the relational operators. Without the brackets, h >= 1 && h <= 99
would be interpreted by C like this:
(h >= 1) && (h <= 99)
• This is the same as with the brackets.
4.2.2 OR, ||
If n is an integer representing a month of the year, we can check if n is invalid by testing if n is less than 1 OR n is greater than 12. In C, we express this as:
(n < 1) || (n > 12)
In C, the symbol for OR is ||. As discussed above, the brackets are not required and we could write the expression as
n < 1 || n > 12
This tests if n is invalid. Of course, we can test if n is valid by testing if n >= 1 && n <= 12
Which test we use depends on how we wish to express our logic. Sometimes it’s convenient to use the valid test, sometimes the invalid one.
4.2.3 NOT, !
If p is some Boolean expression, then NOT p reverses the truth value of p. In others words, if p is true then NOT p is false; if p is false then NOT p is true. In C, the symbol for NOT is the exclamation mark, !. Using the example above, since
n >= 1 && n <= 12
tests for valid n, the condition NOT (n >=1 && n <= 12) tests for invalid n. This is written in C as
!(n >= 1 && n <= 12)
This is equivalent to n < 1 || n > 12. Those familiar with de Morgan’s laws will know that not (a and b) = (not a) or (not b)
and
not(a or b) = (not a) and (not b)
In general, if p and q are Boolean expressions, we have the following:
• p && q is true when both p and q are true and false, otherwise;
• p || q is true when either p or q is true and false only when both p and q are false;
• !p is true when p is false and false when p is true.
This is summarized in the following table (with T for true and F for false):
P q && || !p
T T T T F
T F F T F
F T F T T
F F F F T
Most of the programs in this book will use simple conditions. A few will use compound conditions.
4.2.3.1 The data type bool in C99
The original C standard and the later ANSI C standard did not define a Boolean data type.
Traditionally, C has used the concept of the value of an expression to denote true/false. A numeric expression can be used in any context where a true/false value is required. The expression is considered true if its value is nonzero and false if its value is zero.
The latest C99 standard defines the type bool. However, in this book, we will use the traditional approach mainly because many popular C compilers do not support the C99 standard as yet. Also, as you will see, we can easily live without bool. The vast majority of our Boolean expressions would be relational expressions used in if and while statements. If we ever need a “Boolean” variable, we can use an int variable with 1 representing true and 0 representing false.