4.5. Compound Boolean Expressions
4.5.1. Logical Operators
To be eligible to graduate from M S&T, you must
have 120 credits and a GPA of at least 2.0. C# does not use the
word and. Instead it uses &&
(inherited from the C language).
Then, the requirement translates directly into C# as a compound condition
using the logical operator &&
:
credits >= 120 && GPA >=2.0
This is true if both credits >= 120
is true and GPA >= 2.0
is true. A short example function using this would be:
static void checkGraduation(int credits, double GPA)
{
if (credits >= 120 && GPA >=2.0) {
Console.WriteLine("You are eligible to graduate!");
}
else {
Console.WriteLine("You are not eligible to graduate.");
}
}
The C# syntax for the logical operator &&
is:
condition1
&&
condition2
The compound condition is true
if both
of the component conditions
are true. It is false
if at least one
of the conditions is false.
Suppose we want a C# condition that is true in the same situations
as the mathematical expression: low < val < high. Unfortunately the
math is not a C# expression. The C# operator <
is binary.
In C#, the statement above is equivalent to
(low < val) < high
comparing a Boolean result to high, and causing a compiler error. There is a C# version. Be sure to use this pattern:
low < val && val < high
Now suppose we want the opposite condition: that val is not
strictly between low and high.
There are several approaches.
One is that val
would be less than or equal to low
or greater than or equal to high
. C# translate or into ||
,
so a C# expression would be:
val <= low || val >= high
The C# syntax for the logical operator ||
is:
condition1
||
condition2
The compound condition is true if at least one of the component conditions are true. It is false if both conditions are false.
Another logical way to express the opposite of the condition low < val < high
is that it is not the case
that low < val && val << high. C# translates not as !
. Another way
to state the condition would be
!(low < val && val < high)
The parentheses are needed because the !
operator has higher precedence than
<
.
A way to remember this strange not operator is to think of the use of !
in the not-equal operator: !=
The C# syntax for the operator !
:
!
condition
This whole expression is true when condition is false, and false when condition is true.
Because of the precedence of !
, you are often going to write:
!(
condition)
Remember when such a condition is used in an if
statement, outer
parentheses are also needed:
if (!(
condition)) {
Note that !
has the high precedence of unary arithmetic operators.
The operators &&
and ||
are almost at the bottom of the operators
considered in this book, just above the assignment operators, and below the
relational operators, with &&
above ||
. You are encourages to use
parentheses to make sure.
Compound Overkill: Look back to the code converting a score to a letter grade in the LetterGrade2 (else-if Statements for Cases) method, the condition before assigning the B grade could have been:
(score >= 80 && score < 90)
That would have totally nailed the condition, but it is overly verbose in the
if
.. else if
… code where it appeared. Since you only get
to consider a B as a grade if the grade was not already
set to A, the second part of the compound condition above is redundant.
4.5.2. Compound test conditions
Consider a different situation: Steven Covey suggested that people classify possible actions on two axes: urgent vs. not urgent and important vs. not important, leading to four possible combinations. We could ask a person to classify an activity this way, and them give a process comment, something like from Covey’s book:
Important and urgent: Be sure to schedule this promptly!
Important and not urgent: Make sure that this is included regularly in your plans! Do not let urgent but unimportant things interfere!
Not important and urgent: Can you skip this, or is it really worth letting this displace important things you need to do?
Not important and not urgent: Is there anything more worthwhile for you to do now?
Assume we have Boolean variables important
and urgent
.
There are four separate combinations, and we could handle this with a
chain of compound conditions checking for one at a time:
if (important && urgent) {
Console.WriteLine("Be sure ...");
}
else if (important && !urgent) {
Console.WriteLine("Make sure ...");
}
else if (!important && urgent) {
Console.WriteLine("Can you...");
}
else {
Console.WriteLine("Is there ...");
}
Compound test conditions are not necessary if we keep track of partial
answers by nesting if
statements. Consider the two aspects separately
using an if-else statement with nested if-else sub-statements:
if (important) {
if (urgent) {
Console.WriteLine("Be sure ...");
}
else {
Console.WriteLine("Make sure ...");
}
}
else {
if (urgent) {
Console.WriteLine("Can you...");
}
else {
Console.WriteLine("Is there ...");
}
}
The outer if
-else
determines whether the action is important, so the inner
conditions only need to deal with urgency. Also note that in executing
this version there are never more than two short conditions evaluated.
In the first version, you may have to go through all three conditions.
Both approaches work. Which is clearer to you?